/*
 * 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.myfaces.extensions.scripting.loaders.java.compiler;

import org.apache.myfaces.extensions.scripting.api.CompilationException;
import org.apache.myfaces.extensions.scripting.api.CompilationResult;
import org.apache.myfaces.extensions.scripting.api.CompilerConst;
import org.apache.myfaces.extensions.scripting.api.ScriptingConst;
import org.apache.myfaces.extensions.scripting.core.util.ClassLoaderUtils;
import org.apache.myfaces.extensions.scripting.core.util.ClassUtils;
import org.apache.myfaces.extensions.scripting.core.util.FileUtils;
import org.apache.myfaces.extensions.scripting.core.util.WeavingContext;

import java.io.File;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * <p>A compiler implementation that utilizes some internal classes that enable you to
 * compile Java source code using the javac compiler being provided by your JDK. However,
 * note that this only works if you're using a Sun JDK up to the version 1.5 (as of Java 6
 * you should use the JSR-199 API).</p>
 * <p/>
 * <p>This class loads some internal classes from $JAVA_HOME$/lib/tools.jar so be sure to
 * either include this JAR file in your classpath at startup or set the JAVA_HOME property
 * accordingly so that it points to a valid JDK home directory (it doesn't work if you're
 * just using a JRE!)</p>
 */
public class JavacCompiler implements org.apache.myfaces.extensions.scripting.api.Compiler {

    /**
     * The logger instance for this class.
     */
    private static final Logger _logger = Logger.getLogger(JavacCompiler.class.getName());

    /**
     * The class name of the javac compiler. Note that this class
     * is only available if you're using a Sun JDK.
     */
    private static final String JAVAC_MAIN = "com.sun.tools.javac.Main";

    /**
     * The class reference to the internal Javac compiler.
     */
    private Class _compilerClass;

    // ------------------------------------------ Constructors

    /**
     * <p>Creates a new Javac compiler by searching for the required JAR file '$JAVA_HOME$/lib/tools.jar'
     * automatically. Note that the user has to specify the JAVA_HOME property in this case.</p>
     */
    public JavacCompiler() {
        this(null);
    }

    /**
     * <p>Creates a new Javac compiler by searching for internal classes in the given JAR file.</p>
     *
     * @param toolsJar the location of the JAR file '$JAVA_HOME$/lib/tools.jar' or <code>null</code>
     *                 if you want it to be searched for automatically
     */
    public JavacCompiler(URL toolsJar) {
        ClassLoader classLoader;

        try {
            classLoader = createJavacAwareClassLoader(toolsJar);
        } catch (MalformedURLException ex) {
            throw new IllegalStateException("An error occured while trying to load the Javac compiler class.", ex);
        }

        try {
            this._compilerClass = classLoader.loadClass(JAVAC_MAIN);
        } catch (ClassNotFoundException ex) {
            throw new IllegalStateException("The Javac compiler class '" + JAVAC_MAIN + "' couldn't be found even though" +
                    "the required JAR file '$JAVA_HOME$/lib/tools.jar' has been put on the classpath. Are you sure that " +
                    "you're using a valid Sun JDK?");
        }
    }

    // ------------------------------------------ Compiler methods

