package com.ph.econnection.command.console;

import java.util.Collection;
import java.util.Iterator;

import org.apache.commons.cli.Options;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.OptionGroup;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.PosixParser;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.BasicParser;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.HelpFormatter;

/**
 *
 * A test of cli package
 *
 * @since CP 2.0
 **/
public class Cli {

  /**
   * Test:
     ant [options] [target [target2 [target3] ...]]
       Options: 
       -help                  print this message
       -projecthelp           print project help information
       -version               print the version information and exit
       -quiet                 be extra quiet
       -verbose               be extra verbose
       -debug                 print debugging information
       -emacs                 produce logging information without adornments
       -logfile <file>        use given file for log
       -logger <classname>    the class which is to perform logging
       -listener <classname>  add an instance of class as a project listener
       -buildfile <file>      use given buildfile
       -D<property>=<value>   use value for given property
       -find <file>           search for buildfile towards the root of the
                              filesystem and use it
     For example:
     ./yourtest.bat -buildfile connect.xml -debug -emacs -file xxx -help a1 a2 a3

   **/
  public static void main (String [] args) throws ParseException {

    //
    // boolean options
    //
    Option help   = OptionBuilder
      .withDescription( "print this message" )
      .create( "help" );
    Option projecthelp   = OptionBuilder
      .withDescription( "print project help information" )
      .create( "projecthelp" );
    Option version   = OptionBuilder
      .withDescription( "print the version information and exit" )
      .create( "version" );
    Option quiet   = OptionBuilder
      .withDescription( "be extra quiet" )
      .create( "quiet" );
    Option verbose = OptionBuilder
      .withDescription( "be extra verbose" )
      .create( "verbose" );
    Option debug = OptionBuilder
      .withDescription( "print debugging information" )
      .create( "debug" );
    Option emacs = OptionBuilder
      .withDescription( "produce logging information without adornments" )
      .create( "emacs" );

    // argument options 
    Option logfile   = OptionBuilder
      .withArgName( "file" )
      .hasArg()
      .withDescription(  "use given file for log" )
      .create( "file" );

    Option logger    = OptionBuilder
      .withArgName( "classname" )
      .hasArg()
      .withDescription( "the class which it to perform logging" )
      .create( "logger" );

    Option listener  = OptionBuilder
      .withArgName( "classname" )
      .hasArg()
      .withDescription( "add an instance of class as a project listener" )
      .create( "listener"); 
    
    Option buildfile = OptionBuilder
      .withArgName( "file" )
      .hasArg()
      .withDescription(  "use given buildfile" )
      .create("buildfile");
    
    Option find      = OptionBuilder
      .withArgName( "file" )
      .hasArg()
      .withDescription( "search for buildfile towards the root of the filesystem and use it" )
      .create( "find" );

    // java property option
    Option property  = OptionBuilder
      .withArgName( "property=value" )
      .hasArg()
      .withValueSeparator()
      .withDescription( "use value for given property" )
      .create( "D" );

    // creates the options
    Options options = new Options();
    options.addOption( help );
    options.addOption( projecthelp );
    options.addOption( version );
    options.addOption( quiet );
    options.addOption( verbose );
    options.addOption( debug );
    options.addOption( emacs );
    options.addOption( logfile );
    options.addOption( logger );
    options.addOption( listener );
    options.addOption( buildfile );
    options.addOption( find );
    options.addOption( property );

    //
    // retrieve options
    //
    System.out.println ("option definitions:");
    Collection collection = options.getOptions();
    Iterator iterator = collection.iterator();
    while (iterator.hasNext()) {
      printOption((Option)iterator.next());
    }
    
    //
    // retrieve required options
    //
    /*
    System.out.println ("required option definitions:");
    Collection reqCollection = options.getRequiredOptions();
    Iterator reqIterator = collection.iterator();
    while (reqIterator.hasNext()) {
      printOption((Option)reqIterator.next());
    }
    */
    
    //
    // parse options
    //
    //PosixParser parser = new PosixParser(); // only can handle short opt
    //BasicParser parser = new BasicParser(); // can not handle long opt with one -, i.e.: --help not not -help
    GnuParser parser = new GnuParser();       // support -h, -help and --help
    CommandLine cmd = parser.parse(options, args);

    //
    // query
    //
    if (cmd.hasOption("buildfile")) {
      String buildfileName = cmd.getOptionValue("buildfile");
      System.out.println ("XXXXXX buildfile is on = " + buildfileName);
    }

    if (cmd.hasOption("help")) {
      System.out.println ("XXXXXX help is on");
    }

    if (cmd.hasOption("emacs")) {
      System.out.println ("XXXXXX emacs is on");
    }
    
    if (cmd.hasOption("debug")) {
      System.out.println ("XXXXXX debug is on");
    }

    if (cmd.hasOption("file")) {
      String fileName = cmd.getOptionValue("file");
      System.out.println ("XXXXXX file is on = " + fileName);
    }

    //
    // another query
    //
    System.out.println ("options(after parsing):");
    Option [] opts = cmd.getOptions();
    for (int i = 0; i < opts.length; i++) {
      printOption(opts[i]);
    }

    //
    //
    //
    String [] arguments = cmd.getArgs();
    System.out.println ("arguments:");
    for (int i = 0; i < arguments.length; i++) {
      System.out.println ("\targument " + i + " = " + arguments[i]);
    }
    
    //
    // usage
    //
    (new HelpFormatter()).printHelp("ant", options);
  }


  //
  // dump an option
  //
  private static void printOption (Option option/*, Options options*/) {
    System.out.println ("\tthe argument name is \"" + option.getArgName() + "\"");
    System.out.println ("\tthe number of the argument values this option can take is \"" + option.getArgs() + "\"");
    System.out.println ("\tthe description of the option is \"" + option.getDescription() + "\"");
    System.out.println ("\tthe id is \"" + option.getId() + "\"");
    System.out.println ("\tthe long name of the option is \"" + option.getLongOpt() + "\"");
    System.out.println ("\tthe short name of the option is \"" + option.getOpt() + "\"");
    System.out.println ("\tthe type of the option is \"" + option.getType() + "\"");
    System.out.println ("\tthe value of the option is \"" + option.getValue() + "\"");
    //System.out.println ("\tthe values of the option are \"" + option.getValue(1) + "\"");
    System.out.println ("\tthe values of the option are \"" + option.getValues() + "\"");
    System.out.println ("\tthe values of the option are \"" + option.getValuesList() + "\"");
    System.out.println ("\tvalue separator is \"" + option.getValueSeparator() + "\"");
    System.out.println ("\tdoes the option requires argument: " + option.hasArg());
    System.out.println ("\tdoes the option has name for the argument value that has been set: " + option.hasArgName());
    System.out.println ("\tdoes the option takes many values: " + option.hasArgs());
    System.out.println ("\tdoes the option have long name: " + option.hasLongOpt());
    System.out.println ("\tdoes the option have optional argument: " + option.hasOptionalArg());
    System.out.println ("\tis the option requried: " + option.isRequired());
    System.out.println();

    /**
    OptionGroup optionGroup = options.getOptionGroup(option);
    if (optionGroup != null) {
      Collection names = optionGroup.getNames();
      String selected = optionGroup.getSelected();
      boolean isRequired = optionGroup.isRequired();
    }
    **/
  }

}
















