/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.ignite.internal.commandline;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import java.util.UUID;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import java.util.stream.Collectors;
import org.apache.ignite.IgniteSystemProperties;
import org.apache.ignite.cluster.ClusterNode;
import org.apache.ignite.compute.ComputeTask;
import org.apache.ignite.internal.IgniteNodeAttributes;
import org.apache.ignite.internal.client.GridClient;
import org.apache.ignite.internal.client.GridClientAuthenticationException;
import org.apache.ignite.internal.client.GridClientClosedException;
import org.apache.ignite.internal.client.GridClientClusterState;
import org.apache.ignite.internal.client.GridClientCompute;
import org.apache.ignite.internal.client.GridClientConfiguration;
import org.apache.ignite.internal.client.GridClientDisconnectedException;
import org.apache.ignite.internal.client.GridClientException;
import org.apache.ignite.internal.client.GridClientFactory;
import org.apache.ignite.internal.client.GridClientHandshakeException;
import org.apache.ignite.internal.client.GridClientNode;
import org.apache.ignite.internal.client.GridServerUnreachableException;
import org.apache.ignite.internal.client.impl.connection.GridClientConnectionResetException;
import org.apache.ignite.internal.commandline.cache.CacheArguments;
import org.apache.ignite.internal.commandline.cache.CacheCommand;
import org.apache.ignite.internal.commandline.cache.distribution.CacheDistributionTask;
import org.apache.ignite.internal.commandline.cache.distribution.CacheDistributionTaskArg;
import org.apache.ignite.internal.commandline.cache.distribution.CacheDistributionTaskResult;
import org.apache.ignite.internal.commandline.cache.reset_lost_partitions.CacheResetLostPartitionsTask;
import org.apache.ignite.internal.commandline.cache.reset_lost_partitions.CacheResetLostPartitionsTaskArg;
import org.apache.ignite.internal.commandline.cache.reset_lost_partitions.CacheResetLostPartitionsTaskResult;
import org.apache.ignite.internal.processors.cache.verify.CacheInfo;
import org.apache.ignite.internal.processors.cache.verify.ContentionInfo;
import org.apache.ignite.internal.processors.cache.verify.IdleVerifyResultV2;
import org.apache.ignite.internal.processors.cache.verify.PartitionHashRecord;
import org.apache.ignite.internal.processors.cache.verify.PartitionKey;
import org.apache.ignite.internal.processors.cache.verify.VerifyBackupPartitionsTaskV2;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.X;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.internal.visor.VisorTaskArgument;
import org.apache.ignite.internal.visor.baseline.VisorBaselineNode;
import org.apache.ignite.internal.visor.baseline.VisorBaselineOperation;
import org.apache.ignite.internal.visor.baseline.VisorBaselineTask;
import org.apache.ignite.internal.visor.baseline.VisorBaselineTaskArg;
import org.apache.ignite.internal.visor.baseline.VisorBaselineTaskResult;
import org.apache.ignite.internal.visor.misc.VisorClusterNode;
import org.apache.ignite.internal.visor.misc.VisorWalTask;
import org.apache.ignite.internal.visor.misc.VisorWalTaskArg;
import org.apache.ignite.internal.visor.misc.VisorWalTaskOperation;
import org.apache.ignite.internal.visor.misc.VisorWalTaskResult;
import org.apache.ignite.internal.visor.tx.VisorTxInfo;
import org.apache.ignite.internal.visor.tx.VisorTxOperation;
import org.apache.ignite.internal.visor.tx.VisorTxProjection;
import org.apache.ignite.internal.visor.tx.VisorTxSortOrder;
import org.apache.ignite.internal.visor.tx.VisorTxTask;
import org.apache.ignite.internal.visor.tx.VisorTxTaskArg;
import org.apache.ignite.internal.visor.tx.VisorTxTaskResult;
import org.apache.ignite.internal.visor.verify.IndexValidationIssue;
import org.apache.ignite.internal.visor.verify.ValidateIndexesPartitionResult;
import org.apache.ignite.internal.visor.verify.VisorContentionTask;
import org.apache.ignite.internal.visor.verify.VisorContentionTaskArg;
import org.apache.ignite.internal.visor.verify.VisorContentionTaskResult;
import org.apache.ignite.internal.visor.verify.VisorIdleVerifyDumpTask;
import org.apache.ignite.internal.visor.verify.VisorIdleVerifyDumpTaskArg;
import org.apache.ignite.internal.visor.verify.VisorIdleVerifyTask;
import org.apache.ignite.internal.visor.verify.VisorIdleVerifyTaskArg;
import org.apache.ignite.internal.visor.verify.VisorIdleVerifyTaskResult;
import org.apache.ignite.internal.visor.verify.VisorIdleVerifyTaskV2;
import org.apache.ignite.internal.visor.verify.VisorValidateIndexesJobResult;
import org.apache.ignite.internal.visor.verify.VisorValidateIndexesTaskArg;
import org.apache.ignite.internal.visor.verify.VisorValidateIndexesTaskResult;
import org.apache.ignite.internal.visor.verify.VisorViewCacheTask;
import org.apache.ignite.internal.visor.verify.VisorViewCacheTaskArg;
import org.apache.ignite.internal.visor.verify.VisorViewCacheTaskResult;
import org.apache.ignite.lang.IgniteProductVersion;
import org.apache.ignite.plugin.security.SecurityCredentials;
import org.apache.ignite.plugin.security.SecurityCredentialsBasicProvider;

import static org.apache.ignite.IgniteSystemProperties.IGNITE_ENABLE_EXPERIMENTAL_COMMAND;
import static org.apache.ignite.internal.IgniteVersionUtils.ACK_VER_STR;
import static org.apache.ignite.internal.IgniteVersionUtils.COPYRIGHT;
import static org.apache.ignite.internal.commandline.Command.ACTIVATE;
import static org.apache.ignite.internal.commandline.Command.BASELINE;
import static org.apache.ignite.internal.commandline.Command.CACHE;
import static org.apache.ignite.internal.commandline.Command.DEACTIVATE;
import static org.apache.ignite.internal.commandline.Command.STATE;
import static org.apache.ignite.internal.commandline.Command.TX;
import static org.apache.ignite.internal.commandline.Command.WAL;
import static org.apache.ignite.internal.visor.baseline.VisorBaselineOperation.ADD;
import static org.apache.ignite.internal.visor.baseline.VisorBaselineOperation.COLLECT;
import static org.apache.ignite.internal.visor.baseline.VisorBaselineOperation.REMOVE;
import static org.apache.ignite.internal.visor.baseline.VisorBaselineOperation.SET;
import static org.apache.ignite.internal.visor.baseline.VisorBaselineOperation.VERSION;
import static org.apache.ignite.internal.visor.verify.VisorViewCacheCmd.GROUPS;
import static org.apache.ignite.internal.visor.verify.VisorViewCacheCmd.SEQ;

/**
 * Class that execute several commands passed via command line.
 */
public class CommandHandler {
    /** Logger. */
    private static final Logger log = Logger.getLogger(CommandHandler.class.getName());

    /** */
    static final String DFLT_HOST = "127.0.0.1";

    /** */
    static final String DFLT_PORT = "11211";

    /** */
    private static final String CMD_HELP = "--help";

    /** */
    private static final String CMD_HOST = "--host";

    /** */
    private static final String CMD_PORT = "--port";

    /** */
    private static final String CMD_PASSWORD = "--password";

    /** */
    private static final String CMD_USER = "--user";

    /** Option is used for auto confirmation. */
    private static final String CMD_AUTO_CONFIRMATION = "--yes";

