// test class for CmdLineParser
import dsl99lux.CmdLineParser ;
import dsl99lux.TextListParser ;
import dsl99lux.luxException ;
import dsl99lux.cmdException ;
import dsl99lux.cmdUnknownMethod ;
import java.util.StringTokenizer ;
import java.lang.Integer ;
 /**
 * Copyright (c) 1998-1999  Lucent Technologies, Inc.
 *
 * This software is copyrighted by Lucent Technologies Inc.
 * The following terms apply to all files associated with the
 * software unless explicitly disclaimed in individual files.
 * 
 * The authors hereby grant permission to use and copy this
 * software and its documentation for educational, research
 * and reference purposes provided that existing copyright
 * notices are retained in all copies and that this notice is
 * included verbatim in any distributions. No written agreement,
 * license, or royalty fee is required for such authorized uses.
 * Modifications to this software may not be made without permission.
 * 
 * IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY
 * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
 * DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION,
 * OR ANY DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 * THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE
 * IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
 * NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
 * OR MODIFICATIONS.
 * 
 * GOVERNMENT USE:  If you are acquiring this software on behalf of the
 * U.S. Government, the Government shall have only "Restricted Rights"
 * in the software and related documentation as defined in the Federal
 * Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you
 * are acquiring the software on behalf of the Department of Defense,
 * the software shall be classified as "Commercial Computer Software"
 * and the Government shall have only "Restricted Rights" as defined
 * in Clause 252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing,
 * the authors grant the U.S. Government and other acting in its behalf
 * permission to use and distribute the software in accordance with the
 * terms specified in this license.

 @author Dale Parson
 	 Bell Labs Innovations for Lucent Technologies
	 dparson@lucent.com
 */

public class testCmdLineParser {

    // *********************************************************
    // Here are the public methods to test:

    public int command_sumint(int a, int b)  {
	int result = a + b ;
	System.out.println("sumint " + a + " + " + b + " = " + result);
	return result;
    }

    public String command_tstring(String a, String b, String[] rest) {
	String result ;
	if (rest == null) {
	    System.out.println("tstring got 2 strings");
	    result = a + ":" + b ;
	} else {
	    int numstr = 2 + rest.length ;
	    System.out.println("tstring got " + numstr + " strings");
	    result = a + ":" + b ;
	    for (int i = 0 ; i < rest.length ; i++) {
		result += (":" + rest[i]) ;
	    }
	}
	return(result);
    }

    // Sumsome has a usage string and an optional second parameter,
    // note use of static initialization block for the latter.
    public static final String usage_sumsome = "sumsome int1 [ int2 ] int3" ;
    public static final int optional_sumsome_3[] = new int[1] ;
    static {
	optional_sumsome_3[0] = 1 ;
    }
    public Integer command_sumsome(int i1, Integer i2, int i3) {
	int result ;
	if (i2 == null) {
	    System.out.println("sumsome got 2 ints");
	    result = i1 + i3 ;
	} else {
	    System.out.println("sumsome got 3 ints");
	    result = i1 + i3 + i2.intValue();
	}
	return new Integer(result) ;
    }

    // sum3 is identical to the integer version of sumsome,
    // but the second argument is never optional (no optional_)
    public static final String usage_sum3 = "sum3 int1 int2 int3" ;
    public Integer command_sum3(int i1, Integer i2, int i3) {
	int result ;
	if (i2 == null) {
	    System.out.println("sum3 got 2 ints");
	    result = i1 + i3 ;
	} else {
	    System.out.println("sum3 got 3 ints");
	    result = i1 + i3 + i2.intValue();
	}
	return new Integer(result) ;
    }

    // oload overloads a 2-string and a 3-float method
    public static final String usage_oload =
        "oload string1 string2 | oload float1 float2 float3" ;
    public String command_oload(String a, String b) {
	return(a + ":" + b);
    }
    public float command_oload(float a, float b, float c) {
	return(a + b + c);
    }

