/**
 * 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.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);
    }
}