    /** */
    protected static final String CMD_PING_INTERVAL = "--ping-interval";

    /** */
    protected static final String CMD_PING_TIMEOUT = "--ping-timeout";

    /** */
    private static final String CMD_DUMP = "--dump";

    /** */
    private static final String CMD_SKIP_ZEROS = "--skipZeros";

    /** */
    private static final String CMD_USER_ATTRIBUTES = "--user-attributes";

    /** List of optional auxiliary commands. */
    private static final Set<String> AUX_COMMANDS = new HashSet<>();

    static {
        AUX_COMMANDS.add(CMD_HELP);
        AUX_COMMANDS.add(CMD_HOST);
        AUX_COMMANDS.add(CMD_PORT);
        AUX_COMMANDS.add(CMD_PASSWORD);
        AUX_COMMANDS.add(CMD_USER);
        AUX_COMMANDS.add(CMD_AUTO_CONFIRMATION);
        AUX_COMMANDS.add(CMD_PING_INTERVAL);
        AUX_COMMANDS.add(CMD_PING_TIMEOUT);
    }

    /** Broadcast uuid. */
    private static final UUID BROADCAST_UUID = UUID.randomUUID();

    /** */
    public static final String CONFIRM_MSG = "y";

    /** */
    private static final String BASELINE_ADD = "add";

    /** */
    private static final String BASELINE_REMOVE = "remove";

    /** */
    private static final String BASELINE_COLLECT = "collect";

    /** */
    private static final String BASELINE_SET = "set";

    /** */
    private static final String BASELINE_SET_VERSION = "version";

    /** Parameter name for validate_indexes command. */
    static final String VI_CHECK_FIRST = "checkFirst";

    /** Parameter name for validate_indexes command. */
    static final String VI_CHECK_THROUGH = "checkThrough";

    /** */
    static final String WAL_PRINT = "print";

    /** */
    static final String WAL_DELETE = "delete";

    /** */
    static final String DELIM = "--------------------------------------------------------------------------------";

    /** */
    public static final int EXIT_CODE_OK = 0;

    /** */
    public static final int EXIT_CODE_INVALID_ARGUMENTS = 1;

    /** */
    public static final int EXIT_CODE_CONNECTION_FAILED = 2;

    /** */
    public static final int ERR_AUTHENTICATION_FAILED = 3;

    /** */
    public static final int EXIT_CODE_UNEXPECTED_ERROR = 4;

    /** */
    private static final long DFLT_PING_INTERVAL = 5000L;

    /** */
    private static final long DFLT_PING_TIMEOUT = 30_000L;

    /** */
    private static final Scanner IN = new Scanner(System.in);

    /** Validate indexes task name. */
    private static final String VALIDATE_INDEXES_TASK = "org.apache.ignite.internal.visor.verify.VisorValidateIndexesTask";

    /** */
    private static final String TX_LIMIT = "limit";

    /** */
    private static final String TX_ORDER = "order";

    /** */
    public static final String CMD_TX_ORDER_START_TIME = "START_TIME";

    /** */
    private static final String TX_SERVERS = "servers";

    /** */
    private static final String TX_CLIENTS = "clients";

    /** */
    private static final String TX_DURATION = "minDuration";

    /** */
    private static final String TX_SIZE = "minSize";

    /** */
    private static final String TX_LABEL = "label";

    /** */
    private static final String TX_NODES = "nodes";

    /** */
    private static final String TX_XID = "xid";

    /** */
    private static final String TX_KILL = "kill";

    /** */
    private Iterator<String> argsIt;

    /** */
    private String peekedArg;

    /** */
    private Object lastOperationRes;

    /** */
    private GridClientConfiguration clientCfg;

    /** Check if experimental commands are enabled. Default {@code false}. */
    private final boolean enableExperimental = IgniteSystemProperties.getBoolean(IGNITE_ENABLE_EXPERIMENTAL_COMMAND, false);

    /**
     * Output specified string to console.
     *
     * @param s String to output.
     */
    private void log(String s) {
        System.out.println(s);
    }

    /**
     * Provides a prompt, then reads a single line of text from the console.
     *
     * @param prompt text
     * @return A string containing the line read from the console
     */
    private String readLine(String prompt) {
        System.out.print(prompt);

        return IN.nextLine();
    }

    /**
     * Output empty line.
     */
    private void nl() {
        System.out.println("");
    }

    /**
     * Print error to console.
     *
     * @param errCode Error code to return.
     * @param s Optional message.
     * @param e Error to print.
     */
    private int error(int errCode, String s, Throwable e) {
        if (!F.isEmpty(s))
            log(s);

        String msg = e.getMessage();

        if (F.isEmpty(msg))
            msg = e.getClass().getName();

        if (msg.startsWith("Failed to handle request")) {
            int p = msg.indexOf("err=");

            msg = msg.substring(p + 4, msg.length() - 1);
        }

        log("Error: " + msg);

        return errCode;
    }

    /**
     * Requests interactive user confirmation if forthcoming operation is dangerous.
     *
     * @param args Arguments.
     * @return {@code true} if operation confirmed (or not needed), {@code false} otherwise.
     */
    private boolean confirm(Arguments args) {
        String prompt = confirmationPrompt(args);

        if (prompt == null)
            return true;

        return CONFIRM_MSG.equalsIgnoreCase(readLine(prompt));
    }

    /**
     * @param args Arguments.
     * @return Prompt text if confirmation needed, otherwise {@code null}.
     */
    private String confirmationPrompt(Arguments args) {
        String str = null;

        switch (args.command()) {
            case DEACTIVATE:
                str = "Warning: the command will deactivate a cluster.";

                break;

            case BASELINE:
                if (!BASELINE_COLLECT.equals(args.baselineAction()))
                    str = "Warning: the command will perform changes in baseline.";

                break;

            case WAL:
                if (WAL_DELETE.equals(args.walAction()))
                    str = "Warning: the command will delete unused WAL segments.";

                break;

            case TX:
                if (args.transactionArguments().getOperation() == VisorTxOperation.KILL)
                    str = "Warning: the command will kill some transactions.";

                break;

            default:
                break;
        }

        return str == null ? null : str + "\nPress '" + CONFIRM_MSG + "' to continue . . . ";
    }

    /**
     * @param rawArgs Arguments.
     */
    private void initArgIterator(List<String> rawArgs) {
        argsIt = rawArgs.iterator();
        peekedArg = null;
    }

    /**
     * @return Returns {@code true} if the iteration has more elements.
     */
    private boolean hasNextArg() {
        return peekedArg != null || argsIt.hasNext();
    }

    /**
     * Activate cluster.
     *
     * @param client Client.
     * @throws GridClientException If failed to activate.
     */
    private void activate(GridClient client) throws Throwable {
        try {
            GridClientClusterState state = client.state();

            state.active(true);

            log("Cluster activated");
        }
        catch (Throwable e) {
            log("Failed to activate cluster.");

            throw e;
        }
    }

    /**
     * Deactivate cluster.
     *
     * @param client Client.
     * @throws Throwable If failed to deactivate.
     */
    private void deactivate(GridClient client) throws Throwable {
        try {
            GridClientClusterState state = client.state();

            state.active(false);

            log("Cluster deactivated");
        }
        catch (Throwable e) {
            log("Failed to deactivate cluster.");

            throw e;
        }
    }

    /**
     * Print cluster state.
     *
     * @param client Client.
     * @throws Throwable If failed to print state.
     */
    private void state(GridClient client) throws Throwable {
        try {
            GridClientClusterState state = client.state();

            log("Cluster is " + (state.active() ? "active" : "inactive"));
        }
        catch (Throwable e) {
            log("Failed to get cluster state.");

            throw e;
        }
    }

