/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.jci2.examples.commandline;

import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Iterator;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.Options;
import org.apache.commons.jci2.compilers.CompilationResult;
import org.apache.commons.jci2.compilers.JavaCompiler;
import org.apache.commons.jci2.compilers.JavaCompilerFactory;
import org.apache.commons.jci2.compilers.JavaCompilerSettings;
import org.apache.commons.jci2.problems.CompilationProblem;
import org.apache.commons.jci2.problems.CompilationProblemHandler;
import org.apache.commons.jci2.readers.FileResourceReader;
import org.apache.commons.jci2.readers.ResourceReader;
import org.apache.commons.jci2.stores.FileResourceStore;
import org.apache.commons.jci2.stores.ResourceStore;

/**
 * A simple front end to jci2 mimicking the javac command line
 *
 * @author tcurdt
 */
public final class CommandlineCompiler {
    
    public static void main( final String[] args ) throws Exception {

        final Options options = new Options();

        options.addOption(
                OptionBuilder.withArgName("a.jar:b.jar")
                    .hasArg()
                    .withValueSeparator( ':' )
                    .withDescription("Specify where to find user class files")
                    .create( "classpath" ));

        options.addOption(
                OptionBuilder.withArgName("release")
                    .hasArg()
                    .withDescription("Provide source compatibility with specified release")
                    .create( "source" ));

        options.addOption(
                OptionBuilder.withArgName("release")
                    .hasArg()
                    .withDescription("Generate class files for specific VM version")
                    .create( "target" ));

        options.addOption(
                OptionBuilder.withArgName("path")
                    .hasArg()
                    .withDescription("Specify where to find input source files")
                    .create( "sourcepath" ));

        options.addOption(
                OptionBuilder.withArgName("directory")
                    .hasArg()
                    .withDescription("Specify where to place generated class files")
                    .create( "d" ));

        options.addOption(
                OptionBuilder.withArgName("num")
                    .hasArg()
                    .withDescription("Stop compilation after these number of errors")
                    .create( "Xmaxerrs" ));

        options.addOption(
                OptionBuilder.withArgName("num")
                    .hasArg()
                    .withDescription("Stop compilation after these number of warning")
                    .create( "Xmaxwarns" ));

        options.addOption(
                OptionBuilder.withDescription("Generate no warnings")
                    .create( "nowarn" ));

//        final HelpFormatter formatter = new HelpFormatter();
//        formatter.printHelp("jci2", options);

        final CommandLineParser parser = new GnuParser();
        final CommandLine cmd = parser.parse(options, args, true);

        ClassLoader classloader = CommandlineCompiler.class.getClassLoader();
        File sourcepath = new File(".");
        File targetpath = new File(".");
        int maxerrs = 10;
        int maxwarns = 10;
        final boolean nowarn = cmd.hasOption("nowarn");


        final JavaCompiler compiler = new JavaCompilerFactory().createCompiler("eclipse");
        final JavaCompilerSettings settings = compiler.createDefaultSettings();


        for (final Iterator it = cmd.iterator(); it.hasNext();) {
            final Option option = (Option) it.next();
            if ("classpath".equals(option.getOpt())) {
                final String[] values = option.getValues();
                final URL[] urls = new URL[values.length];
                for (int i = 0; i < urls.length; i++) {
                    urls[i] = new File(values[i]).toURL();
                }
                classloader = new URLClassLoader(urls);
            } else if ("source".equals(option.getOpt())) {
                settings.setSourceVersion(option.getValue());
            } else if ("target".equals(option.getOpt())) {
                settings.setTargetVersion(option.getValue());
            } else if ("sourcepath".equals(option.getOpt())) {
                sourcepath = new File(option.getValue());
            } else if ("d".equals(option.getOpt())) {
                targetpath = new File(option.getValue());
            } else if ("Xmaxerrs".equals(option.getOpt())) {
                maxerrs = Integer.parseInt(option.getValue());
            } else if ("Xmaxwarns".equals(option.getOpt())) {
                maxwarns = Integer.parseInt(option.getValue());
            }
        }

        final ResourceReader reader = new FileResourceReader(sourcepath);
        final ResourceStore store = new FileResourceStore(targetpath);
        
        final int maxErrors = maxerrs;
        final int maxWarnings = maxwarns;
        compiler.setCompilationProblemHandler(new CompilationProblemHandler() {
            int errors = 0;
            int warnings = 0;
            public boolean handle(final CompilationProblem pProblem) {

                if (pProblem.isError()) {
                    System.err.println(pProblem);

                    errors++;

                    if (errors >= maxErrors) {
                        return false;
                    }
                } else {
                    if (!nowarn) {
                        System.err.println(pProblem);
                    }

                    warnings++;

                    if (warnings >= maxWarnings) {
                        return false;
                    }
                }

                return true;
            }
        });
        
        final String[] resource = cmd.getArgs();
        
        for (final String element : resource) {
            System.out.println("compiling " + element);
        }
        
        final CompilationResult result = compiler.compile(resource, reader, store, classloader);
        
        System.out.println( result.getErrors().length + " errors");
        System.out.println( result.getWarnings().length + " warnings");

    }
}