    // Following attempt to test all possible type matches,
    // one at a time, with a pair of values.
    public boolean command_or2(boolean a, boolean b) {
	return(a || b);
    }
    public Boolean command_and2(Boolean a, Boolean b) {
	return(new Boolean(a.booleanValue() && b.booleanValue()));
    }
    public char command_charlt(char a, char b) {
	return((a < b) ? a : b);
    }
    public Character command_chargt(Character a, Character b) {
	char A = a.charValue();
	char B = b.charValue();
	return(new Character((A > B) ? A : B));
    }
    public byte command_addbyte(byte a, byte b) {
	return((byte)(a + b));
    }
    public Byte command_addByte(Byte a, Byte b) {
	return(new Byte((byte)(a.byteValue() + b.byteValue())));
    }
    public short command_addshort(short a, short b) {
	return((short)(a + b));
    }
    public Short command_addShort(Short a, Short b) {
	return(new Short((short)(a.shortValue() + b.shortValue())));
    }
    public int command_addint(int a, int b) {
	return(a + b);
    }
    public Integer command_addInteger(Integer a, Integer b) {
	return(new Integer(a.intValue() + b.intValue()));
    }
    public long command_addlong(long a, long b) {
	return(a + b);
    }
    public Long command_addLong(Long a, Long b) {
	return(new Long(a.longValue() + b.longValue()));
    }
    public float command_addfloat(float a, float b) {
	return(a + b);
    }
    public Float command_addFloat(Float a, Float b) {
	return(new Float(a.floatValue() + b.floatValue()));
    }
    public double command_adddouble(double a, double b) {
	return(a + b);
    }
    public Double command_addDouble(Double a, Double b) {
	return(new Double(a.doubleValue() + b.doubleValue()));
    }
    public static final int optional_mrglist_2[] = new int[1] ;
    static {
	// if the String[] is missing return empty string
	optional_mrglist_2[0] = 1 ;
    }
    public String command_mrglist(TextListParser t, String[] l) {
	if (l == null) {
	    return("EMPTY!");
	}
	return(t.MergeList(l));
    }
    public String command_sublist(String a, String[] b, String c) {
	String res = a ;
	for (int i = 0 ; i < b.length ; i++) {
	    res += ";" + b[i];
	}
	return(res + ":" + c);
    }
    // create a custom type with a valueOf operation
    public static class valtype {
	private String val ;
	private valtype(String s) {
	    val = s ;
	}
	public static valtype valueOf(String init) {
	    return(new valtype(init));
	}
	public static valtype valueOf(Object init) {
	    return(new valtype(init.toString()));
	}
	public String getValue() {
	    return(val);
	}
    }
    public String command_catobjs(valtype a, valtype b) {
	return(a.getValue() + "::" + b.getValue());
    }
    // create a custom type with a list-consuming valueOf operation
    public static class aggtype {
	private String val ;
	private aggtype(String s) {
	    val = s ;
	}
	public static aggtype valueOf(String [] cline, 
    	    CmdLineParser.Counter oset) {
	    // constructor that eats >= 0 String
	    String init = "" ;
	    int consumed = 0 ;
	    int start = oset.getInt();
	    for (; start < (cline.length-1) ; start++) {
		init += "|" + cline[start] + "|" ;
		consumed++ ;
	    }
	    aggtype retval = null ;
	    if (consumed > 0) {
		retval = new aggtype(init);
		oset.setInt(consumed);
	    } else {
		oset.setInt(0);
	    }
	    return(retval);
	}
	public String getValue() {
	    return(val);
	}
    }
    public String command_allbut1(aggtype a, String[] other) {
	System.out.println("allbut1 final array gets " + other.length);
	String sres = "" ;
	for (int i = 0 ; i < other.length ; i++) {
	    sres += other[i] + "|" ;
	}
	return(a.getValue() + ":::" + sres);
    }
    public static class cmdexc extends luxException {
	// helper class to test an exception-throw from a command
	public cmdexc(String msg) {
	    super(msg);
	}
    }
    public void command_excvoid() throws cmdexc {
	throw new cmdexc("dummy exception");
    }
    public void command_voidcmd() {
	System.out.println("inside voidcmd, no parms or return");
    }
    // *********************************************************