    /**
     * @param client Client.
     * @param taskCls Task class.
     * @param taskArgs Task arguments.
     * @return Task result.
     * @throws GridClientException If failed to execute task.
     */
    private <R> R executeTask(GridClient client, Class<? extends ComputeTask<?, R>> taskCls,
        Object taskArgs) throws GridClientException {
        return executeTaskByNameOnNode(client, taskCls.getName(), taskArgs, null);
    }

    /**
     * @param client Client
     * @param taskClsName Task class name.
     * @param taskArgs Task args.
     * @param nodeId Node ID to execute task at (if null, random node will be chosen by balancer).
     * @return Task result.
     * @throws GridClientException If failed to execute task.
     */
    private <R> R executeTaskByNameOnNode(GridClient client, String taskClsName, Object taskArgs, UUID nodeId
    ) throws GridClientException {
        GridClientCompute compute = client.compute();

        if (nodeId == BROADCAST_UUID) {
            Collection<GridClientNode> nodes = compute.nodes(GridClientNode::connectable);

            if (F.isEmpty(nodes))
                throw new GridClientDisconnectedException("Connectable nodes not found", null);

            List<UUID> nodeIds = nodes.stream()
                .map(GridClientNode::nodeId)
                .collect(Collectors.toList());

            return client.compute().execute(taskClsName, new VisorTaskArgument<>(nodeIds, taskArgs, false));
        }

        GridClientNode node = null;

        if (nodeId == null) {
            Collection<GridClientNode> nodes = compute.nodes(GridClientNode::connectable);

            // Prefer node from connect string.
            String origAddr = clientCfg.getServers().iterator().next();

            for (GridClientNode clientNode : nodes) {
                Iterator<String> it = F.concat(clientNode.tcpAddresses().iterator(), clientNode.tcpHostNames().iterator());

                while (it.hasNext()) {
                    if (origAddr.equals(it.next() + ":" + clientNode.tcpPort())) {
                        node = clientNode;

                        break;
                    }
                }
            }

            // Otherwise choose random node.
            if (node == null)
                node = getBalancedNode(compute);
        }
        else {
            for (GridClientNode n : compute.nodes()) {
                if (n.connectable() && nodeId.equals(n.nodeId())) {
                    node = n;

                    break;
                }
            }

            if (node == null)
                throw new IllegalArgumentException("Node with id=" + nodeId + " not found");
        }

        return compute.projection(node).execute(taskClsName, new VisorTaskArgument<>(node.nodeId(), taskArgs, false));
    }

    /**
     * @param compute instance
     * @return balanced node
     */
    private GridClientNode getBalancedNode(GridClientCompute compute) throws GridClientException {
        Collection<GridClientNode> nodes = compute.nodes(GridClientNode::connectable);

        if (F.isEmpty(nodes))
            throw new GridClientDisconnectedException("Connectable node not found", null);

        return compute.balancer().balancedNode(nodes);
    }

    /**
     * Executes --cache subcommand.
     *
     * @param client Client.
     * @param cacheArgs Cache args.
     */
    private void cache(GridClient client, CacheArguments cacheArgs) throws Throwable {
        switch (cacheArgs.command()) {
            case HELP:
                printCacheHelp();

                break;

            case IDLE_VERIFY:
                cacheIdleVerify(client, cacheArgs);

                break;

            case VALIDATE_INDEXES:
                cacheValidateIndexes(client, cacheArgs);

                break;

            case CONTENTION:
                cacheContention(client, cacheArgs);

                break;

            case DISTRIBUTION:
                cacheDistribution(client, cacheArgs);

                break;

            case RESET_LOST_PARTITIONS:
                cacheResetLostPartitions(client, cacheArgs);

                break;

            default:
                cacheView(client, cacheArgs);

                break;
        }
    }

    /**
     *
     */
    private void printCacheHelp() {
        log("--cache subcommand allows to do the following operations:");

        usage("  Show information about caches, groups or sequences that match a regex:", CACHE, " list regexPattern [groups|seq] [nodeId]");
        usage("  Show hot keys that are point of contention for multiple transactions:", CACHE, " contention minQueueSize [nodeId] [maxPrint]");
        usage("  Verify partition counters and hashes between primary and backups on idle cluster:", CACHE, " idle_verify [--dump] [--skipZeros] [cache1,...,cacheN]");
        usage("  Validate custom indexes on idle cluster:", CACHE, " validate_indexes [cache1,...,cacheN] [nodeId] [checkFirst|checkThrough]");
        usage("  Collect partition distribution information:", CACHE, " distribution nodeId|null [cacheName1,...,cacheNameN] [--user-attributes attributeName1[,...,attributeNameN]]");
        usage("  Reset lost partitions:", CACHE, " reset_lost_partitions cacheName1[,...,cacheNameN]");

        log("  If [nodeId] is not specified, contention and validate_indexes commands will be broadcasted to all server nodes.");
        log("  Another commands where [nodeId] is optional will run on a random server node.");
        log("  checkFirst numeric parameter for validate_indexes specifies number of first K keys to be validated.");
        log("  checkThrough numeric parameter for validate_indexes allows to check each Kth key.");
        nl();
    }

    /**
     * @param client Client.
     * @param cacheArgs Cache args.
     */
    private void cacheContention(GridClient client, CacheArguments cacheArgs) throws GridClientException {
        VisorContentionTaskArg taskArg = new VisorContentionTaskArg(
            cacheArgs.minQueueSize(), cacheArgs.maxPrint());

        UUID nodeId = cacheArgs.nodeId() == null ? BROADCAST_UUID : cacheArgs.nodeId();

        VisorContentionTaskResult res = executeTaskByNameOnNode(
            client, VisorContentionTask.class.getName(), taskArg, nodeId);

        if (!F.isEmpty(res.exceptions())) {
            log("Contention check failed on nodes:");

            for (Map.Entry<UUID, Exception> e : res.exceptions().entrySet()) {
                log("Node ID = " + e.getKey());

                log("Exception message:");
                log(e.getValue().getMessage());
                nl();
            }
        }

        for (ContentionInfo info : res.getInfos())
            info.print();
    }

    /**
     * @param client Client.
     * @param cacheArgs Cache args.
     */
    private void cacheValidateIndexes(GridClient client, CacheArguments cacheArgs) throws GridClientException {
        VisorValidateIndexesTaskArg taskArg = new VisorValidateIndexesTaskArg(
            cacheArgs.caches(),
            cacheArgs.checkFirst(),
            cacheArgs.checkThrough()
        );

        UUID nodeId = cacheArgs.nodeId() == null ? BROADCAST_UUID : cacheArgs.nodeId();

        VisorValidateIndexesTaskResult taskRes = executeTaskByNameOnNode(
            client, VALIDATE_INDEXES_TASK, taskArg, nodeId);

        if (!F.isEmpty(taskRes.exceptions())) {
            log("Index validation failed on nodes:");

            for (Map.Entry<UUID, Exception> e : taskRes.exceptions().entrySet()) {
                log("Node ID = " + e.getKey());

                log("Exception message:");
                log(e.getValue().getMessage());
                nl();
            }
        }

        boolean errors = false;

        for (Map.Entry<UUID, VisorValidateIndexesJobResult> nodeEntry : taskRes.results().entrySet()) {
            Map<PartitionKey, ValidateIndexesPartitionResult> partRes = nodeEntry.getValue().partitionResult();

            for (Map.Entry<PartitionKey, ValidateIndexesPartitionResult> e : partRes.entrySet()) {
                ValidateIndexesPartitionResult res = e.getValue();

                if (!res.issues().isEmpty()) {
                    errors = true;

                    log(e.getKey().toString() + " " + e.getValue().toString());

                    for (IndexValidationIssue is : res.issues())
                        log(is.toString());
                }
            }

            Map<String, ValidateIndexesPartitionResult> idxRes = nodeEntry.getValue().indexResult();

            for (Map.Entry<String, ValidateIndexesPartitionResult> e : idxRes.entrySet()) {
                ValidateIndexesPartitionResult res = e.getValue();

                if (!res.issues().isEmpty()) {
                    errors = true;

                    log("SQL Index " + e.getKey() + " " + e.getValue().toString());

                    for (IndexValidationIssue is : res.issues())
                        log(is.toString());
                }
            }
        }

        if (!errors)
            log("validate_indexes has finished, no issues found.");
        else
            log("validate_indexes has finished with errors (listed above).");
    }

