/*
 * Copyright 2017 HugeGraph Authors
 *
 * 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 com.baidu.hugegraph.cmd;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;

import com.baidu.hugegraph.api.API;
import com.baidu.hugegraph.constant.AuthRestoreConflictStrategy;
import com.baidu.hugegraph.manager.TasksManager;
import com.baidu.hugegraph.structure.constant.GraphMode;
import com.baidu.hugegraph.structure.constant.HugeType;
import com.baidu.hugegraph.util.E;
import com.baidu.hugegraph.util.InsertionOrderUtil;
import com.beust.jcommander.DynamicParameter;
import com.beust.jcommander.IParameterValidator;
import com.beust.jcommander.IStringConverter;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.ParameterException;
import com.beust.jcommander.Parameters;
import com.beust.jcommander.ParametersDelegate;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;

public class SubCommands {

    private Map<String, Object> commands;

    public SubCommands() {
        this.commands = InsertionOrderUtil.newMap();
        this.initSubCommands();
    }

    private void initSubCommands() {
        this.commands.put("graph-list", new GraphList());
        this.commands.put("graph-get", new GraphGet());
        this.commands.put("graph-clear", new GraphClear());
        this.commands.put("graph-mode-set", new GraphModeSet());
        this.commands.put("graph-mode-get", new GraphModeGet());

        this.commands.put("task-list", new TaskList());
        this.commands.put("task-get", new TaskGet());
        this.commands.put("task-delete", new TaskDelete());
        this.commands.put("task-cancel", new TaskCancel());
        this.commands.put("task-clear", new TaskClear());

        this.commands.put("gremlin-execute", new Gremlin());
        this.commands.put("gremlin-schedule", new GremlinJob());

        this.commands.put("backup", new Backup());
        this.commands.put("schedule-backup", new ScheduleBackup());
        this.commands.put("dump", new DumpGraph());
        this.commands.put("restore", new Restore());
        this.commands.put("migrate", new Migrate());

        this.commands.put("deploy", new Deploy());
        this.commands.put("start-all", new StartAll());
        this.commands.put("clear", new Clear());
        this.commands.put("stop-all", new StopAll());

        this.commands.put("auth-backup", new AuthBackup());
        this.commands.put("auth-restore", new AuthRestore());

        this.commands.put("help", new Help());
    }

    public Map<String, Object> commands() {
        return this.commands;
    }

    @Parameters(commandDescription = "Schedule backup task")
    public static class ScheduleBackup {

        @Parameter(names = {"--interval"}, arity = 1,
                   description =
                           "The interval of backup, format is: \"a b c d e\"." +
                           " 'a' means minute (0 - 59)," +
                           " 'b' means hour (0 - 23)," +
                           " 'c' means day of month (1 - 31)," +
                           " 'd' means month (1 - 12)," +
                           " 'e' means day of week (0 - 6) (Sunday=0)," +
                           " \"*\" means all")
        public String interval = "\"0 0 * * *\"";

        @Parameter(names = {"--backup-num"}, arity = 1,
                   description = "The number of latest backups to keep")
        public int num = 3;

        @Parameter(names = {"--directory", "-d"}, arity = 1, required = true,
                   description = "The directory of backups stored")
        public String directory;
    }

    @Parameters(commandDescription = "Backup graph schema/data. If directory " +
                                     "is on HDFS, use -D to set HDFS params. " +
                                     "For example: " +
                                     "-Dfs.default.name=hdfs://localhost:9000")
    public static class Backup extends BackupRestore {

        @Parameter(names = {"--split-size", "-s"}, arity = 1,
                   description = "Split size of shard")
        public long splitSize = 1024 * 1024L;

        @ParametersDelegate
        private HugeTypes types = new HugeTypes();

        @Parameter(names = {"--format"}, arity = 1,
                   validateWith = {FormatValidator.class},
                   description = "File format, valid is [json, text]")
        public String format = "json";

        @Parameter(names = {"--compress"}, arity = 1,
                   description = "compress flag")
        public boolean compress = true;

        @Parameter(names = {"--label"}, arity = 1,
                   description = "Vertex label or edge label, only valid when type " +
                                 "is vertex or edge")
        public String label;

        @Parameter(names = {"--all-properties"}, arity = 1,
                   description = "All properties to be backup flag")
        public boolean allProperties = false;

        @Parameter(names = {"--properties"}, arity = 1,
                   description = "Vertex or edge properties to backup, " +
                                 "only valid when type is vertex or edge")
        public List<String> properties = ImmutableList.of();

        public long splitSize() {
            return this.splitSize;
        }

        public void splitSize(long splitSize) {
            this.splitSize = splitSize;
        }

        public List<HugeType> types() {
            return this.types.types;
        }

        public void types(List<HugeType> types) {
            this.types.types = types;
        }

        public String format() {
            return this.format;
        }

        public void format(String format) {
            this.format = format;
        }

        public boolean compress() {
            return this.compress;
        }

        public void compress(boolean compress) {
            this.compress = compress;
        }

        public String label() {
            return this.label;
        }

        public void label(String label) {
            this.label = label;
        }

        public boolean allProperties() {
            return this.allProperties;
        }

        public void allProperties(boolean allProperties) {
            this.allProperties = allProperties;
        }

        public List<String> properties() {
            return this.properties;
        }

        public void properties(List<String> properties) {
            this.properties = properties;
        }
    }

    @Parameters(commandDescription = "Restore graph schema/data. If directory" +
                                     " is on HDFS, use -D to set HDFS params " +
                                     "if needed. For example:" +
                                     "-Dfs.default.name=hdfs://localhost:9000")
    public static class Restore extends BackupRestore {
        @Parameter(names = {"--clean"},
                   description = "Whether to remove the directory of " +
                                 "graph data after restored")
        public boolean clean = false;

        @ParametersDelegate
        private HugeTypes types = new HugeTypes();

        public boolean clean() {
            return this.clean;
        }

        public void clean(boolean clean) {
            this.clean = clean;
        }

        public List<HugeType> types() {
            return this.types.types;
        }

        public void types(List<HugeType> types) {
            this.types.types = types;
        }
    }

    @Parameters(commandDescription = "Dump graph to files")
    public static class DumpGraph extends BackupRestore {

        @Parameter(names = {"--formatter", "-f"}, arity = 1,
                   description = "Formatter to customize format of vertex/edge")
        public String formatter = "JsonFormatter";

        @Parameter(names = {"--split-size", "-s"}, arity = 1,
                   description = "Split size of shard")
        public long splitSize = 1024 * 1024L;

        public String formatter() {
            return this.formatter;
        }

        public long splitSize() {
            return this.splitSize;
        }

        public void splitSize(long splitSize) {
            this.splitSize = splitSize;
        }
    }

    @Parameters(commandDescription = "Migrate graph")
    public static class Migrate extends BackupRestore {

        @Parameter(names = {"--split-size", "-s"}, arity = 1,
                   description = "Split size of shard")
        public long splitSize = 1024 * 1024L;

        @ParametersDelegate
        private HugeTypes types = new HugeTypes();

        @Parameter(names = {"--target-url"}, arity = 1,
                   description = "The url of target graph to migrate")
        public String targetUrl = "http://127.0.0.1:8081";

        @Parameter(names = {"--target-graph"}, arity = 1,
                   description = "The name of target graph to migrate")
        public String targetGraph = "hugegraph";

        @Parameter(names = {"--target-user"}, arity = 1,
                   description = "The username of target graph to migrate")
        public String targetUsername;

        @Parameter(names = {"--target-password"}, arity = 1,
                   description = "The password of target graph to migrate")
        public String targetPassword;

        @Parameter(names = {"--target-timeout"}, arity = 1,
                   description = "The timeout to connect target graph to " +
                                 "migrate")
        public int targetTimeout;

        @Parameter(names = {"--target-trust-store-file"}, arity = 1,
                   description = "The trust store file of target graph to " +
                                 "migrate")
        public String targetTrustStoreFile;

        @Parameter(names = {"--target-trust-store-password"}, arity = 1,
                   description = "The trust store password of target graph " +
                                 "to migrate")
        public String targetTrustStorePassword;

        @Parameter(names = {"--graph-mode", "-m"}, arity = 1,
                   converter = GraphModeConverter.class,
                   description = "Mode used when migrating to target graph, " +
                                 "include: [RESTORING, MERGING]")
        public GraphMode mode = GraphMode.RESTORING;

        @Parameter(names = {"--keep-local-data"},
                   description = "Whether to keep the local directory of " +
                                 "graph data after restored")
        public boolean keepData = false;

        public long splitSize() {
            return this.splitSize;
        }

        public void splitSize(long splitSize) {
            this.splitSize = splitSize;
        }

        public List<HugeType> types() {
            return this.types.types;
        }

        public void types(List<HugeType> types) {
            this.types.types = types;
        }

        public String targetUrl() {
            return this.targetUrl;
        }

        public String targetGraph() {
            return this.targetGraph;
        }

        public String targetUsername() {
            return this.targetUsername;
        }

        public String targetPassword() {
            return this.targetPassword;
        }

        public int targetTimeout() {
            return this.targetTimeout;
        }

        public String targetTrustStoreFile() {
            return this.targetTrustStoreFile;
        }

        public String targetTrustStorePassword() {
            return this.targetTrustStorePassword;
        }

        public GraphMode mode() {
            return this.mode;
        }

        public boolean keepData() {
            return this.keepData;
        }
    }

    @Parameters(commandDescription = "List all graphs")
    public static class GraphList {
    }

    @Parameters(commandDescription = "Get graph info")
    public static class GraphGet {}

    @Parameters(commandDescription = "Clear graph schema and data")
    public static class GraphClear {

        @ParametersDelegate
        private ConfirmMessage message = new ConfirmMessage();

        public String confirmMessage() {
            return this.message.confirmMessage;
        }
    }

    @Parameters(commandDescription = "Set graph mode")
    public static class GraphModeSet {

        @ParametersDelegate
        private Mode mode = new Mode();

        public GraphMode mode() {
            return this.mode.mode;
        }
    }

    @Parameters(commandDescription = "Get graph mode")
    public static class GraphModeGet {}

    @Parameters(commandDescription = "Execute Gremlin statements")
    public static class Gremlin extends GremlinJob {

        @ParametersDelegate
        private Aliases aliases = new Aliases();

        public Map<String, String> aliases() {
            return this.aliases.aliases;
        }
    }

    @Parameters(commandDescription = "Execute Gremlin statements as " +
                                     "asynchronous job")
    public static class GremlinJob {

        @ParametersDelegate
        private FileScript fileScript = new FileScript();

        @ParametersDelegate
        private GremlinScript cmdScript = new GremlinScript();

        @ParametersDelegate
        private Language language = new Language();

        @ParametersDelegate
        private Bindings bindings = new Bindings();

        public String fileScript() {
            return this.fileScript.script;
        }

        public String cmdScript() {
            return this.cmdScript.script;
        }

        public String language() {
            return this.language.language;
        }

        public Map<String, String> bindings() {
            return this.bindings.bindings;
        }

        public String script() {
            String script;
            if (this.cmdScript() == null) {
                E.checkArgument(this.fileScript() != null,
                                "Either --script or --file must " +
                                "be provided, but both are null");
                script = this.fileScript();
            } else {
                E.checkArgument(this.fileScript() == null,
                                "Either --script or --file must " +
                                "be provided, but both are provided: " +
                                "'%s' and '%s'",
                                this.cmdScript(), this.fileScript());
                script = this.cmdScript();
            }
            return script;
        }
    }

    @Parameters(commandDescription = "List tasks")
    public static class TaskList {

        @ParametersDelegate
        private TaskStatus status = new TaskStatus();

        @ParametersDelegate
        private Limit limit = new Limit();

        public String status() {
            if (this.status.status == null) {
                return null;
            }
            return this.status.status.toUpperCase();
        }

        public long limit() {
            return this.limit.limit;
        }
    }

    @Parameters(commandDescription = "Get task info")
    public static class TaskGet {

        @ParametersDelegate
        private TaskId taskId = new TaskId();

        public long taskId() {
            return this.taskId.taskId;
        }
    }

    @Parameters(commandDescription = "Delete task")
    public static class TaskDelete {

        @ParametersDelegate
        private TaskId taskId = new TaskId();

        public long taskId() {
            return this.taskId.taskId;
        }
    }

    @Parameters(commandDescription = "Cancel task")
    public static class TaskCancel {

        @ParametersDelegate
        private TaskId taskId = new TaskId();

        public long taskId() {
            return this.taskId.taskId;
        }
    }

    @Parameters(commandDescription = "Clear completed tasks")
    public static class TaskClear {

        @Parameter(names = "--force",
                   description = "Force to clear all tasks, " +
                                 "cancel all uncompleted tasks firstly, " +
                                 "and delete all completed tasks")
        private boolean force = false;

        public boolean force() {
            return this.force;
        }
    }

    @Parameters(commandDescription = "Install HugeGraph-Server and " +
                                     "HugeGraph-Studio")
    public static class Deploy {

        @ParametersDelegate
        private Version version = new Version();

        @ParametersDelegate
        public InstallPath path = new InstallPath();

        @ParametersDelegate
        public DownloadURL url = new DownloadURL();
    }

    @Parameters(commandDescription = "Start HugeGraph-Server and " +
                                     "HugeGraph-Studio")
    public static class StartAll {

        @ParametersDelegate
        private Version version = new Version();

        @ParametersDelegate
        public InstallPath path = new InstallPath();
    }

    @Parameters(commandDescription = "Clear HugeGraph-Server and " +
                                     "HugeGraph-Studio")
    public static class Clear {

        @ParametersDelegate
        public InstallPath path = new InstallPath();
    }

    @Parameters(commandDescription = "Stop HugeGraph-Server and " +
                                     "HugeGraph-Studio")
    public static class StopAll {
    }

    @Parameters(commandDescription = "Print usage")
    public static class Help {
    }

    public static class BackupRestore {

        @Parameter(names = {"--directory", "-d"}, arity = 1,
                   description = "Directory of graph schema/data, default is " +
                                 "'./{graphname}' in local file system " +
                                 "or '{fs.default.name}/{graphname}' in HDFS")
        public String directory;

        @Parameter(names = {"--log", "-l"}, arity = 1,
                   description = "Directory of log")
        public String logDir = "./logs";

        @Parameter(names = {"--thread-num", "-T"}, arity = 1,
                   validateWith = {PositiveValidator.class},
                   description = "Threads number to use, default is " +
                                 "Math.min(10, Math.max(4, CPUs / 2))")
        public int threadsNum;

        @ParametersDelegate
        private Retry retry = new Retry();

        @DynamicParameter(names = "-D",
                          description = "HDFS config parameters")
        private Map<String, String> hdfsConf = new HashMap<>();

        public String directory() {
            return this.directory;
        }

        public String logDir() {
            return this.logDir;
        }

        public int threadsNum() {
            return this.threadsNum;
        }

        public int retry() {
            return this.retry.retry;
        }

        public Map<String, String> hdfsConf() {
            return this.hdfsConf;
        }

        public void directory(String directory) {
            this.directory = directory;
        }

        public void logDir(String logDir) {
            this.logDir = logDir;
        }

        public void retry(int retry) {
            this.retry.retry = retry;
        }

        public void hdfsConf(Map<String, String> hdfsConf) {
            this.hdfsConf = hdfsConf;
        }
    }

    public static class Url {

        @Parameter(names = {"--url"}, arity = 1,
                   validateWith = {UrlValidator.class},
                   description = "The URL of HugeGraph-Server")
        public String url = "http://127.0.0.1:8080";
    }

    public static class Graph {

        @Parameter(names = {"--graph"}, arity = 1,
                   description = "Name of graph")
        public String graph = "hugegraph";
    }

    public static class Username {

        @Parameter(names = {"--user"}, arity = 1,
                   description = "Name of user")
        public String username;
    }

    public static class Password {

        @Parameter(names = {"--password"}, arity = 1,
                   description = "Password of user")
        public String password;
    }

    public static class Timeout {

        @Parameter(names = {"--timeout"}, arity = 1,
                   description = "Connection timeout")
        public int timeout = 30;
    }

    public static class Protocol {

        @Parameter(names = {"--protocol"}, arity = 1,
                   validateWith = {ProtocolValidator.class},
                   description = "The Protocol of HugeGraph-Server, allowed values " +
                                 "are: http or https")
        public String protocol = "http";
    }

    public static class TrustStoreFile {

        @Parameter(names = {"--trust-store-file"}, arity = 1,
                   description = "The path of client truststore file used when " +
                                 "https protocol is enabled")
        public String trustStoreFile;
    }

    public static class TrustStorePassword {

        @Parameter(names = {"--trust-store-password"}, arity = 1,
                   description = "The password of the client truststore file " +
                                 "used when the https protocol is enabled")
        public String trustStorePassword;
    }

    public static class ThrowMode {

        @Parameter(names = {"--throw-mode"}, arity = 1,
                   description = "Whether the hugegraph-tools work " +
                                 "to throw an exception")
        public boolean throwMode = false;
    }

    public static class HugeTypes {

        @Parameter(names = {"--huge-types", "-t"},
                   listConverter = HugeTypeListConverter.class,
                   description = "Type of schema/data. Concat with ',' if more " +
                                 "than one. Other types include 'all' and " +
                                 "'schema'. 'all' means all vertices, edges and " +
                                 "schema. In other words, 'all' equals with " +
                                 "'vertex, edge, vertex_label, edge_label, " +
                                 "property_key, index_label'. 'schema' equals " +
                                 "with 'vertex_label, edge_label, property_key, " +
                                 "index_label'.")
        public List<HugeType> types = HugeTypeListConverter.ALL_TYPES;
    }

    public static class InstallPath {

        @Parameter(names = {"-p"}, arity = 1, required = true,
                   description = "Install path of HugeGraph-Server and " +
                                 "HugeGraph-Studio")
        public String directory;
    }

    public static class DownloadURL {

        @Parameter(names = {"-u"}, arity = 1,
                   description = "Download url prefix path of " +
                                 "HugeGraph-Server and HugeGraph-Studio")
        public String url = null;
    }

    public static class ConfirmMessage {

        @Parameter(names = {"--confirm-message", "-c"}, arity = 1,
                   description = "Confirm message of graph clear is " +
                                 "\"I'm sure to delete all data\". " +
                                 "(Note: include \"\")",
                   required = true)
        public String confirmMessage;
    }

    public static class Mode {

        @Parameter(names = {"--graph-mode", "-m"}, arity = 1,
                   converter = GraphModeConverter.class,
                   description = "Graph mode, " +
                                 "include: [NONE, RESTORING, MERGING]",
                   required = true)
        public GraphMode mode;
    }

    public static class FileScript {

        @Parameter(names = {"--file", "-f"}, arity = 1,
                   converter = FileNameToContentConverter.class,
                   description = "Gremlin Script file to be executed, UTF-8 " +
                                 "encoded, exclusive to --script")
        public String script;
    }

    public static class GremlinScript {

        @Parameter(names = {"--script", "-s"}, arity = 1,
                   description = "Gremlin script to be executed, " +
                                 "exclusive to --file")
        public String script;
    }

    public static class Language {

        @Parameter(names = {"--language", "-l"}, arity = 1,
                   description = "Gremlin script language")
        public String language = "gremlin-groovy";
    }

    public static class Bindings {

        @Parameter(names = {"--bindings", "-b"}, arity = 1,
                   converter = MapConverter.class,
                   description = "Gremlin bindings, valid format is: " +
                                 "'key1=value1,key2=value2...'")
        public Map<String, String> bindings = ImmutableMap.of();
    }

    public static class Aliases {

        @Parameter(names = {"--aliases", "-a"}, arity = 1,
                   converter = MapConverter.class,
                   description = "Gremlin aliases, valid format is: " +
                                 "'key1=value1,key2=value2...'")
        public Map<String, String> aliases = ImmutableMap.of();
    }

    public static class Version {

        @Parameter(names = {"-v"}, arity = 1, required = true,
                   description = "Version of HugeGraph-Server and " +
                                 "HugeGraph-Studio")
        public String version;
    }

    public static class Retry {

        @Parameter(names = {"--retry"}, arity = 1,
                   validateWith = {PositiveValidator.class},
                   description = "Retry times, default is 3")
        public int retry = 3;
    }

    public static class Limit {

        @Parameter(names = {"--limit"}, arity = 1,
                   validateWith = {PositiveValidator.class},
                   description = "Limit number, no limit if not provided")
        public long limit = -1;
    }

    public static class TaskStatus {

        @Parameter(names = {"--status"}, arity = 1,
                   validateWith = TaskStatusValidator.class,
                   description = "Status of task")
        public String status = null;
    }

    public static class TaskId {

        @Parameter(names = {"--task-id"}, arity = 1, required = true,
                   validateWith = {PositiveValidator.class},
                   description = "Task id")
        private long taskId;
    }

    public static class AuthBackupRestore {

        @ParametersDelegate
        private AuthTypes types = new AuthTypes();

        @Parameter(names = {"--directory"}, arity = 1,
                   description = "Directory of auth information, default " +
                                 "is './{auth-backup-restore}' in local " +
                                 "file system or '{fs.default.name}/" +
                                 "{auth-backup-restore}' in HDFS")
        public String directory;

        @DynamicParameter(names = "-D",
                          description = "HDFS config parameters")
        private Map<String, String> hdfsConf = new HashMap<>();

        @ParametersDelegate
        private Retry retry = new Retry();

        public List<HugeType> types() {
            return this.types.types;
        }

        public void types(List<HugeType> types) {
            this.types.types = types;
        }

        public int retry() {
            return this.retry.retry;
        }

        public void retry(int retry) {
            this.retry.retry = retry;
        }

        public String directory() {
            return this.directory;
        }

        public void directory(String directory) {
            this.directory = directory;
        }

        public Map<String, String> hdfsConf() {
            return this.hdfsConf;
        }

        public void hdfsConf(Map<String, String> hdfsConf) {
            this.hdfsConf = hdfsConf;
        }
    }

    public static class AuthBackup extends AuthBackupRestore {
    }

    public static class AuthRestore extends AuthBackupRestore {

        @Parameter(names = {"--strategy"},
                   converter = AuthStrategyConverter.class,
                   description = "The strategy needs to be chosen in the event " +
                                 "of a conflict when restoring. Valid " +
                                 "strategies include 'stop' and 'ignore', " +
                                 "default is 'stop'. 'stop' means if there " +
                                 "a conflict, stop restore. 'ignore' means if " +
                                 "there a conflict, ignore and continue to " +
                                 "restore.")
        public AuthRestoreConflictStrategy strategy = AuthStrategyConverter.strategy;

        @Parameter(names = {"--init-password"}, arity = 1,
                   description = "Init user password, if restore type include " +
                                 "'user', please specify the init-password of " +
                                 "users.")
        public String initPassword = StringUtils.EMPTY;

        public AuthRestoreConflictStrategy strategy() {
            return this.strategy;
        }

        public void strategy(AuthRestoreConflictStrategy strategy) {
            this.strategy = strategy;
        }

        public String initPassword() {
            return this.initPassword;
        }

        public void initPassword(String initPassword) {
            this.initPassword = initPassword;
        }
    }

    public static class AuthTypes {

        @Parameter(names = {"--types", "-t"},
                   listConverter = AuthHugeTypeConverter.class,
                   description = "Type of auth data to restore and backup, " +
                                 "concat with ',' if more than one. 'all' " +
                                 "means all auth information. In other words, " +
                                 "'all' equals with 'user, group, target, " +
                                 "belong, access'. In addition, 'belong' or " +
                                 "'access' can not backup or restore alone, if " +
                                 "type contains 'belong' then should contains " +
                                 "'user' and 'group'. If type contains 'access' " +
                                 "then should contains 'group' and 'target'.")
        public List<HugeType> types = AuthHugeTypeConverter.AUTH_ALL_TYPES;
    }

    public static class GraphModeConverter
                  implements IStringConverter<GraphMode> {

        @Override
        public GraphMode convert(String value) {
            E.checkArgument(value != null && !value.isEmpty(),
                            "GraphMode can't be null or empty");
            return GraphMode.valueOf(value);
        }
    }

    public static class HugeTypeListConverter
                  implements IStringConverter<List<HugeType>> {

        public static final List<HugeType> ALL_TYPES = ImmutableList.of(
                HugeType.PROPERTY_KEY, HugeType.VERTEX_LABEL,
                HugeType.EDGE_LABEL, HugeType.INDEX_LABEL,
                HugeType.VERTEX, HugeType.EDGE
        );

        public static final List<HugeType> SCHEMA_TYPES = ImmutableList.of(
                HugeType.PROPERTY_KEY, HugeType.VERTEX_LABEL,
                HugeType.EDGE_LABEL, HugeType.INDEX_LABEL
        );

        @Override
        public List<HugeType> convert(String value) {
            E.checkArgument(value != null && !value.isEmpty(),
                            "HugeType can't be null or empty");
            String[] types = value.split(",");
            if (types.length == 1 && types[0].equalsIgnoreCase("all")) {
                return ALL_TYPES;
            }
            if (types.length == 1 && types[0].equalsIgnoreCase("schema")) {
                return SCHEMA_TYPES;
            }
            List<HugeType> hugeTypes = new ArrayList<>();
            for (String type : types) {
                try {
                    hugeTypes.add(HugeType.valueOf(type.toUpperCase()));
                } catch (IllegalArgumentException e) {
                    throw new ParameterException(String.format(
                              "Invalid --type '%s', valid value is 'all' or " +
                              "combination of 'vertex,edge,vertex_label," +
                              "edge_label,property_key,index_label'", type));
                }
            }
            return hugeTypes;
        }
    }

    public static class AuthHugeTypeConverter
                  implements IStringConverter<List<HugeType>> {

        public static final List<HugeType> AUTH_ALL_TYPES = ImmutableList.of(
                HugeType.TARGET, HugeType.GROUP,
                HugeType.USER, HugeType.ACCESS,
                HugeType.BELONG
        );

        @Override
        public List<HugeType> convert(String value) {
            E.checkArgument(value != null && !value.isEmpty(),
                            "HugeType can't be null or empty");
            String[] types = value.split(",");
            if (types.length == 1 && types[0].equalsIgnoreCase("all")) {
                return AUTH_ALL_TYPES;
            }
            List<String> typeList = Arrays.asList(types);
            E.checkArgument(!typeList.contains(HugeType.BELONG.toString().toLowerCase()) ||
                            (typeList.contains(HugeType.USER.toString().toLowerCase()) &&
                            typeList.contains(HugeType.GROUP.toString().toLowerCase())),
                            "Invalid --type '%s', if type contains 'belong'" +
                            " then 'user' and 'group' are required.", value);
            E.checkArgument(!typeList.contains(HugeType.ACCESS.toString().toLowerCase()) ||
                            (typeList.contains(HugeType.GROUP.toString().toLowerCase()) &&
                            typeList.contains(HugeType.TARGET.toString().toLowerCase())),
                            "Invalid --type '%s', if type contains 'access'" +
                            " then 'group' and 'target' are required.", value);
            List<HugeType> hugeTypes = new ArrayList<>();
            for (String type : types) {
                try {
                    hugeTypes.add(HugeType.valueOf(type.toUpperCase()));
                } catch (IllegalArgumentException e) {
                    throw new IllegalArgumentException(String.format(
                              "Invalid --type '%s', valid value is 'all' or " +
                              "combination of [user,group,target," +
                              "belong,access]", type));
                }
            }
            return hugeTypes;
        }
    }

    public static class AuthStrategyConverter
                  implements IStringConverter<AuthRestoreConflictStrategy> {

        public static final AuthRestoreConflictStrategy strategy =
                            AuthRestoreConflictStrategy.STOP;

        @Override
        public AuthRestoreConflictStrategy convert(String value) {
            E.checkArgument(value != null && !value.isEmpty(),
                            "Strategy can't be null or empty");
            E.checkArgument(AuthRestoreConflictStrategy.matchStrategy(value),
                            "Invalid --strategy '%s', valid value is " +
                            "'stop' or 'ignore", value);
            return AuthRestoreConflictStrategy.fromName(value);
        }
    }

    public static class MapConverter
                  implements IStringConverter<Map<String, String>> {

        @Override
        public Map<String, String> convert(String value) {
            E.checkArgument(value != null && !value.isEmpty(),
                            "HugeType can't be null or empty");
            String[] equals = value.split(",");
            Map<String, String> result = new HashMap<>();
            for (String equal : equals) {
                String[] kv = equal.split("=");
                E.checkArgument(kv.length == 2,
                                "Map arguments format should be key=value, " +
                                "but got '%s'", equal);
                result.put(kv[0], kv[1]);
            }
            return result;
        }
    }

    public static class FileNameToContentConverter
                  implements IStringConverter<String> {

        @Override
        public String convert(String value) {
            File file = FileUtils.getFile(value);
            if (!file.exists() || !file.isFile() || !file.canRead()) {
                throw new ParameterException(String.format(
                          "'%s' must be existed readable file", value));
            }
            String content;
            try {
                content = FileUtils.readFileToString(file, API.CHARSET);
            } catch (IOException e) {
                throw new ParameterException(String.format(
                          "Read file '%s' error", value), e);
            }
            return content;
        }
    }

    public static class FormatValidator implements IParameterValidator {

        private static final Set<String> FORMATS = ImmutableSet.of(
                "JSON", "TEXT"
        );

        @Override
        public void validate(String name, String value) {
            if (!FORMATS.contains(value.toUpperCase())) {
                throw new ParameterException(String.format(
                          "Invalid --format '%s', valid value is %s",
                          value, FORMATS));
            }
        }
    }

    public static class ProtocolValidator implements IParameterValidator {

        private static final Set<String> PROTOCOLS = ImmutableSet.of(
                "HTTP", "HTTPS"
        );

        @Override
        public void validate(String name, String value) {
            if (!PROTOCOLS.contains(value.toUpperCase())) {
                throw new ParameterException(String.format(
                          "Invalid --protocol '%s', valid value is %s",
                          value, PROTOCOLS));
            }
        }
    }

    public static class TaskStatusValidator implements IParameterValidator {

        @Override
        public void validate(String name, String value) {
            if (!TasksManager.TASK_STATUSES.contains(value.toUpperCase())) {
                throw new ParameterException(String.format(
                          "Invalid --status '%s', valid value is %s",
                          value, TasksManager.TASK_STATUSES));
            }
        }
    }

    public static class UrlValidator implements IParameterValidator {

        @Override
        public void validate(String name, String value) {
            String regex = "^((http)(s?)://)?"
                    // IP URL, like: 10.0.0.1
                    + "(((25[0-5])|(2[0-4]\\d)|(1\\d\\d)|([1-9]\\d)|\\d)"
                    + "(\\.((25[0-5])|(2[0-4]\\d)|(1\\d\\d)|([1-9]\\d)|\\d)){3}"
                    + "|"
                    // Or domain name
                    + "([0-9a-z_!~*'()-]+\\.)*[0-9a-z_!~*'()-]+)"
                    // Port
                    + ":([0-9]|[1-9]\\d{1,3}|[1-5]\\d{4}|6[0-5]{2}[0-3][0-5])$";
            if (!value.matches(regex)) {
                throw new ParameterException(String.format(
                          "Invalid url value of args '%s': '%s'", name, value));
            }
        }
    }

    public static class DirectoryValidator implements IParameterValidator {

        @Override
        public void validate(String name, String value) {
            File file = new File(value);
            if (!file.exists() || !file.isDirectory()) {
                throw new ParameterException(String.format(
                          "Invalid value of argument '%s': '%s'", name, value));
            }
        }
    }

    public static class PositiveValidator implements IParameterValidator {

        @Override
        public void validate(String name, String value) {
            int retry = Integer.parseInt(value);
            if (retry <= 0) {
                throw new ParameterException(
                          "Parameter " + name + " should be positive, " +
                          "but got " + value);
            }
        }
    }
}
