/*
 * 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.jsr199;

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.FileUtils;
import org.apache.myfaces.extensions.scripting.core.util.WeavingContext;

import javax.tools.*;
import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * <p>
 * A compiler facade encapsulating the JSR 199
 * so that we can switch the implementations
 * of connecting to javac on the fly
 * </p>
 * <p>
 * This class is applied to systems which can use the JSR199 compiler
 * API. For older systems we have a javac compiler fallback and
 * probably in the long run also an eclipse as well.
 * </p>
 * <p>
 * We applied first the apache commons-jci project there, but the state
 * of the project was not where we needed it to be for our implementation
 * and fixing and changing it was more work than what was needed for this project.
 * In the dawn of the usage of JSR 199 it simply did not make any more sense
 * to use commons-jci so we rolled our own small specialized facade for this
 * </p>
 *
 * @author Werner Punz (latest modification by $Author: werpu $)
 * @version $Revision: 812255 $ $Date: 2009-09-07 20:51:39 +0200 (Mo, 07 Sep 2009) $
 */
@SuppressWarnings("unused")
public class JSR199Compiler implements org.apache.myfaces.extensions.scripting.api.Compiler {

    JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler();
    ContainerFileManager fileManager = null;

    public JSR199Compiler() {
        super();
    }

    /**
     * Compile a single file
     *
     * @param sourceRoot the source search path (root of our source)
     * @return the compilation result of the  compilation
     * @throws CompilationException in case of a compilation error
     * @deprecated note we will move over to a single
     *             compile step in the beginning in the long run
     *             we will deprecate it as soon as the full
     *             compile at the beginning of the request
     *             is implemented
     *             <p/>
     *             TODO move this code over to the weaver instead of the compiler
     *             we do not do a single compile step anymore
     */
    public CompilationResult compile(File sourceRoot, File targetPath, File toCompile, ClassLoader classPathHolder) throws CompilationException {
        fileManager = new ContainerFileManager(javaCompiler.getStandardFileManager(new DiagnosticCollector<JavaFileObject>(), null, null));

        DiagnosticCollector<JavaFileObject> diagnosticCollector = new DiagnosticCollector<JavaFileObject>();

        //TODO add whitelist check here

        getLog().info("[EXT-SCRIPTING] Doing a full recompile");

        Iterable<? extends JavaFileObject> fileObjects = fileManager.getJavaFileObjects(toCompile);
        String[] options = new String[]{CompilerConst.JC_CLASSPATH, fileManager.getClassPath(), CompilerConst.JC_TARGET_PATH, WeavingContext.getConfiguration().getCompileTarget().getAbsolutePath(), CompilerConst.JC_SOURCEPATH, sourceRoot.getAbsolutePath(), CompilerConst.JC_DEBUG};
        javaCompiler.getTask(null, fileManager, diagnosticCollector, Arrays.asList(options), null, fileObjects).call();
        try {
            handleDiagnostics(diagnosticCollector);
        } catch (ClassNotFoundException e) {
            throw new CompilationException(e);
        }
        return WeavingContext.getCompilationResult(ScriptingConst.ENGINE_TYPE_JSF_JAVA);

    }

    /**
     * compile all files starting from a given root
     * <p/>
     * note, the java compiler interface does not allow per se
     * wildcards due to its file object indirection
     * we deal with that problem by determine all files manually and then
     * push the list into the jsr compiler interface
     *
     * @param sourceRoot the root for all java sources to be compiled
     * @param loader     the classpath holder for the compilation
     * @throws CompilationException in case of a compilation error
     */
    public CompilationResult compile(File sourceRoot, File destination, ClassLoader loader) throws CompilationException {
        fileManager = new ContainerFileManager(javaCompiler.getStandardFileManager(new DiagnosticCollector<JavaFileObject>(), null, null));

        DiagnosticCollector<JavaFileObject> diagnosticCollector = new DiagnosticCollector<JavaFileObject>();

        getLog().info("[EXT-SCRIPTING] Doing a full recompile");

        List<File> sourceFiles = FileUtils.fetchSourceFiles(WeavingContext.getConfiguration().getWhitelistedSourceDirs(ScriptingConst.ENGINE_TYPE_JSF_JAVA), CompilerConst.JAVA_WILDCARD);
        for (File sourceFile : sourceFiles) {
            if (!sourceFile.exists()) {
                getLog().log(Level.WARNING, "[EXT-SCRIPTING] Source file with path {0} does not exist it might cause an error in the compilation process", sourceFile.getAbsolutePath());
            }
        }
        Iterable<? extends JavaFileObject> fileObjects = fileManager.getJavaFileObjects(sourceFiles.toArray(new File[sourceFiles.size()]));
        String[] options = new String[]{CompilerConst.JC_CLASSPATH, fileManager.getClassPath(), CompilerConst.JC_TARGET_PATH, WeavingContext.getConfiguration().getCompileTarget().getAbsolutePath(), CompilerConst.JC_SOURCEPATH, sourceRoot.getAbsolutePath(), CompilerConst.JC_DEBUG};
        javaCompiler.getTask(null, fileManager, diagnosticCollector, Arrays.asList(options), null, fileObjects).call();
        try {
            handleDiagnostics(diagnosticCollector);
        } catch (ClassNotFoundException e) {
            throw new CompilationException(e);
        }
        return WeavingContext.getCompilationResult(ScriptingConst.ENGINE_TYPE_JSF_JAVA);
    }