    /**
     * @param client Client.
     * @param cacheArgs Cache args.
     */
    private void cacheView(GridClient client, CacheArguments cacheArgs) throws GridClientException {
        VisorViewCacheTaskArg taskArg = new VisorViewCacheTaskArg(cacheArgs.regex(), cacheArgs.cacheCommand());

        VisorViewCacheTaskResult res = executeTaskByNameOnNode(
            client, VisorViewCacheTask.class.getName(), taskArg, cacheArgs.nodeId());

        for (CacheInfo info : res.cacheInfos())
            info.print(cacheArgs.cacheCommand());
    }

    /**
     * Executes appropriate version of idle_verify check. Old version will be used if there are old nodes in the
     * cluster.
     *
     * @param client Client.
     * @param cacheArgs Cache args.
     */
    private void cacheIdleVerify(GridClient client, CacheArguments cacheArgs) throws GridClientException {
        Collection<GridClientNode> nodes = client.compute().nodes(GridClientNode::connectable);

        boolean idleVerifyV2 = true;

        for (GridClientNode node : nodes) {
            String nodeVerStr = node.attribute(IgniteNodeAttributes.ATTR_BUILD_VER);

            IgniteProductVersion nodeVer = IgniteProductVersion.fromString(nodeVerStr);

            if (nodeVer.compareTo(VerifyBackupPartitionsTaskV2.V2_SINCE_VER) < 0) {
                idleVerifyV2 = false;

                break;
            }
        }

        if (cacheArgs.dump())
            cacheIdleVerifyDump(client, cacheArgs);
        else if (idleVerifyV2)
            cacheIdleVerifyV2(client, cacheArgs);
        else
            legacyCacheIdleVerify(client, cacheArgs);
    }

    /**
     * @param client Client.
     * @param cacheArgs Cache args.
     */
    private void legacyCacheIdleVerify(GridClient client, CacheArguments cacheArgs) throws GridClientException {
        VisorIdleVerifyTaskResult res = executeTask(
            client, VisorIdleVerifyTask.class, new VisorIdleVerifyTaskArg(cacheArgs.caches()));

        Map<PartitionKey, List<PartitionHashRecord>> conflicts = res.getConflicts();

        if (conflicts.isEmpty()) {
            log("idle_verify check has finished, no conflicts have been found.");
            nl();
        }
        else {
            log("idle_verify check has finished, found " + conflicts.size() + " conflict partitions.");
            nl();

            for (Map.Entry<PartitionKey, List<PartitionHashRecord>> entry : conflicts.entrySet()) {
                log("Conflict partition: " + entry.getKey());

                log("Partition instances: " + entry.getValue());
            }
        }
    }

    /**
     * @param client Client.
     * @param cacheArgs Cache args.
     */
    private void cacheDistribution(GridClient client, CacheArguments cacheArgs) throws GridClientException {
        CacheDistributionTaskArg taskArg = new CacheDistributionTaskArg(cacheArgs.caches(), cacheArgs.getUserAttributes());

        UUID nodeId = cacheArgs.nodeId() == null ? BROADCAST_UUID : cacheArgs.nodeId();

        CacheDistributionTaskResult res = executeTaskByNameOnNode(client, CacheDistributionTask.class.getName(), taskArg, nodeId);

        res.print(System.out);
    }

    /**
     * @param client Client.
     * @param cacheArgs Cache args.
     */
    private void cacheResetLostPartitions(GridClient client, CacheArguments cacheArgs) throws GridClientException {

        CacheResetLostPartitionsTaskArg taskArg = new CacheResetLostPartitionsTaskArg(cacheArgs.caches());

        CacheResetLostPartitionsTaskResult res = executeTaskByNameOnNode(client, CacheResetLostPartitionsTask.class.getName(), taskArg, null);

        res.print(System.out);
    }

    /**
     * @param client Client.
     * @param cacheArgs Cache args.
     */
    private void cacheIdleVerifyDump(GridClient client, CacheArguments cacheArgs) throws GridClientException {
        String path = executeTask(
            client,
            VisorIdleVerifyDumpTask.class,
            new VisorIdleVerifyDumpTaskArg(cacheArgs.caches(), cacheArgs.isSkipZeros())
        );

        log("VisorIdleVerifyDumpTask successfully written output to '" + path + "'");
    }

    /**
     * @param client Client.
     * @param cacheArgs Cache args.
     */
    private void cacheIdleVerifyV2(GridClient client, CacheArguments cacheArgs) throws GridClientException {
        IdleVerifyResultV2 res = executeTask(
            client, VisorIdleVerifyTaskV2.class, new VisorIdleVerifyTaskArg(cacheArgs.caches()));

        res.print(System.out::print);
    }

    /**
     * Change baseline.
     *
     * @param client Client.
     * @param baselineAct Baseline action to execute.  @throws GridClientException If failed to execute baseline
     * action.
     * @param baselineArgs Baseline action arguments.
     * @throws Throwable If failed to execute baseline action.
     */
    private void baseline(GridClient client, String baselineAct, String baselineArgs) throws Throwable {
        switch (baselineAct) {
            case BASELINE_ADD:
                baselineAdd(client, baselineArgs);
                break;

            case BASELINE_REMOVE:
                baselineRemove(client, baselineArgs);
                break;

            case BASELINE_SET:
                baselineSet(client, baselineArgs);
                break;

            case BASELINE_SET_VERSION:
                baselineVersion(client, baselineArgs);
                break;

            case BASELINE_COLLECT:
                baselinePrint(client);
                break;
        }
    }

    /**
     * Prepare task argument.
     *
     * @param op Operation.
     * @param s Argument from command line.
     * @return Task argument.
     */
    private VisorBaselineTaskArg arg(VisorBaselineOperation op, String s) {
        switch (op) {
            case ADD:
            case REMOVE:
            case SET:
                List<String> consistentIds = getConsistentIds(s);

                return new VisorBaselineTaskArg(op, -1, consistentIds);

            case VERSION:
                try {
                    long topVer = Long.parseLong(s);

                    return new VisorBaselineTaskArg(op, topVer, null);
                }
                catch (NumberFormatException e) {
                    throw new IllegalArgumentException("Invalid topology version: " + s, e);
                }

            default:
                return new VisorBaselineTaskArg(op, -1, null);
        }
    }

    /**
     * @param s String of consisted ids delimited by comma.
     * @return List of consistent ids.
     */
    private List<String> getConsistentIds(String s) {
        if (F.isEmpty(s))
            throw new IllegalArgumentException("Empty list of consistent IDs");

        List<String> consistentIds = new ArrayList<>();

        for (String consistentId : s.split(","))
            consistentIds.add(consistentId.trim());

        return consistentIds;
    }