    /**
     * <p>Compiles the given file and creates an according class file in the given target path.</p>
     *
     * @param sourcePath the path to the source directory
     * @param targetPath the path to the target directory
     * @return the compilation result, i.e. as of now only the compiler output
     */
    public CompilationResult compile(File sourcePath, File targetPath, ClassLoader loader) throws CompilationException {
        FileUtils.assertPath(targetPath);

        try {
            StringWriter compilerOutput = new StringWriter();
            // Invoke the Javac compiler
            Method compile = _compilerClass.getMethod("compile", new Class[]{String[].class, PrintWriter.class});
            Object[] compilerArguments = new Object[]{buildCompilerArgumentsWhitelisted(sourcePath, targetPath, loader), new PrintWriter(compilerOutput)};
            logCommandLine(compilerArguments);

            Integer returnCode = (Integer) compile.invoke(null, compilerArguments);

            CompilationResult result = new CompilationResult(compilerOutput.toString());
            if (returnCode == null || returnCode.intValue() != 0) {
                result.registerError(new CompilationResult.CompilationMessage(-1,
                        "Executing the javac compiler failed. The return code is '" + returnCode + "'." + compilerOutput.toString()));
            }
            WeavingContext.setCompilationResult(ScriptingConst.ENGINE_TYPE_JSF_JAVA, result);
            return result;
        } catch (NoSuchMethodException ex) {
            throw new CompilationException("The Javac compiler class '" + _compilerClass + "' doesn't provide the method " +
                    "compile(String, PrintWriter). Are you sure that you're using a valid Sun JDK?", ex);
        } catch (InvocationTargetException ex) {
            throw new CompilationException("An error occured while invoking the compile(String, PrintWriter) method of the " +
                    "Javac compiler class '" + _compilerClass + "'. Are you sure that you're using a valid Sun JDK?", ex);
        } catch (IllegalAccessException ex) {
            throw new CompilationException("An error occured while invoking the compile(String, PrintWriter) method of the " +
                    "Javac compiler class '" + _compilerClass + "'. Are you sure that you're using a valid Sun JDK?", ex);
        }

    }

    /**
     * <p>Compiles the given file and creates an according class file in the given target path.</p>
     *
     * @param sourcePath the path to the source directory
     * @param targetPath the path to the target directory
     * @param file       the relative file name of the class you want to compile
     * @return the compilation result, i.e. as of now only the compiler output
     */
    public CompilationResult compile(File sourcePath, File targetPath, File file, ClassLoader loader) throws CompilationException {
        // The destination directory must already exist as javac will not create the destination directory.
        FileUtils.assertPath(targetPath);

        try {
            StringWriter compilerOutput = new StringWriter();

            // Invoke the Javac compiler
            Method compile = _compilerClass.getMethod("compile", new Class[]{String[].class, PrintWriter.class});
            if (!targetPath.exists()) {
                if (!targetPath.mkdirs()) {
                    throw new IllegalStateException("It wasn't possible to create the target " +
                            "directory for the compiler ['" + targetPath.getAbsolutePath() + "'].");
                }
            }

            //TODO make a whitelist check here
            Object[] compilerArguments = new Object[]{buildCompilerArguments(sourcePath, targetPath, file.getAbsolutePath(), loader), new PrintWriter(compilerOutput)};
            logCommandLine(compilerArguments);

            Integer returnCode = (Integer) compile.invoke(null,
                    compilerArguments);

            CompilationResult result = new CompilationResult(compilerOutput.toString());
            if (returnCode == null || returnCode != 0) {
                result.registerError(new CompilationResult.CompilationMessage(-1,
                        "Executing the javac compiler failed. The return code is '" + returnCode + "'." + compilerOutput.toString()));
            }
            WeavingContext.setCompilationResult(ScriptingConst.ENGINE_TYPE_JSF_JAVA, result);
            return result;
        } catch (NoSuchMethodException ex) {
            throw new IllegalStateException("The Javac compiler class '" + _compilerClass + "' doesn't provide the method " +
                    "compile(String, PrintWriter). Are you sure that you're using a valid Sun JDK?", ex);
        } catch (InvocationTargetException ex) {
            throw new IllegalStateException("An error occured while invoking the compile(String, PrintWriter) method of the " +
                    "Javac compiler class '" + _compilerClass + "'. Are you sure that you're using a valid Sun JDK?", ex);
        } catch (IllegalAccessException ex) {
            throw new IllegalStateException("An error occured while invoking the compile(String, PrintWriter) method of the " +
                    "Javac compiler class '" + _compilerClass + "'. Are you sure that you're using a valid Sun JDK?", ex);
        }
    }

