
/**
 * Opts.java
 *
 * Copyright (c) 2006 Ying-Chun Liu (PaulLiu)
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions are 
 * met:
 *
 *  1. Redistributions of source code must retain the copyright notice,
 *     this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in
 *     the documentation and/or other materials provided with the
 *     distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND
 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

package org.jlhafrontend;
import java.util.logging.*;
import java.util.regex.*;

/**
 * This class parses LHA commands
 *
 */

public class Opts {

    /**
     * INVALID COMMAND
     */
    public static int CMD_INVALID=0;
    /**
     * ADD COMMAND
     */
    public static int CMD_ADD=1;
    /**
     * EXTRACT COMMAND
     */
    public static int CMD_EXTRACT=2;
    /**
     * LIST COMMAND 
     */
    public static int CMD_LIST=3;
    /**
     * VERBOSE LIST COMMAND
     */
    public static int CMD_VERBOSELIST=4;
    /**
     * UPDATE COMMAND
     */
    public static int CMD_UPDATE=5;
    /**
     * DELETE COMMAND
     */
    public static int CMD_DELETE=6;
    /**
     * RECONSTRUCT COMMAND
     */
    public static int CMD_RECONSTRUCT=7;
    /**
     * PRINT STDOUT COMMAND
     */
    public static int CMD_PRINTSTDOUT=8;
    /**
     * TEST COMMAND
     */
    public static int CMD_TEST=9;

    /**
     * archive filename
     */
    String archive_filename=null;
    /**
     * Debug logger
     */
    Logger mylogger=null;


    int cmd=Opts.CMD_INVALID;
    int quiet=0;
    boolean verbose=false;
    boolean notExecute=false;
    boolean force=false;
    int compressionMethod=0;
    String specifyExtractDirectory=null;
    boolean deleteFiles=false;
    boolean ignorePath=false;
    boolean fileNotCompress=false;
    boolean genericFormat=false;
    boolean textMode=false;
    boolean eucMode=false;
    int headerLevel=-1;


    /**
     * get command
     *
     * @return command code
     */
    public int getCmd() {
	return cmd;
    }

    /**
     * get quiet level 
     *
     * @return quiet level
     */
    public int getQuiet() {
	return quiet;
    }

    /**
     * set quiet level 
     *
     * @param quiet quiet level
     */
    public void setQuiet(int quiet) {
	this.quiet=quiet;
    }

    /**
     * get verbose flag 
     * @return verbose flag
     */
    public boolean getVerbose() {
	return verbose;
    }

    /**
     * get not execute flag
     * @return not execute flag
     */
    public boolean getNotExecute() {
	return notExecute;
    }

    /**
     * get force flag
     * @return force flag
     */
    public boolean getForce() {
        return force;
    }

    /**
     * get compression method
     * @return method
     */
    public int getCompressionMethod() {
	return compressionMethod;
    }

    /**
     * get extract directory pathname
     * @return extract directory pathname
     */
    public String getSpecifyExtractDirectory() {
	return (specifyExtractDirectory);
    }

    /**
     * get delete files flag
     * @return the flag
     */
    public boolean getDeleteFiles() {
	return deleteFiles;
    }

    /**
     * get ignore path flag
     * @return the flag
     */
    public boolean getIgnorePath() {
	return ignorePath;
    }
    
    /**
     * get not compress flag
     * @return the flag
     */
    public boolean getFileNotCompress() {
	return fileNotCompress;
    }

    /**
     * get generic format flag
     * @return the flag
     */
    public boolean getGenericFormat() {
	return genericFormat;
    }

    /**
     * get header level
     * @return header level
     */
    public int getHeaderLevel() {
	return headerLevel;
    }

    /**
     * get text mode flag
     * @return text mode flag
     */
    public boolean getTextMode() {
	return textMode;
    }

    /**
     * get EUC conversion mode flag
     * @return euc mode flag
     */
    public boolean getEUCMode() {
	return eucMode;
    }

    /**
     * constructor
     */
    public Opts() {
	mylogger = Logger.getLogger("org.jlhafrontend");
    }

    /**
     * constructor, with given command-line options
     * @param optstr command-line opts
     */
    public Opts(String optstr) {
	this();
	setOpts(optstr);
    }