    /**
     * Print baseline topology.
     *
     * @param res Task result with baseline topology.
     */
    private void baselinePrint0(VisorBaselineTaskResult res) {
        log("Cluster state: " + (res.isActive() ? "active" : "inactive"));
        log("Current topology version: " + res.getTopologyVersion());
        nl();

        Map<String, VisorBaselineNode> baseline = res.getBaseline();

        Map<String, VisorBaselineNode> srvs = res.getServers();

        if (F.isEmpty(baseline))
            log("Baseline nodes not found.");
        else {
            log("Baseline nodes:");

            for (VisorBaselineNode node : baseline.values()) {
                log("    ConsistentID=" + node.getConsistentId() + ", STATE=" +
                    (srvs.containsKey(node.getConsistentId()) ? "ONLINE" : "OFFLINE"));
            }

            log(DELIM);
            log("Number of baseline nodes: " + baseline.size());

            nl();

            List<VisorBaselineNode> others = new ArrayList<>();

            for (VisorBaselineNode node : srvs.values()) {
                if (!baseline.containsKey(node.getConsistentId()))
                    others.add(node);
            }

            if (F.isEmpty(others))
                log("Other nodes not found.");
            else {
                log("Other nodes:");

                for (VisorBaselineNode node : others)
                    log("    ConsistentID=" + node.getConsistentId());

                log("Number of other nodes: " + others.size());
            }
        }
    }

    /**
     * Print current baseline.
     *
     * @param client Client.
     */
    private void baselinePrint(GridClient client) throws GridClientException {
        VisorBaselineTaskResult res = executeTask(client, VisorBaselineTask.class, arg(COLLECT, ""));

        baselinePrint0(res);
    }

    /**
     * Add nodes to baseline.
     *
     * @param client Client.
     * @param baselineArgs Baseline action arguments.
     * @throws Throwable If failed to add nodes to baseline.
     */
    private void baselineAdd(GridClient client, String baselineArgs) throws Throwable {
        try {
            VisorBaselineTaskResult res = executeTask(client, VisorBaselineTask.class, arg(ADD, baselineArgs));

            baselinePrint0(res);
        }
        catch (Throwable e) {
            log("Failed to add nodes to baseline.");

            throw e;
        }
    }

    /**
     * Remove nodes from baseline.
     *
     * @param client Client.
     * @param consistentIds Consistent IDs.
     * @throws Throwable If failed to remove nodes from baseline.
     */
    private void baselineRemove(GridClient client, String consistentIds) throws Throwable {
        try {
            VisorBaselineTaskResult res = executeTask(client, VisorBaselineTask.class, arg(REMOVE, consistentIds));

            baselinePrint0(res);
        }
        catch (Throwable e) {
            log("Failed to remove nodes from baseline.");

            throw e;
        }
    }

    /**
     * Set baseline.
     *
     * @param client Client.
     * @param consistentIds Consistent IDs.
     * @throws Throwable If failed to set baseline.
     */
    private void baselineSet(GridClient client, String consistentIds) throws Throwable {
        try {
            VisorBaselineTaskResult res = executeTask(client, VisorBaselineTask.class, arg(SET, consistentIds));

            baselinePrint0(res);
        }
        catch (Throwable e) {
            log("Failed to set baseline.");

            throw e;
        }
    }

    /**
     * Set baseline by topology version.
     *
     * @param client Client.
     * @param arg Argument from command line.
     */
    private void baselineVersion(GridClient client, String arg) throws GridClientException {
        try {
            VisorBaselineTaskResult res = executeTask(client, VisorBaselineTask.class, arg(VERSION, arg));

            baselinePrint0(res);
        }
        catch (Throwable e) {
            log("Failed to set baseline with specified topology version.");

            throw e;
        }
    }

    /**
     * Dump transactions information.
     *
     * @param client Client.
     * @param arg Transaction search arguments
     */
    private void transactions(GridClient client, VisorTxTaskArg arg) throws GridClientException {
        try {
            Map<ClusterNode, VisorTxTaskResult> res = executeTask(client, VisorTxTask.class, arg);

            lastOperationRes = res;

            if (res.isEmpty())
                log("Nothing found.");
            else if (arg.getOperation() == VisorTxOperation.KILL)
                log("Killed transactions:");
            else
                log("Matching transactions:");

            for (Map.Entry<ClusterNode, VisorTxTaskResult> entry : res.entrySet()) {
                if (entry.getValue().getInfos().isEmpty())
                    continue;

                ClusterNode key = entry.getKey();

                log(key.getClass().getSimpleName() + " [id=" + key.id() +
                    ", addrs=" + key.addresses() +
                    ", order=" + key.order() +
                    ", ver=" + key.version() +
                    ", isClient=" + key.isClient() +
                    ", consistentId=" + key.consistentId() +
                    "]");

                for (VisorTxInfo info : entry.getValue().getInfos())
                    log(info.toUserString());
            }
        }
        catch (Throwable e) {
            log("Failed to perform operation.");

            throw e;
        }
    }

    /**
     * Execute WAL command.
     *
     * @param client Client.
     * @param walAct WAL action to execute.
     * @param walArgs WAL args.
     * @throws Throwable If failed to execute wal action.
     */
    private void wal(GridClient client, String walAct, String walArgs) throws Throwable {
        switch (walAct) {
            case WAL_DELETE:
                deleteUnusedWalSegments(client, walArgs);

                break;

            case WAL_PRINT:
            default:
                printUnusedWalSegments(client, walArgs);

                break;
        }
    }

    /**
     * Execute delete unused WAL segments task.
     *
     * @param client Client.
     * @param walArgs WAL args.
     */
    private void deleteUnusedWalSegments(GridClient client, String walArgs) throws Throwable {
        VisorWalTaskResult res = executeTask(client, VisorWalTask.class,
            walArg(VisorWalTaskOperation.DELETE_UNUSED_WAL_SEGMENTS, walArgs));
        printDeleteWalSegments0(res);
    }

    /**
     * Execute print unused WAL segments task.
     *
     * @param client Client.
     * @param walArgs Wal args.
     */
    private void printUnusedWalSegments(GridClient client, String walArgs) throws Throwable {
        VisorWalTaskResult res = executeTask(client, VisorWalTask.class,
            walArg(VisorWalTaskOperation.PRINT_UNUSED_WAL_SEGMENTS, walArgs));
        printUnusedWalSegments0(res);
    }

    /**
     * Prepare WAL task argument.
     *
     * @param op Operation.
     * @param s Argument from command line.
     * @return Task argument.
     */
    private VisorWalTaskArg walArg(VisorWalTaskOperation op, String s) {
        List<String> consistentIds = null;

        if (!F.isEmpty(s)) {
            consistentIds = new ArrayList<>();

            for (String consistentId : s.split(","))
                consistentIds.add(consistentId.trim());
        }

        switch (op) {
            case DELETE_UNUSED_WAL_SEGMENTS:
            case PRINT_UNUSED_WAL_SEGMENTS:
                return new VisorWalTaskArg(op, consistentIds);

            default:
                return new VisorWalTaskArg(VisorWalTaskOperation.PRINT_UNUSED_WAL_SEGMENTS, consistentIds);
        }

    }

