/*
 * Copyright 2002,2004 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.commons.jelly.util;

import java.io.File;
import java.io.FileWriter;
import java.net.URL;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.Parser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.jelly.Jelly;
import org.apache.commons.jelly.JellyContext;
import org.apache.commons.jelly.JellyException;
import org.apache.commons.jelly.Script;
import org.apache.commons.jelly.XMLOutput;

/**
 * Utility class to parse command line options using CLI.
 * Using a separate class allows us to run Jelly without
 * CLI in the classpath when the command line interface
 * is not in use.
 *
 * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
 * @author Morgan Delagrange
 * @version $Revision: 1.10 $
 */
public class CommandLineParser {

    protected static CommandLineParser _instance = new CommandLineParser();
    
    private Options cmdLineOptions = null;

    public static CommandLineParser getInstance() {
        return _instance;
    }

    /**
     * Parse out the command line options and configure
     * the give Jelly instance.
     *
     * @param args   options from the command line
     * @exception JellyException
     *                   if the command line could not be parsed
     */
    public void invokeCommandLineJelly(String[] args) throws JellyException {
        CommandLine cmdLine = null;
        try {
            cmdLine = parseCommandLineOptions(args);
        } catch (ParseException e) {
            throw new JellyException(e);
        }
        
        // check for -h or -v
        if (cmdLine.hasOption("h")) {
            new HelpFormatter().printHelp("jelly [scriptFile] [-script scriptFile] [-o outputFile] [-Dsysprop=syspropval] [-awt]",
                cmdLineOptions);
            System.exit(1);
        }
        if (cmdLine.hasOption("v")) {
            System.err.println("Jelly " + Jelly.getJellyVersion());
            System.err.println(" compiled: " + Jelly.getJellyBuildDate());
            System.err.println("");
            System.exit(1);
        }

        // get the -script option. If there isn't one then use args[0]
        String scriptFile = null;
        if (cmdLine.hasOption("script")) {
            scriptFile = cmdLine.getOptionValue("script");
        } else {
            scriptFile = args[0];
        }
        
        // check the -awt option.
        boolean runInSwingThread = cmdLine.hasOption("awt") || cmdLine.hasOption("swing");

        //
        // Use classloader to find file
        //
        URL url = ClassLoaderUtils.getClassLoader(getClass()).getResource(scriptFile);
        // check if the script file exists
        if (url == null && !(new File(scriptFile)).exists()) {
            throw new JellyException("Script file " + scriptFile + " not found");
        }

        try {
            // extract the -o option for the output file to use
            final XMLOutput output = cmdLine.hasOption("o") ?
                    XMLOutput.createXMLOutput(new FileWriter(cmdLine.getOptionValue("o"))) :
                    XMLOutput.createXMLOutput(System.out);

            Jelly jelly = new Jelly();
            jelly.setScript(scriptFile);

            final Script script = jelly.compileScript();

            // add the system properties and the command line arguments
            final JellyContext context = jelly.getJellyContext();
            context.setVariable("args", args);
            context.setVariable("commandLine", cmdLine);
            if (runInSwingThread) {
                javax.swing.SwingUtilities.invokeAndWait(new Runnable() { public void run() {
                    try {
                        script.run(context, output);
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
            } } ); } else {
                script.run(context, output);
            }

            // now lets wait for all threads to close
            Runtime.getRuntime().addShutdownHook(new Thread() {
                    public void run() {
                        try {
                            output.close();
                        }
                        catch (Exception e) {
                            // ignore errors
                        }
                    }
                }
            );

        } catch (Exception e) {
            throw new JellyException(e);
        }

    }

    /**
     * Parse the command line using CLI. -o and -script are reserved for Jelly.
     * -Dsysprop=sysval is support on the command line as well.
     */
    public CommandLine parseCommandLineOptions(String[] args) throws ParseException {
        // create the expected options
        cmdLineOptions = new Options();
        cmdLineOptions.addOption("o", true, "Output file");
        cmdLineOptions.addOption("script", true, "Jelly script to run");
        cmdLineOptions.addOption("h","help", false, "Give this help message");
        cmdLineOptions.addOption("v","version", false, "prints Jelly's version and exits");
        cmdLineOptions.addOption("script", true, "Jelly script to run");
        cmdLineOptions.addOption("awt", false, "Wether to run in the AWT thread.");
        cmdLineOptions.addOption("swing", false, "Synonym of \"-awt\".");
        List builtinOptionNames = Arrays.asList(new String[]{
            "-o","-script","-h","--help","-v","--version","-awt","-swing"});
        
        // -D options will be added to the system properties
        Properties sysProps = System.getProperties();

        // filter the system property setting from the arg list
        // before passing it to the CLI parser
        ArrayList filteredArgList = new ArrayList();

        for (int i=0;i<args.length;i++) {
            String arg = args[i];

            // if this is a -D property parse it and add it to the system properties.
            // -D args will not be copied into the filteredArgList.
            if (arg.startsWith("-D") && (arg.length() > 2)) {
                arg = arg.substring(2);
                int ePos = arg.indexOf("=");
                if(ePos==-1 || ePos==0 || ePos==arg.length()-1)
                    System.err.println("Invalid system property: \"" + arg + "\".");
                sysProps.setProperty(arg.substring(0,ePos), arg.substring(ePos+1));
            } else {
                // add this to the filtered list of arguments
                filteredArgList.add(arg);

                // add additional "-?" options to the options object. if this is not done
                // the only options allowed would be the builtin-ones.
                if (arg.startsWith("-") && arg.length() > 1) {
                    if (!(builtinOptionNames.contains(arg))) {
                        cmdLineOptions.addOption(arg.substring(1, arg.length()), true, "dynamic option");
                    }
                }
            }
        }

        // make the filteredArgList into an array
        String[] filterArgs = new String[filteredArgList.size()];
        filteredArgList.toArray(filterArgs);

        // parse the command line
        Parser parser = new org.apache.commons.cli.GnuParser();
        return parser.parse(cmdLineOptions, filterArgs);
    }

}