    /**
     * internal diagnostics handler
     * which just logs the errors
     *
     * @param diagnosticCollector the compilation results, the jsr 199 uses a DiagnosticsCollector object
     *                            to keep the errors and warnings of the compiler
     * @throws ClassNotFoundException in case of an error (this is enforced by the compiler interface
     *                                and probably will be overhauled in the long run)
     */
    private void handleDiagnostics(DiagnosticCollector<JavaFileObject> diagnosticCollector) throws ClassNotFoundException {
        if (diagnosticCollector.getDiagnostics().size() > 0) {
            Logger log = Logger.getLogger(this.getClass().getName());
            StringBuilder errors = new StringBuilder();
            CompilationResult result = new CompilationResult("");
            boolean hasError = false;
            for (Diagnostic diagnostic : diagnosticCollector.getDiagnostics()) {
                String error = createErrorMessage(diagnostic);
                log.log(Level.WARNING, "[EXT-SCRIPTING] Compiler: {0}", error);

                if (diagnostic.getKind().equals(Diagnostic.Kind.ERROR)) {
                    hasError = true;
                    result.getErrors().add(new CompilationResult.CompilationMessage(diagnostic.getLineNumber(), diagnostic.getMessage(Locale.getDefault())));
                } else {
                    result.getWarnings().add(new CompilationResult.CompilationMessage(diagnostic.getLineNumber(), diagnostic.getMessage(Locale.getDefault())));
                }
                errors.append(error);
            }
            WeavingContext.setCompilationResult(ScriptingConst.ENGINE_TYPE_JSF_JAVA, result);
            assertErrorFound(errors, hasError);
        } else {
            WeavingContext.setCompilationResult(ScriptingConst.ENGINE_TYPE_JSF_JAVA, new CompilationResult(""));
        }
    }

    /**
     * interruption of the compile flow should only
     * happen if an error has occurred otherwise we will proceed
     * as expected
     *
     * @param errors   the errors messages found
     * @param hasError marker if an error was found or not
     * @throws ClassNotFoundException in case of a compile error
     */
    private void assertErrorFound(StringBuilder errors, boolean hasError) throws ClassNotFoundException {
        if (hasError) {
            throw new ClassNotFoundException("Compile error of java file:" + errors.toString());
        }
    }

    /**
     * creates a standardized error message
     *
     * @param diagnostic the diagnostic of the compiler containing the error data
     * @return a formatted string with the standardized error message which then later
     *         can be processed by the user
     */
    private String createErrorMessage(Diagnostic diagnostic) {
        StringBuilder retVal = new StringBuilder(256);
        if (diagnostic == null) {
            return retVal.toString();
        }
        if (diagnostic.getKind().equals(Diagnostic.Kind.ERROR)) {
            retVal.append(CompilerConst.STD_ERROR_HEAD);
        } else if (diagnostic.getKind().equals(Diagnostic.Kind.NOTE)) {
            retVal.append(CompilerConst.STD_NOTE_HEAD);
        } else if (diagnostic.getKind().equals(Diagnostic.Kind.WARNING)) {
            retVal.append(CompilerConst.STD_WARN_HEAD);
        } else if (diagnostic.getKind().equals(Diagnostic.Kind.MANDATORY_WARNING)) {
            retVal.append(CompilerConst.STD_MANDATORY_WARN_HEAD);
        } else if (diagnostic.getKind().equals(Diagnostic.Kind.OTHER)) {
            retVal.append(CompilerConst.STD_OTHER_HEAD);
        }
        String message = diagnostic.getMessage(Locale.getDefault());
        message = (message == null) ? "" : message;
        retVal.append(message);
        retVal.append(diagnostic.getLineNumber());

        retVal.append("\n\n");

        String source = "No additional source info";

        if (diagnostic.getSource() != null) {
            source = diagnostic.getSource().toString();
        }
        retVal.append(source);

        return retVal.toString();
    }

    private Logger getLog() {
        return Logger.getLogger(this.getClass().getName());
    }

}