    /**
     * Print list of unused wal segments.
     *
     * @param taskRes Task result with baseline topology.
     */
    private void printUnusedWalSegments0(VisorWalTaskResult taskRes) {
        log("Unused wal segments per node:");
        nl();

        Map<String, Collection<String>> res = taskRes.results();
        Map<String, Exception> failRes = taskRes.exceptions();
        Map<String, VisorClusterNode> nodesInfo = taskRes.getNodesInfo();

        for (Map.Entry<String, Collection<String>> entry : res.entrySet()) {
            VisorClusterNode node = nodesInfo.get(entry.getKey());

            log("Node=" + node.getConsistentId());
            log("     addresses " + U.addressesAsString(node.getAddresses(), node.getHostNames()));

            for (String fileName : entry.getValue())
                log("   " + fileName);

            nl();
        }

        for (Map.Entry<String, Exception> entry : failRes.entrySet()) {
            VisorClusterNode node = nodesInfo.get(entry.getKey());

            log("Node=" + node.getConsistentId());
            log("     addresses " + U.addressesAsString(node.getAddresses(), node.getHostNames()));
            log("   failed with error: " + entry.getValue().getMessage());
            nl();
        }
    }

    /**
     * Print list of unused wal segments.
     *
     * @param taskRes Task result with baseline topology.
     */
    private void printDeleteWalSegments0(VisorWalTaskResult taskRes) {
        log("WAL segments deleted for nodes:");
        nl();

        Map<String, Collection<String>> res = taskRes.results();
        Map<String, Exception> errors = taskRes.exceptions();
        Map<String, VisorClusterNode> nodesInfo = taskRes.getNodesInfo();

        for (Map.Entry<String, Collection<String>> entry : res.entrySet()) {
            VisorClusterNode node = nodesInfo.get(entry.getKey());

            log("Node=" + node.getConsistentId());
            log("     addresses " + U.addressesAsString(node.getAddresses(), node.getHostNames()));
            nl();
        }

        for (Map.Entry<String, Exception> entry : errors.entrySet()) {
            VisorClusterNode node = nodesInfo.get(entry.getKey());

            log("Node=" + node.getConsistentId());
            log("     addresses " + U.addressesAsString(node.getAddresses(), node.getHostNames()));
            log("   failed with error: " + entry.getValue().getMessage());
            nl();
        }
    }

    /**
     * @param e Exception to check.
     * @return {@code true} if specified exception is {@link GridClientAuthenticationException}.
     */
    private boolean isAuthError(Throwable e) {
        return X.hasCause(e, GridClientAuthenticationException.class);
    }

    /**
     * @param e Exception to check.
     * @return {@code true} if specified exception is a connection error.
     */
    private boolean isConnectionError(Throwable e) {
        return e instanceof GridClientClosedException ||
            e instanceof GridClientConnectionResetException ||
            e instanceof GridClientDisconnectedException ||
            e instanceof GridClientHandshakeException ||
            e instanceof GridServerUnreachableException;
    }

    /**
     * Print command usage.
     *
     * @param desc Command description.
     * @param args Arguments.
     */
    private void usage(String desc, Command cmd, String... args) {
        log(desc);
        log("    control.sh [--host HOST_OR_IP] [--port PORT] [--user USER] [--password PASSWORD] " +
            " [--ping-interval PING_INTERVAL] [--ping-timeout PING_TIMEOUT] " + cmd.text() + String.join("", args));
        nl();
    }

    /**
     * Extract next argument.
     *
     * @param err Error message.
     * @return Next argument value.
     */
    private String nextArg(String err) {
        if (peekedArg != null) {
            String res = peekedArg;

            peekedArg = null;

            return res;
        }

        if (argsIt.hasNext())
            return argsIt.next();

        throw new IllegalArgumentException(err);
    }

    /**
     * Returns the next argument in the iteration, without advancing the iteration.
     *
     * @return Next argument value or {@code null} if no next argument.
     */
    private String peekNextArg() {
        if (peekedArg == null && argsIt.hasNext())
            peekedArg = argsIt.next();

        return peekedArg;
    }

    /**
     * Parses and validates arguments.
     *
     * @param rawArgs Array of arguments.
     * @return Arguments bean.
     * @throws IllegalArgumentException In case arguments aren't valid.
     */
    Arguments parseAndValidate(List<String> rawArgs) {
        String host = DFLT_HOST;

        String port = DFLT_PORT;

        String user = null;

        String pwd = null;

        String baselineAct = "";

        String baselineArgs = "";

        Long pingInterval = DFLT_PING_INTERVAL;

        Long pingTimeout = DFLT_PING_TIMEOUT;

        String walAct = "";

        String walArgs = "";

        boolean autoConfirmation = false;

        CacheArguments cacheArgs = null;

        List<Command> commands = new ArrayList<>();

        initArgIterator(rawArgs);

        VisorTxTaskArg txArgs = null;

        while (hasNextArg()) {
            String str = nextArg("").toLowerCase();

            Command cmd = Command.of(str);

            if (cmd != null) {
                switch (cmd) {
                    case ACTIVATE:
                    case DEACTIVATE:
                    case STATE:
                        commands.add(cmd);

                        break;

                    case TX:
                        commands.add(TX);

                        txArgs = parseTransactionArguments();

                        break;

                    case BASELINE:
                        commands.add(BASELINE);

                        baselineAct = BASELINE_COLLECT; //default baseline action

                        str = peekNextArg();

                        if (str != null) {
                            str = str.toLowerCase();

                            if (BASELINE_ADD.equals(str) || BASELINE_REMOVE.equals(str) ||
                                BASELINE_SET.equals(str) || BASELINE_SET_VERSION.equals(str)) {
                                baselineAct = nextArg("Expected baseline action");

                                baselineArgs = nextArg("Expected baseline arguments");
                            }
                        }

                        break;

                    case CACHE:
                        commands.add(CACHE);

                        cacheArgs = parseAndValidateCacheArgs();

                        break;

                    case WAL:
                        if (!enableExperimental)
                            throw new IllegalArgumentException("Experimental command is disabled.");

                        commands.add(WAL);

                        str = nextArg("Expected arguments for " + WAL.text());

                        walAct = str.toLowerCase();

                        if (WAL_PRINT.equals(walAct) || WAL_DELETE.equals(walAct))
                            walArgs = (str = peekNextArg()) != null && !isCommandOrOption(str)
                                ? nextArg("Unexpected argument for " + WAL.text() + ": " + walAct)
                                : "";
                        else
                            throw new IllegalArgumentException("Unexpected action " + walAct + " for " + WAL.text());

                        break;
                    default:
                        throw new IllegalArgumentException("Unexpected command: " + str);
                }
            }
            else {
                switch (str) {
                    case CMD_HOST:
                        host = nextArg("Expected host name");

                        break;

                    case CMD_PORT:
                        port = nextArg("Expected port number");

                        try {
                            int p = Integer.parseInt(port);

                            if (p <= 0 || p > 65535)
                                throw new IllegalArgumentException("Invalid value for port: " + port);
                        }
                        catch (NumberFormatException ignored) {
                            throw new IllegalArgumentException("Invalid value for port: " + port);
                        }

                        break;

                    case CMD_PING_INTERVAL:
                        pingInterval = getPingParam("Expected ping interval", "Invalid value for ping interval");

                        break;

                    case CMD_PING_TIMEOUT:
                        pingTimeout = getPingParam("Expected ping timeout", "Invalid value for ping timeout");

                        break;

                    case CMD_USER:
                        user = nextArg("Expected user name");

                        break;

                    case CMD_PASSWORD:
                        pwd = nextArg("Expected password");

                        break;

                    case CMD_AUTO_CONFIRMATION:
                        autoConfirmation = true;

                        break;

                    default:
                        throw new IllegalArgumentException("Unexpected argument: " + str);
                }
            }
        }

        int sz = commands.size();

        if (sz < 1)
            throw new IllegalArgumentException("No action was specified");

        if (sz > 1)
            throw new IllegalArgumentException("Only one action can be specified, but found: " + sz);

        Command cmd = commands.get(0);

        boolean hasUsr = F.isEmpty(user);
        boolean hasPwd = F.isEmpty(pwd);

        if (hasUsr != hasPwd)
            throw new IllegalArgumentException("Both user and password should be specified");

        return new Arguments(cmd, host, port, user, pwd, baselineAct, baselineArgs, txArgs, cacheArgs, walAct, walArgs,
            pingTimeout, pingInterval, autoConfirmation);
    }

