package com.postgres.util.cmd;

import java.io.*;
import java.util.*;

public final class CmdLine {
    private static  boolean DEBUG = false;
    private static CmdLine _instance = null;
    private StringBuffer[] inputArgs;
    private Vector vArgs = new Vector();
    private Hashtable arguments;

    private void add(CmdProcessor processor, GenericCmd argCmd) {
        processor.add(argCmd);
        vArgs.addElement(argCmd);
    }

    private void checkArgs() throws Exception {
        Enumeration allArgs  = vArgs.elements();
        boolean bAnythingSet = false;
        while (bAnythingSet == false && allArgs.hasMoreElements()) {
            GenericCmd thisArg = (GenericCmd)allArgs.nextElement();
            if (thisArg.wasSet()) bAnythingSet = true;
        } // -- end while
        if (!bAnythingSet) {
            //System.out.println("The following arguments are reqiured:");
            //for(int i=0;i<params.length;i++)
            //   System.out.println("  "+params[i]);
            throw new Exception("No valid command-line arguments found");
        }
    }

    private Object getArg(String key) throws Exception {
        if (DEBUG) System.out.println("CmdLine::getArg BEGIN key=" + key);
        GenericCmd gc = (GenericCmd)arguments.get(key);
        if (gc != null) return gc.get();
        return null;
    }

    public boolean getFlag(String key) throws Exception {
        Boolean flag = (Boolean)getArg(key);
        if (flag != null) return flag.booleanValue();
        return false;
    }

    public String getParam(String key) throws Exception {
        if (DEBUG) System.out.println("CmdLine::getParam BEGIN key=" + key);
        StringBuffer sb = (StringBuffer)getArg(key);
        if (sb != null) return sb.toString();
        return null;
    }

    static public CmdLine instance(String[] args, String[] params)
        throws Exception {
            if (null == _instance) {
                _instance = new CmdLine(args, params);
            }
            return _instance;
    }

    static public CmdLine instance(String[] args, String[] params, String[] flags)
        throws Exception {
            if (null == _instance) {
                _instance = new CmdLine(args, params, flags);
            }
            return _instance;
    }

    public static String getUsage(String appName, String[] params, String[] flags){
        String usage = "USAGE: \n" + appName;

        if (params != null && params.length > 0) {
            for (int i=0; i<params.length; i++) {
            	usage += " [" + params[i] + " <"+ params[i] + "_value>]";
            }
        }

	    if (flags != null && flags.length > 0) {
            for (int i=0; i<flags.length; i++) {
             usage += " [" + flags[i] + "]";
            }
        }
        return  usage;
    }

    private CmdLine(String[] args, String[] params, String[] flags)
        throws Exception {
            if (DEBUG) System.out.println("CmdLine:: BEGIN CmdLine(String[] args, String[] params, String[] flags)");
            //this.params = params;
            //this.flags = flags;
            inputArgs = new StringBuffer[params.length];
            for (int i = 0; i < params.length; i++) {
                inputArgs[i] = new StringBuffer("");
            }
            arguments = processArgs(args, params, flags);
    }

    private CmdLine(String[] args, String[] params) throws Exception {
        //this.params = params;
        //this.flags = flags;
        inputArgs = new StringBuffer[params.length];
        for (int i = 0; i < params.length; i++) {
            inputArgs[i] = new StringBuffer("");
        }
        arguments = processArgs(args, params, null);
    }

    public static void main(String args[]) {
        int iReturn = 0;
        String labels[] =  {"-host", "-port", "-message", "-threads"};
        String flags[] =  {"-debug", "-verbose"};
        //CmdLine cline = new CmdLine(labels, flags);
        try {
            CmdLine cline = CmdLine.instance(args, labels, flags);
            String host = cline.getParam("-host");
            String port = cline.getParam("-port");
            String message = cline.getParam("-message");
            String threads = cline.getParam("-threads");
            boolean debug = cline.getFlag("-debug");
            boolean verbose = cline.getFlag("-verbose");
            System.out.println("host=" + host);
            System.out.println("port=" + port);
            System.out.println("message=" + message);
            System.out.println("threads=" + threads);
            System.out.println("debug=" + debug);
            System.out.println("verbose=" + verbose);
        } catch (Exception e) {
            e.printStackTrace();
            iReturn = 1;
        }
        System.exit(iReturn);
    }

    private Hashtable processArgs(String args[], String[] params, String[] flags)
        throws Exception {
            CmdProcessor processor = new CmdProcessor(args);

            if (params != null) {
                for (int i = 0; i < params.length; i++) {
                    if (DEBUG) System.out.println("CmdLine::processArgs: "
                    +"; inputArgs["+i+"]="+inputArgs[i]
                    +"; params["+i+"]="+params[i]);
                    add(processor,
                        new ArgCmd(params[i],  inputArgs[i]));
                }
            }
            if (flags != null) {
                FlagCmd[] flagArg = new FlagCmd[flags.length];
                for (int i = 0; i < flags.length; i++) {
                    flagArg[i] = new FlagCmd(flags[i], true);
                    add(processor, flagArg[i]);			
                }
            }
            Hashtable arguments = processor.process();
            checkArgs();
            return arguments;
    }
}
