/**
 * 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.twitter.distributedlog.tools;

import org.apache.bookkeeper.util.ReflectionUtils;
import org.apache.commons.cli.BasicParser;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;

import java.util.Map;
import java.util.TreeMap;

/**
 * A Tool Framework
 */
public abstract class Tool {

    /**
     * Interface of a command to run in a tool.
     */
    protected interface Command {
        String getName();
        String getDescription();
        int runCmd(String[] args) throws Exception;
        void printUsage();
    }

    /**
     * {@link org.apache.commons.cli.Options} based command.
     */
    protected abstract static class OptsCommand implements Command {

        /**
         * @return options used by this command.
         */
        protected abstract Options getOptions();

        /**
         * @return usage of this command.
         */
        protected String getUsage() {
            return cmdName + " [options]";
        }

        /**
         * Run given command line <i>commandLine</i>.
         *
         * @param commandLine
         *          command line to run.
         * @return return code of this command.
         * @throws Exception
         */
        protected abstract int runCmd(CommandLine commandLine) throws Exception;

        protected String cmdName;
        protected String description;

        protected OptsCommand(String name, String description) {
            this.cmdName = name;
            this.description = description;
        }

        @Override
        public String getName() {
            return cmdName;
        }

        @Override
        public String getDescription() {
            return description;
        }

        @Override
        public int runCmd(String[] args) throws Exception {
            try {
                BasicParser parser = new BasicParser();
                CommandLine cmdline = parser.parse(getOptions(), args);
                return runCmd(cmdline);
            } catch (ParseException e) {
                printUsage();
                return -1;
            }
        }

        @Override
        public void printUsage() {
            HelpFormatter helpFormatter = new HelpFormatter();
            println(cmdName + ": " + getDescription());
            helpFormatter.printHelp(getUsage(), getOptions());
        }
    }

    public class HelpCommand implements Command {

        @Override
        public String getName() {
            return "help";
        }

        @Override
        public String getDescription() {
            return "describe the usage of this tool or its sub-commands.";
        }

        @Override
        public int runCmd(String[] args) throws Exception {
            if (args.length == 0) {
                printToolUsage();
                return -1;
            }
            String cmdName = args[0];
            Command command = commands.get(cmdName);
            if (null == command) {
                System.err.println("Unknown command " + cmdName);
                printToolUsage();
                return -1;
            }
            command.printUsage();
            println("");
            return 0;
        }

        @Override
        public void printUsage() {
            println(getName() + ": " + getDescription());
            println("");
            println("usage: " + getName() + " <command>");
        }
    }

    // Commands managed by a tool
    protected final Map<String, Command> commands =
            new TreeMap<String, Command>();

    protected Tool() {
        addCommand(new HelpCommand());
    }

    /**
     * @return tool name.
     */
    protected abstract String getName();

    /**
     * Add a command in this tool.
     *
     * @param command
     *          command to run in this tool.
     */
    protected void addCommand(Command command) {
        commands.put(command.getName(), command);
    }

    /**
     * Print a message in this tool.
     *
     * @param msg
     *          message to print
     */
    protected static void println(String msg) {
        System.out.println(msg);
    }

    /**
     * print tool usage.
     */
    protected void printToolUsage() {
        println("Usage: " + getName() + " <command>");
        println("");
        int maxKeyLength = 0;
        for (String key : commands.keySet()) {
            if (key.length() > maxKeyLength) {
                maxKeyLength = key.length();
            }
        }
        maxKeyLength += 2;
        for (Map.Entry<String, Command> entry : commands.entrySet()) {
            StringBuilder spacesBuilder = new StringBuilder();
            int numSpaces = maxKeyLength - entry.getKey().length();
            for (int i = 0; i < numSpaces; i++) {
                spacesBuilder.append(" ");
            }
            println("\t"  + entry.getKey() + spacesBuilder.toString() + ": " + entry.getValue().getDescription());
        }
        println("");
    }

    public int run(String[] args) throws Exception {
        if (args.length <= 0) {
            printToolUsage();
            return -1;
        }
        String cmdName = args[0];
        Command cmd = commands.get(cmdName);
        if (null == cmd) {
            System.err.println("ERROR: Unknown command " + cmdName);
            printToolUsage();
            return -1;
        }
        // prepare new args
        String[] newArgs = new String[args.length - 1];
        System.arraycopy(args, 1, newArgs, 0, newArgs.length);
        return cmd.runCmd(newArgs);
    }

    public static void main(String args[]) {
        int rc = -1;
        if (args.length <= 0) {
            System.err.println("No tool to run.");
            System.err.println("");
            System.err.println("Usage : Tool <tool_class_name> <options>");
            System.exit(-1);
        }
        String toolClass = args[0];
        try {
            Tool tool = ReflectionUtils.newInstance(toolClass, Tool.class);
            String[] newArgs = new String[args.length - 1];
            System.arraycopy(args, 1, newArgs, 0, newArgs.length);
            rc = tool.run(newArgs);
        } catch (Throwable t) {
            System.err.println("Fail to run tool " + toolClass + " : ");
            t.printStackTrace();
        }
        System.exit(rc);
    }
}