    private void logCommandLine(Object[] compilerArguments) {
        if (_logger.isLoggable(Level.FINE)) {
            StringBuilder commandLine = new StringBuilder();
            commandLine.append("javac ");
            for (String compilerArgument : (String[]) compilerArguments[0]) {
                commandLine.append(compilerArgument);
                commandLine.append(" ");
            }
            _logger.log(Level.FINE, commandLine.toString());
        }
        if (_logger.isLoggable(Level.INFO)) {
            _logger.info("[EXT-SCRIPTING] compiling java");
        }

    }

    // ------------------------------------------ Utility methods

    /**
     * <p/>
     * Creates the arguments for the compiler, i.e. builds up an array of arguments
     * that one would pass to the javac compiler to compile a full path instead of a single file
     *
     * @param sourcePath the path to the source directory
     * @param targetPath the path to the target directory
     * @return an array of arguments that you have to pass to the Javac compiler
     */
    protected String[] buildCompilerArgumentsWhitelisted(File sourcePath, File targetPath, ClassLoader loader) {
        List<File> sourceFiles = FileUtils.fetchSourceFiles(WeavingContext.getConfiguration().getWhitelistedSourceDirs(ScriptingConst.ENGINE_TYPE_JSF_JAVA), "*.java");

        List arguments = getDefaultArguments(sourcePath, targetPath, loader);

        // Append the source file that is to be compiled. Note that the user specifies only a relative file location.
        for (File sourceFile : sourceFiles) {
            arguments.add(sourceFile.getAbsolutePath());
        }
        return (String[]) argumentsToArray(arguments);
    }

    private Object[] argumentsToArray(List arguments) {
        return arguments.toArray(new String[arguments.size()]);
    }

    /**
     * <p/>
     * Creates the arguments for the compiler, i.e. builds up an array of arguments
     * that one would pass to the javac compiler to compile a full path instead of a single file
     *
     * @param sourcePath the path to the source directory
     * @param targetPath the path to the target directory
     * @return an array of arguments that you have to pass to the Javac compiler
     */
    protected String[] buildCompilerArguments(File sourcePath, File targetPath, ClassLoader loader) {
        List<File> sourceFiles = FileUtils.fetchSourceFiles(sourcePath, "*.java");

        List arguments = getDefaultArguments(sourcePath, targetPath, loader);

        // Append the source file that is to be compiled. Note that the user specifies only a relative file location.
        for (File sourceFile : sourceFiles) {
            arguments.add(sourceFile.getAbsolutePath());
        }
        return (String[]) argumentsToArray(arguments);
    }

    /**
     * <p>Creates the arguments for the compiler, i.e. it builds an array of arguments that one would pass to
     * the Javac compiler on the command line.</p>
     *
     * @param sourcePath the path to the source directory
     * @param targetPath the path to the target directory
     * @param loader     the classpath holder for the compiler
     * @param file       the relative file name of the class you want to compile
     * @return an array of arguments that you have to pass to the Javac compiler
     */
    protected String[] buildCompilerArguments(File sourcePath, File targetPath, String file, ClassLoader loader) {
        List arguments = getDefaultArguments(sourcePath, targetPath, loader);

        // Append the source file that is to be compiled. Note that the user specifies only a relative file location.
        arguments.add(new File(sourcePath, file).getAbsolutePath());

        return (String[]) argumentsToArray(arguments);
    }

    /**
     * <p>
     * Determination of the default arguments
     * which have to be the same over all
     * different compilation strategies
     * </p>
     *
     * @param sourcePath the path to the source directory
     * @param targetPath the path to the target directory
     * @param loader     the classloader holding the classpath
     * @return
     */
    private List getDefaultArguments(File sourcePath, File targetPath, ClassLoader loader) {
        List arguments = new ArrayList();

        // Set both the source code path to search for class or interface
        // definitions and the destination directory for class files.
        arguments.add(CompilerConst.JC_SOURCEPATH);
        arguments.add(sourcePath.getAbsolutePath());
        arguments.add(CompilerConst.JC_TARGET_PATH);
        arguments.add(targetPath.getAbsolutePath());
        arguments.add(CompilerConst.JC_CLASSPATH);
        arguments.add(ClassLoaderUtils.buildClasspath(loader));

        // Enable verbose output.
        arguments.add(CompilerConst.JC_VERBOSE);

        // Generate all debugging information, including local variables.
        arguments.add(CompilerConst.JC_DEBUG);
        return arguments;
    }