    /**
     * Parses and validates cache arguments.
     *
     * @return --cache subcommand arguments in case validation is successful.
     */
    private CacheArguments parseAndValidateCacheArgs() {
        if (!hasNextCacheArg()) {
            throw new IllegalArgumentException("Arguments are expected for --cache subcommand, " +
                "run --cache help for more info.");
        }

        CacheArguments cacheArgs = new CacheArguments();

        String str = nextArg("").toLowerCase();

        CacheCommand cmd = CacheCommand.of(str);

        if (cmd == null)
            cmd = CacheCommand.HELP;

        cacheArgs.command(cmd);

        switch (cmd) {
            case HELP:
                break;

            case IDLE_VERIFY:
                int idleVerifyArgsCnt = 3;

                while (hasNextCacheArg() && idleVerifyArgsCnt-- > 0) {
                    String nextArg = nextArg("");

                    if (CMD_DUMP.equals(nextArg))
                        cacheArgs.dump(true);
                    else if (CMD_SKIP_ZEROS.equals(nextArg))
                        cacheArgs.skipZeros(true);
                    else
                        parseCacheNames(nextArg, cacheArgs);
                }
                break;

            case CONTENTION:
                cacheArgs.minQueueSize(Integer.parseInt(nextArg("Min queue size expected")));

                if (hasNextCacheArg())
                    cacheArgs.nodeId(UUID.fromString(nextArg("")));

                if (hasNextCacheArg())
                    cacheArgs.maxPrint(Integer.parseInt(nextArg("")));
                else
                    cacheArgs.maxPrint(10);

                break;

            case VALIDATE_INDEXES:
                int argsCnt = 0;

                while (hasNextCacheArg() && argsCnt++ < 4) {
                    String arg = nextArg("");

                    if (VI_CHECK_FIRST.equals(arg) || VI_CHECK_THROUGH.equals(arg)) {
                        if (!hasNextCacheArg())
                            throw new IllegalArgumentException("Numeric value for '" + arg + "' parameter expected.");

                        int numVal;

                        String numStr = nextArg("");

                        try {
                            numVal = Integer.parseInt(numStr);
                        }
                        catch (IllegalArgumentException e) {
                            throw new IllegalArgumentException(
                                "Not numeric value was passed for '"
                                    + arg
                                    + "' parameter: "
                                    + numStr
                            );
                        }

                        if (numVal <= 0)
                            throw new IllegalArgumentException("Value for '" + arg + "' property should be positive.");

                        if (VI_CHECK_FIRST.equals(arg))
                            cacheArgs.checkFirst(numVal);
                        else
                            cacheArgs.checkThrough(numVal);

                        continue;
                    }

                    try {
                        cacheArgs.nodeId(UUID.fromString(arg));

                        continue;
                    }
                    catch (IllegalArgumentException ignored) {
                        //No-op.
                    }

                    parseCacheNames(arg, cacheArgs);
                }

                break;

            case DISTRIBUTION:
                String nodeIdStr = nextArg("Node id expected or null");
                if (!"null".equals(nodeIdStr))
                    cacheArgs.nodeId(UUID.fromString(nodeIdStr));

                while (hasNextCacheArg()) {
                    String nextArg = nextArg("");

                    if (CMD_USER_ATTRIBUTES.equals(nextArg)){
                        nextArg = nextArg("User attributes are expected to be separated by commas");

                        Set<String> userAttributes = new HashSet();

                        for (String userAttribute:nextArg.split(","))
                            userAttributes.add(userAttribute.trim());

                        cacheArgs.setUserAttributes(userAttributes);

                        nextArg = (hasNextCacheArg()) ? nextArg("") : null;

                    }

                    if (nextArg!=null)
                        parseCacheNames(nextArg, cacheArgs);
                }

                break;

            case RESET_LOST_PARTITIONS:
                parseCacheNames(nextArg("Cache name expected"), cacheArgs);

                break;

            default:
                cacheArgs.regex(nextArg("Regex is expected"));

                if (hasNextCacheArg()) {
                    String tmp = nextArg("");

                    switch (tmp) {
                        case "groups":
                            cacheArgs.cacheCommand(GROUPS);

                            break;

                        case "seq":
                            cacheArgs.cacheCommand(SEQ);

                            break;

                        default:
                            cacheArgs.nodeId(UUID.fromString(tmp));
                    }
                }

                break;
        }

        if (hasNextCacheArg())
            throw new IllegalArgumentException("Unexpected argument of --cache subcommand: " + peekNextArg());

        return cacheArgs;
    }

    /**
     * @return <code>true</code> if there's next argument for --cache subcommand.
     */
    private boolean hasNextCacheArg() {
        return hasNextArg() && Command.of(peekNextArg()) == null && !AUX_COMMANDS.contains(peekNextArg());
    }

    /**
     * @param cacheArgs Cache args.
     */
    private void parseCacheNames(String cacheNames, CacheArguments cacheArgs) {
        String[] cacheNamesArr = cacheNames.split(",");
        Set<String> cacheNamesSet = new HashSet<>();

        for (String cacheName : cacheNamesArr) {
            if (F.isEmpty(cacheName))
                throw new IllegalArgumentException("Non-empty cache names expected.");

            cacheNamesSet.add(cacheName.trim());
        }

        cacheArgs.caches(cacheNamesSet);
    }

    /**
     * Get ping param for grid client.
     *
     * @param nextArgErr Argument extraction error message.
     * @param invalidErr Param validation error message.
     */
    private Long getPingParam(String nextArgErr, String invalidErr) {
        String raw = nextArg(nextArgErr);

        try {
            long val = Long.valueOf(raw);

            if (val <= 0)
                throw new IllegalArgumentException(invalidErr + ": " + val);
            else
                return val;
        }
        catch (NumberFormatException ignored) {
            throw new IllegalArgumentException(invalidErr + ": " + raw);
        }
    }

