/*
 * Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved.
 *
 * The contents of this file are subject to the CCM Public
 * License (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.redhat.com/licenses/ccmpl.html.
 *
 * Software distributed under the License is distributed on an
 * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
 * or implied. See the License for the specific language
 * governing rights and limitations under the License.
 *
 */
package com.arsdigita.packaging;

import com.arsdigita.util.*;
import java.util.*;
import java.io.*;

import org.apache.commons.cli.*;

import org.apache.log4j.Logger;

/**
 * Implements the ccm command line tool.
 *
 * @author Justin Ross &lt;jross@redhat.com&gt;
 * @version $Id: //core-platform/dev/src/com/arsdigita/packaging/MasterTool.java#10 $
 */
public class MasterTool {
    public static final String versionId =
        "$Id: //core-platform/dev/src/com/arsdigita/packaging/MasterTool.java#10 $" +
        "$Author: dennis $" +
        "$DateTime: 2004/04/07 16:07:11 $";

    private static final Logger s_log = Logger.getLogger(MasterTool.class);

    private static void usage(Commands cmds, PrintStream out) {
        out.println("usage: ccm [OPTIONS | COMMAND]");
        out.println();
        out.println("Options:");
        out.println("  --help     Display help");
        out.println("  --usage    Print this message");
        out.println();
        out.println("Commands:");
        out.print(cmds.getCommands());
    }

    /**
     * Entry point for the the ccm command line tool.
     *
     * @param args the command line arguments
     **/

    public static final void main(final String[] args) {
        final PrintStream out = System.out;
        final PrintStream err = System.err;

        Commands cmds = new Commands();
        Command help = new Help();
        Command usage = new Usage();
        cmds.add(help, true);
        cmds.add(usage, true);
        cmds.add(new Load());
        cmds.add(new Unload(), true);
        cmds.add(new Upgrade());
        cmds.add(new Get());
        cmds.add(new Set());
        cmds.add(new Clear());
        cmds.add(new Status());
        cmds.add(new Which());

        if (args.length == 0) {
            usage(cmds, err);
            System.exit(1);
        }

        String name = args[0];
        Command cmd = cmds.get(name);

        if (cmd == null) {
            err.println("no such command: " + name);
            System.exit(1);
        }

        String[] command = new String[args.length - 1];
        System.arraycopy(args, 1, command, 0, command.length);

        boolean result = cmd.run(command);
        if (cmd == help || cmd == usage) {
            usage(cmds, out);
        }
        if (result) {
            System.exit(0);
        } else {
            System.exit(1);
        }
    }

    private static final class Commands {

        private List m_commands = new ArrayList();
        private Map m_map = new HashMap();
        private int m_maxName = 0;
        private HashSet m_hidden = new HashSet();

        public Commands() {}

        public void add(Command command, boolean hidden) {
            m_commands.add(command);
            String name = command.getName();
            m_map.put(name, command);
            int length = name.length();
            if (length > m_maxName) {
                m_maxName = length;
            }
            if (hidden) {
                m_hidden.add(command);
            }
        }

        public void add(Command command) {
            add(command, false);
        }

        public Command get(String name) {
            return (Command) m_map.get(name);
        }

        public String getCommands() {
            StringBuffer result = new StringBuffer();
            for (Iterator it = m_commands.iterator(); it.hasNext(); ) {
                Command cmd = (Command) it.next();
                if (m_hidden.contains(cmd)) { continue; }
                String line = "  " + cmd.getName();
                result.append(line);
                for (int i = 0; i < m_maxName + 6 - line.length(); i++) {
                    result.append(" ");
                }
                result.append(cmd.getSummary() + "\n");
            }

            return result.toString();
        }

    }

}