    /**
     * <p>Returns a possibly newly created classloader that you can use in order to load the
     * Javac compiler class. Usually the user would have to put the JAR file
     * '$JAVA_HOME$/lib/tools.jar' on the classpath but this method recognizes this on its own
     * and loads the JAR file if necessary. However, it's not guaranteed that the Javac compiler
     * class is available (e.g. if one is providing a wrong tools.jar file that doesn't contain
     * the required classes).</p>
     *
     * @param toolsJar the location of the JAR file '$JAVA_HOME$/lib/tools.jar' or <code>null</code>
     *                 if you want it to be searched for automatically
     * @return a classloader that you can use in order to load the Javac compiler class
     * @throws MalformedURLException if an error occurred while constructing the URL
     */
    private static ClassLoader createJavacAwareClassLoader(URL toolsJar) throws MalformedURLException {
        // If the user has already included the tools.jar in the classpath we don't have
        // to create a custom class loader as the class is already available.
        if (ClassUtils.isPresent(JAVAC_MAIN)) {
            if (_logger.isLoggable(Level.FINE)) {
                _logger.log(Level.FINE, "Seemingly the required JAR file '$JAVA_HOME$/lib/tools.jar' has already been "
                        + "put on the classpath as the class '" + JAVAC_MAIN + "' is present. So there's no "
                        + "need to create a custom classloader for the Javac compiler.");
            }

            return ClassUtils.getContextClassLoader();
        } else {
            // The compiler isn't available in the current classpath, but the user could have specified the tools.jar file.
            if (toolsJar == null) {
                String javaHome = System.getProperty("java.home");
                if (javaHome.toLowerCase(Locale.getDefault()).endsWith(File.separator + "jre")) {
                    // Note that even if the user has installed a valid JDK the $JAVA_HOME$ property might reference
                    // the JRE, e.g. '/usr/lib/jvm/java-6-sun-1.6.0.16/jre'. However, in this case we just have to
                    // remove the last four characters (i.e. the '/jre'). 
                    javaHome = javaHome.substring(0, javaHome.length() - 4);
                }

                // If the user hasn't specified the URL to the tools.jar file, we'll try to find it on our own.
                File toolsJarFile = new File(javaHome, "lib" + File.separatorChar + "tools.jar");
                if (toolsJarFile.exists()) {
                    if (_logger.isLoggable(Level.FINE)) {
                        _logger.log(Level.FINE,
                                "The required JAR file '$JAVA_HOME$/lib/tools.jar' has been found ['" + toolsJarFile.getAbsolutePath()
                                        + "']. A custom URL classloader will be created for the Javac compiler.");
                    }

                    return new URLClassLoader(
                            new URL[]{toolsJarFile.toURI().toURL()}, ClassUtils.getContextClassLoader());
                } else {
                    throw new IllegalStateException("The Javac compiler class '" + JAVAC_MAIN + "' and the required JAR file " +
                            "'$JAVA_HOME$/lib/tools.jar' couldn't be found. Are you sure that you're using a valid Sun JDK? " +
                            "[$JAVA_HOME$: '" + System.getProperty("java.home") + "']");
                }
            } else {
                if (_logger.isLoggable(Level.FINE)) {
                    _logger.log(Level.FINE, "The user has specified the required JAR file '$JAVA_HOME$/lib/tools.jar' ['"
                            + toolsJar.toExternalForm() + "']. A custom URL classloader will be created for the Javac compiler.");
                }

                return new URLClassLoader(new URL[]{toolsJar}, ClassUtils.getContextClassLoader());
            }
        }
    }

}