    /**
     * @return Transaction arguments.
     */
    private VisorTxTaskArg parseTransactionArguments() {
        VisorTxProjection proj = null;

        Integer limit = null;

        VisorTxSortOrder sortOrder = null;

        Long duration = null;

        Integer size = null;

        String lbRegex = null;

        List<String> consistentIds = null;

        VisorTxOperation op = VisorTxOperation.LIST;

        String xid = null;

        boolean end = false;

        do {
            String str = peekNextArg();

            if (str == null)
                break;

            switch (str) {
                case TX_LIMIT:
                    nextArg("");

                    limit = (int)nextLongArg(TX_LIMIT);
                    break;

                case TX_ORDER:
                    nextArg("");

                    sortOrder = VisorTxSortOrder.fromString(nextArg(TX_ORDER));

                    break;

                case TX_SERVERS:
                    nextArg("");

                    proj = VisorTxProjection.SERVER;
                    break;

                case TX_CLIENTS:
                    nextArg("");

                    proj = VisorTxProjection.CLIENT;
                    break;

                case TX_NODES:
                    nextArg("");

                    consistentIds = getConsistentIds(nextArg(TX_NODES));
                    break;

                case TX_DURATION:
                    nextArg("");

                    duration = nextLongArg(TX_DURATION) * 1000L;
                    break;

                case TX_SIZE:
                    nextArg("");

                    size = (int)nextLongArg(TX_SIZE);
                    break;

                case TX_LABEL:
                    nextArg("");

                    lbRegex = nextArg(TX_LABEL);

                    try {
                        Pattern.compile(lbRegex);
                    }
                    catch (PatternSyntaxException ignored) {
                        throw new IllegalArgumentException("Illegal regex syntax");
                    }

                    break;

                case TX_XID:
                    nextArg("");

                    xid = nextArg(TX_XID);
                    break;

                case TX_KILL:
                    nextArg("");

                    op = VisorTxOperation.KILL;
                    break;

                default:
                    end = true;
            }
        }
        while (!end);

        if (proj != null && consistentIds != null)
            throw new IllegalArgumentException("Projection can't be used together with list of consistent ids.");

        return new VisorTxTaskArg(op, limit, duration, size, null, proj, consistentIds, xid, lbRegex, sortOrder);
    }

    /**
     * @return Numeric value.
     */
    private long nextLongArg(String lb) {
        String str = nextArg("Expecting " + lb);

        try {
            long val = Long.parseLong(str);

            if (val < 0)
                throw new IllegalArgumentException("Invalid value for " + lb + ": " + val);

            return val;
        }
        catch (NumberFormatException ignored) {
            throw new IllegalArgumentException("Invalid value for " + lb + ": " + str);
        }
    }

    /**
     * Check if raw arg is command or option.
     *
     * @return {@code true} If raw arg is command, overwise {@code false}.
     */
    private boolean isCommandOrOption(String raw) {
        return raw != null && raw.contains("--");
    }

    /**
     * Parse and execute command.
     *
     * @param rawArgs Arguments to parse and execute.
     * @return Exit code.
     */
    public int execute(List<String> rawArgs) {
        log("Control utility [ver. " + ACK_VER_STR + "]");
        log(COPYRIGHT);
        log("User: " + System.getProperty("user.name"));
        log(DELIM);

        try {
            if (F.isEmpty(rawArgs) || (rawArgs.size() == 1 && CMD_HELP.equalsIgnoreCase(rawArgs.get(0)))) {
                log("This utility can do the following commands:");

                usage("  Activate cluster:", ACTIVATE);
                usage("  Deactivate cluster:", DEACTIVATE, " [" + CMD_AUTO_CONFIRMATION + "]");
                usage("  Print current cluster state:", STATE);
                usage("  Print cluster baseline topology:", BASELINE);
                usage("  Add nodes into baseline topology:", BASELINE, " add consistentId1[,consistentId2,....,consistentIdN] [" + CMD_AUTO_CONFIRMATION + "]");
                usage("  Remove nodes from baseline topology:", BASELINE, " remove consistentId1[,consistentId2,....,consistentIdN] [" + CMD_AUTO_CONFIRMATION + "]");
                usage("  Set baseline topology:", BASELINE, " set consistentId1[,consistentId2,....,consistentIdN] [" + CMD_AUTO_CONFIRMATION + "]");
                usage("  Set baseline topology based on version:", BASELINE, " version topologyVersion [" + CMD_AUTO_CONFIRMATION + "]");
                usage("  List or kill transactions:", TX, " [xid XID] [minDuration SECONDS] " +
                    "[minSize SIZE] [label PATTERN_REGEX] [servers|clients] " +
                    "[nodes consistentId1[,consistentId2,....,consistentIdN] [limit NUMBER] [order DURATION|SIZE|", CMD_TX_ORDER_START_TIME, "] [kill] [" + CMD_AUTO_CONFIRMATION + "]");

                if (enableExperimental) {
                    usage("  Print absolute paths of unused archived wal segments on each node:", WAL,
                        " print [consistentId1,consistentId2,....,consistentIdN]");
                    usage("  Delete unused archived wal segments on each node:", WAL,
                        " delete [consistentId1,consistentId2,....,consistentIdN] [" + CMD_AUTO_CONFIRMATION + "]");
                }

                log("  View caches information in a cluster. For more details type:");
                log("    control.sh --cache help");
                nl();

                log("By default commands affecting the cluster require interactive confirmation.");
                log("Use " + CMD_AUTO_CONFIRMATION + " option to disable it.");
                nl();

                log("Default values:");
                log("    HOST_OR_IP=" + DFLT_HOST);
                log("    PORT=" + DFLT_PORT);
                log("    PING_INTERVAL=" + DFLT_PING_INTERVAL);
                log("    PING_TIMEOUT=" + DFLT_PING_TIMEOUT);
                nl();

                log("Exit codes:");
                log("    " + EXIT_CODE_OK + " - successful execution.");
                log("    " + EXIT_CODE_INVALID_ARGUMENTS + " - invalid arguments.");
                log("    " + EXIT_CODE_CONNECTION_FAILED + " - connection failed.");
                log("    " + ERR_AUTHENTICATION_FAILED + " - authentication failed.");
                log("    " + EXIT_CODE_UNEXPECTED_ERROR + " - unexpected error.");

                return EXIT_CODE_OK;
            }

            Arguments args = parseAndValidate(rawArgs);

            if (!args.autoConfirmation() && !confirm(args)) {
                log("Operation cancelled.");

                return EXIT_CODE_OK;
            }

            clientCfg = new GridClientConfiguration();

            clientCfg.setPingInterval(args.pingInterval());

            clientCfg.setPingTimeout(args.pingTimeout());

            clientCfg.setServers(Collections.singletonList(args.host() + ":" + args.port()));

            if (!F.isEmpty(args.user())) {
                clientCfg.setSecurityCredentialsProvider(
                    new SecurityCredentialsBasicProvider(new SecurityCredentials(args.user(), args.password())));
            }

            try (GridClient client = GridClientFactory.start(clientCfg)) {
                switch (args.command()) {
                    case ACTIVATE:
                        activate(client);

                        break;

                    case DEACTIVATE:
                        deactivate(client);

                        break;

                    case STATE:
                        state(client);

                        break;

                    case BASELINE:
                        baseline(client, args.baselineAction(), args.baselineArguments());

                        break;

                    case TX:
                        transactions(client, args.transactionArguments());

                        break;

                    case CACHE:
                        cache(client, args.cacheArgs());

                        break;

                    case WAL:
                        wal(client, args.walAction(), args.walArguments());

                        break;
                }
            }

            return 0;
        }
        catch (IllegalArgumentException e) {
            return error(EXIT_CODE_INVALID_ARGUMENTS, "Check arguments.", e);
        }
        catch (Throwable e) {
            if (isAuthError(e))
                return error(ERR_AUTHENTICATION_FAILED, "Authentication error.", e);

            if (isConnectionError(e))
                return error(EXIT_CODE_CONNECTION_FAILED, "Connection to cluster failed.", e);

            return error(EXIT_CODE_UNEXPECTED_ERROR, "", e);
        }
    }

    /**
     * @param args Arguments to parse and apply.
     */
    public static void main(String[] args) {
        CommandHandler hnd = new CommandHandler();

        System.exit(hnd.execute(Arrays.asList(args)));
    }

    /**
     * Used for tests.
     *
     * @return Last operation result;
     */
    @SuppressWarnings("unchecked")
    public <T> T getLastOperationResult() {
        return (T)lastOperationRes;
    }
}