    /**
     * set the command-line opts to handle
     * This method parses the user-input options. Results can be retrived by
     * other getX methods.
     * @param optstr command-line opts
     * @return valid opt or not
     */
    public boolean setOpts (String optstr) {
	int i;
	boolean ret;
	String regex1 = "[-]{0,1}(a|x|e|l|v|u|d|m|c|p|t)(?:(q\\d*)|(v)|(n)|(f)|(o\\d*)|(d)|(i)|(z)|(g)|(0|1|2|3)|(e)|(y)|(t))*(w[=].*){0,1}";
	Pattern pat_p;
	Matcher mat_p;
	String mat_str;

	pat_p = Pattern.compile(regex1);
	mat_p = pat_p.matcher(optstr);
	ret = mat_p.matches();

	if (ret) {
	    for (i=0 ; i<=mat_p.groupCount() ; i++) {
		mat_str = mat_p.group(i);
		if (mat_str==null) continue;
		mylogger.log(Level.FINEST,Integer.toString(i)+": "+mat_str);
		switch (i) {
		case 1:
		    if (mat_str.compareTo("a")==0) {
			cmd = CMD_ADD;
		    } else if (mat_str.compareTo("e")==0) {
			cmd = CMD_EXTRACT;
		    } else if (mat_str.compareTo("x")==0) {
			cmd = CMD_EXTRACT;
		    } else if (mat_str.compareTo("l")==0) {
			cmd = CMD_LIST;
		    } else if (mat_str.compareTo("v")==0) {
			cmd = CMD_VERBOSELIST;
		    } else if (mat_str.compareTo("u")==0) {
			cmd = CMD_UPDATE;
		    } else if (mat_str.compareTo("d")==0) {
			cmd = CMD_DELETE;
		    } else if (mat_str.compareTo("c")==0) {
			cmd = CMD_RECONSTRUCT;
		    } else if (mat_str.compareTo("p")==0) {
			cmd = CMD_PRINTSTDOUT;
		    } else if (mat_str.compareTo("t")==0) {
			cmd = CMD_TEST;
		    } else if (mat_str.compareTo("m")==0) {
		        cmd = CMD_ADD;
		        deleteFiles=true;
                    }
		    break;
		case 2:
		    try {
			if (mat_str.charAt(0) == 'q') {
			    if (mat_str.length()>1) {
				quiet=Integer.parseInt(mat_str.substring(1));
			    } else {
				quiet++;
			    }
			}
		    } catch (Exception e) {
			
		    }
		    break;
		case 3:
		    if (mat_str.compareTo("v")==0) {
			verbose = true;
		    }
		    break;
		case 4:
		    if (mat_str.compareTo("n")==0) {
			notExecute=true;
		    }
		    break;
                case 5:
                    if (mat_str.compareTo("f")==0) {
                        force = true;
                    }
                    break;
		case 6:
		    try {
			if (mat_str.charAt(0) == 'o') {
			    if (mat_str.length()>1) {
				compressionMethod=Integer.parseInt(mat_str.substring(1));
			    }
			}
		    } catch (Exception e) {
			
		    }
		    break;
		case 7:
		    if (mat_str.compareTo("d")==0) {
			deleteFiles=true;
		    }
		    break;
		case 8:
		    if (mat_str.compareTo("i")==0) {
			ignorePath=true;
		    }
		    break;
		case 9:
		    if (mat_str.compareTo("z")==0) {
			fileNotCompress=true;
		    }
		    break;
		case 10:
		    if (mat_str.compareTo("g")==0) {
			genericFormat=true;
		    }
		    break;
		case 11:
		    if (mat_str.compareTo("0")==0) {
			headerLevel=0;
		    } else if (mat_str.compareTo("1")==0) {
			headerLevel=1;
		    } else if (mat_str.compareTo("2")==0) {
			headerLevel=2;
		    } 
		    /* headerLevel = 3 is not supported by the non-free lha,
		       thus we disable it now */
		    /*else if (mat_str.compareTo("3")==0) {
			headerLevel=3;
		    }*/
		    break;
		case 12:
		    if (mat_str.compareTo("e")==0) {
			eucMode = true;
		    }
		    break;
		case 13:
		    if (mat_str.compareTo("y")==0) {
			try {
			    java.util.Locale.setDefault(java.util.Locale.JAPAN); /* FIXME: ugly, but work */
			} catch (Exception e) {
			    mylogger.warning("Set locale to Japan error: "+e.toString());
			}
		    }
		    break;
		case 14:
		    if (mat_str.compareTo("t")==0) {
			textMode = true;
		    }
		    break;
		case 15:
		    try {
			if (mat_str.charAt(0) == 'w' && mat_str.charAt(1)== '=') {
			    if (mat_str.length()>2) {
				specifyExtractDirectory=mat_str.substring(2);
			    }
			}
		    } catch (Exception e) {
			
		    }
		    break;
		default:
		    break;
		}
	    }
	} else {
	    mylogger.log(Level.INFO,"Not match");
	}

	return ret;
    }

    /**
     *
     * testing function
     */
    public static void main (String[] args) {
	Opts o1 = new Opts();
	Logger.getLogger("org.jlhafrontend").setLevel(Level.ALL);
	Logger.getLogger("org.jlhafrontend").addHandler(new ConsoleHandler());
	o1.setOpts(args[0]);
    }

}