    // We need a SplitList/MergeList class, we'll do it
    // by simply splitting over spaces.
    public static class testTextListParser implements TextListParser {
	public boolean isList(String structuredString) {
	    return(structuredString != null
		    && ! structuredString.equals(""));
	}

	public int length(String structuredString) {
	    int retval ;
	    if (! isList(structuredString)) {
		retval = -1 ;
	    } else {
		// break up string on white space
		StringTokenizer scan = new StringTokenizer(structuredString);
		retval = scan.countTokens();
	    }
	    return(retval);
	}

	public String[] SplitList(String structuredString) {
	    StringTokenizer scan = new StringTokenizer(structuredString);
	    String[] pieces = new String[scan.countTokens()];
	    for (int i = 0 ; i < pieces.length ; i++) {
		pieces[i] = scan.nextToken();
	    }
	    return(pieces);
	}
	public String MergeList(String slist[]) {
	    String result = "";
	    for (int i = 0 ; i < slist.length ; i++) {
		result = result + slist[i] ;
		if (i < (slist.length-1)) {
		    result = result + " " ;
		}
	    }
	    return(result);
	}
    }


    // Here is the test driver.
    public static void main(String[] args) {
	if (args.length == 1 && args[0].equals("AUTO")) {
	    // subtest recursively calls back here with a test set
	    subtest();
	} else {
	    String line = "" ;
	    for (int i = 0 ; i < args.length ; i++) {
		line = line + args[i];
		if (i < (args.length-1)) {
		    line = line + "|";
		}
	    }
	    System.out.println("TEST: " + line);
	    testTextListParser lister = new testTextListParser();
	    testCmdLineParser targetobj = new testCmdLineParser() ;
	    CmdLineParser parser = new CmdLineParser(targetobj);
	    if (args.length == 0) {
		// On no command, dump list of commands.
		CmdLineParser.method_N[] methods = parser.getMethodNames();
		for (int i = 0 ; i < methods.length ; i++) {
		    System.out.println("found method " + methods[i].getName()
			+ ", arity = " + methods[i].getArity());
		}
		System.out.println("Number methods = " +
		    parser.getMethodCount());
	    } else {
		// args array constitutes the command line
		if (parser.isCommand(args[0])) {
		    System.out.println(args[0] + " is a command");
		} else {
		    System.out.println(args[0] + " is NOT a command!");
	        }
	        try {
		    String result = parser.parse(args,lister);
		    System.out.println("result = " + result);
	        } catch (cmdException e) {
		    System.out.println("cmdException: " + e.getMessage());
	        } catch (cmdUnknownMethod e) {
		    System.out.println("cmdUnknownMethod: " + e.getMessage());
	        }
	    }
	}
    }
	private static String [][] tests = {
	    { },
	    { "sumint" },
	    { "sumint", "1" },
	    { "sumint", "1", "2" },
	    { "sumint", "1a", "2" },
	    { "sumint", "1", "2c" },
	    { "sumint", "1", "2", "3" },
	    { "tstring" },
	    { "tstring", "one" },
	    { "tstring", "one", "two" },
	    { "tstring", "one", "two", "three" },
	    { "tstring", "one", "two", "three", "another", "string", "final" },
	    { "tstring", "one", "two", "a four part list" },
	    { "tstring", "one", "two", "a four part list", "final" },
	    { "sumsome" },
	    { "sumsome", "1" },
	    { "sumsome", "1", "2" },
	    { "sumsome", "1", "2", "3" },
	    { "sumsome", "1", "2", "3", "4" },
	    { "sum3", "1" },
	    { "sum3", "1", "2" },
	    { "sum3", "1", "2", "3" },
	    { "sum3", "1", "2", "3", "4" },
	    { "sumsome", "1", "cat", "3" },
	    { "sum3", "1", "2", "dog" },
	    { "oload" },
	    { "oload", "one string", "two string" },
	    { "oload", "one string" },
	    { "oload", "1.2", "1.3", "1.4" },
	    { "oload", ".2", "1.", "1" },
	    { "oload", ".2", "cat", "1" },
	    { "oload", ".2", "1.", "1", "5.6" },
	    { "or2", "true", "false" },
	    { "or2", "FALSE", "TRUE" },
	    { "or2", "", "false" },
	    { "or2", "TRUE", "TRUE" },
	    { "or2", "1", "2" },
	    { "and2", "true", "false" },
	    { "and2", "FALSE", "TRUE" },
	    { "and2", "", "false" },
	    { "and2", "TRUE", "TRUE" },
	    { "and2", "1", "2" },
	    { "charlt", "true", "false" },
	    { "charlt", "FALSE", "TRUE" },
	    { "charlt", "", "false" },
	    { "charlt", "TRUE", "TRUE" },
	    { "charlt", "1", "2" },
	    { "chargt", "true", "false" },
	    { "chargt", "FALSE", "TRUE" },
	    { "chargt", "", "false" },
	    { "chargt", "TRUE", "TRUE" },
	    { "chargt", "1", "2" },
	    { "addbyte", "1", "-10" },
	    { "addbyte", "10", "-1" },
	    { "addbyte", "", "0" },
	    { "addbyte", "0", "TRUE" },
	    { "addByte", "1", "-10" },
	    { "addByte", "10", "-1" },
	    { "addByte", "", "0" },
	    { "addByte", "0", "TRUE" },
	    { "addshort", "1", "-10" },
	    { "addshort", "10", "-1" },
	    { "addshort", "", "0" },
	    { "addshort", "0", "TRUE" },
	    { "addShort", "1", "-10" },
	    { "addShort", "10", "-1" },
	    { "addShort", "", "0" },
	    { "addShort", "0", "TRUE" },
	    { "addint", "1", "-10" },
	    { "addint", "10", "-1" },
	    { "addint", "", "0" },
	    { "addint", "0", "TRUE" },
	    { "addInteger", "1", "-10" },
	    { "addInteger", "10", "-1" },
	    { "addInteger", "", "0" },
	    { "addInteger", "0", "TRUE" },
	    { "addlong", "1", "-10" },
	    { "addlong", "10", "-1" },
	    { "addlong", "", "0" },
	    { "addlong", "0", "TRUE" },
	    { "addLong", "1", "-10" },
	    { "addLong", "10", "-1" },
	    { "addLong", "", "0" },
	    { "addLong", "0", "TRUE" },
	    { "addfloat", "1.2", "-10.4" },
	    { "addfloat", "10.4", "-1.2" },
	    { "addfloat", "", "0" },
	    { "addfloat", "0", "TRUE" },
	    { "addFloat", "1.2", "-10.4" },
	    { "addFloat", "10.4", "-1.2" },
	    { "addFloat", "", "0" },
	    { "addFloat", "0", "TRUE" },
	    { "adddouble", "1.2", "-10.4" },
	    { "adddouble", "10.4", "-1.2" },
	    { "adddouble", "", "0" },
	    { "adddouble", "0", "TRUE" },
	    { "addDouble", "1.2", "-10.4" },
	    { "addDouble", "10.4", "-1.2" },
	    { "addDouble", "", "0" },
	    { "addDouble", "0", "TRUE" },
	    { "mrglist" },
	    { "mrglist", "one string" },
	    { "mrglist", "one string" , "another" },
	    { "mrglist", "one string" , "another" , "yet another"},
	    { "mrglist", "one string" , "another" , "yet another", "stop"},
	    { "sublist", "a", "nested sub list", "z" },
	    { "catobjs", "object1", "object2" },
	    { "allbut1", "object1", "object2" , "object3", "object4" },
	    { "allbut1", "object1", "object2" , "object3" },
	    { "allbut1", "object1", "object2" },
	    { "allbut1", "object1" },
	    { "allbut1" },
	    { "voidcmd" },
	    { "excvoid" },
	    { "nogood" }
	} ;
    private static void subtest() {
	for (int i = 0 ; i < tests.length ; i++) {
	    main(tests[i]);
	}
    }
}

