/*******************************************************************************
 * 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.sling.scripting.sightly.compiler.java.utils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.FileObject;
import javax.tools.ForwardingJavaFileManager;
import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.JavaFileObject.Kind;
import javax.tools.SimpleJavaFileObject;
import javax.tools.StandardLocation;
import javax.tools.ToolProvider;

/**
 * This compiler is a slightly simplified version of the CharSequenceCompiler described at
 * http://www.ibm.com/developerworks/java/library/j-jcomp/index.html.
 */
public class CharSequenceJavaCompiler<T> {
    // Compiler requires source files with a ".java" extension:
    static final String JAVA_EXTENSION = ".java";

    private final ClassLoaderImpl classLoader;

    // The compiler instance that this facade uses.
    private final JavaCompiler compiler;

    // The compiler options (such as "-target" "1.5").
    private final List<String> options;

    // collect compiler diagnostics in this instance.
    private DiagnosticCollector<JavaFileObject> diagnostics;

    // The FileManager which will store source and class "files".
    private final FileManagerImpl javaFileManager;

    /**
     * Construct a new instance which delegates to the named class loader.
     *
     * @param loader
     *           the application ClassLoader. The compiler will look through to
     *           this // class loader for dependent classes
     * @param options
     *           The compiler options (such as "-target" "1.5"). See the usage
     *           for javac
     * @throws IllegalStateException
     *            if the Java compiler cannot be loaded.
     */
    public CharSequenceJavaCompiler(ClassLoader loader, Iterable<String> options) {
        compiler = ToolProvider.getSystemJavaCompiler();
        if (compiler == null) {
            throw new IllegalStateException("Cannot find the system Java compiler. "
                    + "Check that your class path includes tools.jar");
        }
        classLoader = new ClassLoaderImpl(loader);
        diagnostics = new DiagnosticCollector<>();
        final JavaFileManager fileManager = compiler.getStandardFileManager(diagnostics,
                null, null);
        // create our FileManager which chains to the default file manager
        // and our ClassLoader
        javaFileManager = new FileManagerImpl(fileManager, classLoader);
        this.options = new ArrayList<>();
        if (options != null) { // make a save copy of input options
            for (String option : options) {
                this.options.add(option);
            }
        }
    }

    /**
     * Compile Java source in <var>javaSource</name> and return the resulting
     * class.
     * <p>
     * Thread safety: this method is thread safe if the <var>javaSource</var>
     * and <var>diagnosticsList</var> are isolated to this thread.
     *
     * @param qualifiedClassName
     *           The fully qualified class name.
     * @param javaSource
     *           Complete java source, including a package statement and a class,
     *           interface, or annotation declaration.
     * @param types
     *           zero or more Class objects representing classes or interfaces
     *           that the resulting class must be assignable (castable) to.
     * @return a Class which is generated by compiling the source
     * @throws CharSequenceJavaCompilerException
     *            if the source cannot be compiled - for example, if it contains
     *            syntax or semantic errors or if dependent classes cannot be
     *            found.
     * @throws ClassCastException
     *            if the generated class is not assignable to all the optional
     *            <var>types</var>.
     */
    public synchronized Class<T> compile(final String qualifiedClassName,
                                         final CharSequence javaSource,
                                         final Class<?>... types) throws ClassCastException {
        Map<String, CharSequence> classes = new HashMap<>(1);
        classes.put(qualifiedClassName, javaSource);
        try {
            Map<String, Class<T>> compiled = compile(classes);
            Class<T> newClass = compiled.get(qualifiedClassName);
            return castable(newClass, types);
        } catch (CharSequenceJavaCompilerException e) {
            StringBuilder stringBuilder = new StringBuilder();
            for (Diagnostic diagnostic : e.getDiagnostics().getDiagnostics()) {
                stringBuilder.append(diagnostic.toString()).append(System.lineSeparator());
            }
            throw new RuntimeException(stringBuilder.toString());
        }
    }

    /**
     * Compile multiple Java source strings and return a Map containing the
     * resulting classes.
     * <p>
     * Thread safety: this method is thread safe if the <var>classes</var> and
     * <var>diagnosticsList</var> are isolated to this thread.
     *
     * @param classes
     *           A Map whose keys are qualified class names and whose values are
     *           the Java source strings containing the definition of the class.
     *           A map value may be null, indicating that compiled class is
     *           expected, although no source exists for it (it may be a
     *           non-public class contained in one of the other strings.)
     * @return A mapping of qualified class names to their corresponding classes.
     *         The map has the same keys as the input <var>classes</var>; the
     *         values are the corresponding Class objects.
     * @throws CharSequenceJavaCompilerException
     *            if the source cannot be compiled
     */
    public synchronized Map<String, Class<T>> compile(final Map<String, CharSequence> classes) throws CharSequenceJavaCompilerException {
        List<JavaFileObject> sources = new ArrayList<>();
        for (Entry<String, CharSequence> entry : classes.entrySet()) {
            String qualifiedClassName = entry.getKey();
            CharSequence javaSource = entry.getValue();
            if (javaSource != null) {
                final int dotPos = qualifiedClassName.lastIndexOf('.');
                final String className = dotPos == -1 ? qualifiedClassName
                        : qualifiedClassName.substring(dotPos + 1);
                final String packageName = dotPos == -1 ? "" : qualifiedClassName
                        .substring(0, dotPos);
                final JavaFileObjectImpl source = new JavaFileObjectImpl(className,
                        javaSource);
                sources.add(source);
                // Store the source file in the FileManager via package/class
                // name.
                // For source files, we add a .java extension
                javaFileManager.putFileForInput(StandardLocation.SOURCE_PATH, packageName,
                        className + JAVA_EXTENSION, source);
            }
        }
        // Get a CompliationTask from the compiler and compile the sources
        final CompilationTask task = compiler.getTask(null, javaFileManager, diagnostics,
                options, null, sources);
        final Boolean result = task.call();
        if (result == null || !result) {
            throw new CharSequenceJavaCompilerException("Compilation failed.", classes
                    .keySet(), diagnostics);
        }
        try {
            // For each class name in the input map, get its compiled
            // class and put it in the output map
            Map<String, Class<T>> compiled = new HashMap<>();
            for (String qualifiedClassName : classes.keySet()) {
                final Class<T> newClass = loadClass(qualifiedClassName);
                compiled.put(qualifiedClassName, newClass);
            }
            return compiled;
        } catch (ClassNotFoundException e) {
            throw new CharSequenceJavaCompilerException(classes.keySet(), e, diagnostics);
        }
    }

    /**
     * Load a class that was generated by this instance or accessible from its
     * parent class loader. Use this method if you need access to additional
     * classes compiled by
     * {@link #compile(String, CharSequence, Class...) compile()},
     * for example if the primary class contained nested classes or additional
     * non-public classes.
     *
     * @param qualifiedClassName
     *           the name of the compiled class you wish to load
     * @return a Class instance named by <var>qualifiedClassName</var>
     * @throws ClassNotFoundException
     *            if no such class is found.
     */
    @SuppressWarnings("unchecked")
    public Class<T> loadClass(final String qualifiedClassName)
            throws ClassNotFoundException {
        return (Class<T>) classLoader.loadClass(qualifiedClassName);
    }

    /**
     * Check that the <var>newClass</var> is a subtype of all the type
     * parameters and throw a ClassCastException if not.
     *
     * @param types
     *           zero of more classes or interfaces that the <var>newClass</var>
     *           must be castable to.
     * @return <var>newClass</var> if it is castable to all the types
     * @throws ClassCastException
     *            if <var>newClass</var> is not castable to all the types.
     */
    private Class<T> castable(Class<T> newClass, Class<?>... types)
            throws ClassCastException {
        for (Class<?> type : types)
            if (!type.isAssignableFrom(newClass)) {
                throw new ClassCastException(type.getName());
            }
        return newClass;
    }

    /**
     * Converts a String to a URI.
     *
     * @param name
     *           a file name
     * @return a URI
     */
    static URI toURI(String name) {
        try {
            return new URI(name);
        } catch (URISyntaxException e) {
            throw new RuntimeException(e);
        }
    }
}

/**
 * A JavaFileManager which manages Java source and classes. This FileManager
 * delegates to the JavaFileManager and the ClassLoaderImpl provided in the
 * constructor. The sources are all in memory CharSequence instances and the
 * classes are all in memory byte arrays.
 */
final class FileManagerImpl extends ForwardingJavaFileManager<JavaFileManager> {
    // the delegating class loader (passed to the constructor)
    private final ClassLoaderImpl classLoader;

    // Internal map of filename URIs to JavaFileObjects.
    private final Map<URI, JavaFileObject> fileObjects = new HashMap<>();

    /**
     * Construct a new FileManager which forwards to the <var>fileManager</var>
     * for source and to the <var>classLoader</var> for classes
     *
     * @param fileManager
     *           another FileManager that this instance delegates to for
     *           additional source.
     * @param classLoader
     *           a ClassLoader which contains dependent classes that the compiled
     *           classes will require when compiling them.
     */
    public FileManagerImpl(JavaFileManager fileManager, ClassLoaderImpl classLoader) {
        super(fileManager);
        this.classLoader = classLoader;
    }

    /**
     * For a given file <var>location</var>, return a FileObject from which the
     * compiler can obtain source or byte code.
     *
     * @param location
     *           an abstract file location
     * @param packageName
     *           the package name for the file
     * @param relativeName
     *           the file's relative name
     * @return a FileObject from this or the delegated FileManager
     * @see javax.tools.ForwardingJavaFileManager#getFileForInput(javax.tools.JavaFileManager.Location,
     *      java.lang.String, java.lang.String)
     */
    @Override
    public FileObject getFileForInput(Location location, String packageName,
                                      String relativeName) throws IOException {
        FileObject o = fileObjects.get(uri(location, packageName, relativeName));
        if (o != null)
            return o;
        return super.getFileForInput(location, packageName, relativeName);
    }

    /**
     * Store a file that may be retrieved later with
     * {@link #getFileForInput(javax.tools.JavaFileManager.Location, String, String)}
     *
     * @param location
     *           the file location
     * @param packageName
     *           the Java class' package name
     * @param relativeName
     *           the relative name
     * @param file
     *           the file object to store for later retrieval
     */
    public void putFileForInput(StandardLocation location, String packageName,
                                String relativeName, JavaFileObject file) {
        fileObjects.put(uri(location, packageName, relativeName), file);
    }

    /**
     * Convert a location and class name to a URI
     */
    private URI uri(Location location, String packageName, String relativeName) {
        return CharSequenceJavaCompiler.toURI(location.getName() + '/' + packageName + '/'
                + relativeName);
    }

    /**
     * Create a JavaFileImpl for an output class file and store it in the
     * classloader.
     *
     * @see javax.tools.ForwardingJavaFileManager#getJavaFileForOutput(javax.tools.JavaFileManager.Location,
     *      java.lang.String, javax.tools.JavaFileObject.Kind,
     *      javax.tools.FileObject)
     */
    @Override
    public JavaFileObject getJavaFileForOutput(Location location, String qualifiedName,
                                               Kind kind, FileObject outputFile) throws IOException {
        JavaFileObject file = new JavaFileObjectImpl(qualifiedName, kind);
        classLoader.add(qualifiedName, file);
        return file;
    }

    @Override
    public ClassLoader getClassLoader(JavaFileManager.Location location) {
        return classLoader;
    }

    @Override
    public String inferBinaryName(Location loc, JavaFileObject file) {
        String result;
        // For our JavaFileImpl instances, return the file's name, else
        // simply run the default implementation
        if (file instanceof JavaFileObjectImpl)
            result = file.getName();
        else
            result = super.inferBinaryName(loc, file);
        return result;
    }

    @Override
    public Iterable<JavaFileObject> list(Location location, String packageName,
                                         Set<Kind> kinds, boolean recurse) throws IOException {
        Iterable<JavaFileObject> result = super.list(location, packageName, kinds,
                recurse);
        ArrayList<JavaFileObject> files = new ArrayList<>();
        if (location == StandardLocation.CLASS_PATH
                && kinds.contains(JavaFileObject.Kind.CLASS)) {
            for (JavaFileObject file : fileObjects.values()) {
                if (file.getKind() == Kind.CLASS && file.getName().startsWith(packageName))
                    files.add(file);
            }
            files.addAll(classLoader.files());
        } else if (location == StandardLocation.SOURCE_PATH
                && kinds.contains(JavaFileObject.Kind.SOURCE)) {
            for (JavaFileObject file : fileObjects.values()) {
                if (file.getKind() == Kind.SOURCE && file.getName().startsWith(packageName))
                    files.add(file);
            }
        }
        for (JavaFileObject file : result) {
            files.add(file);
        }
        return files;
    }
}

/**
 * A JavaFileObject which contains either the source text or the compiler
 * generated class. This class is used in two cases.
 * <ol>
 * <li>This instance uses it to store the source which is passed to the
 * compiler. This uses the
 * {@link JavaFileObjectImpl#JavaFileObjectImpl(String, CharSequence)}
 * constructor.
 * <li>The Java compiler also creates instances (indirectly through the
 * FileManagerImplFileManager) when it wants to create a JavaFileObject for the
 * .class output. This uses the
 * {@link JavaFileObjectImpl#JavaFileObjectImpl(String, JavaFileObject.Kind)}
 * constructor.
 * </ol>
 * This class does not attempt to reuse instances (there does not seem to be a
 * need, as it would require adding a Map for the purpose, and this would also
 * prevent garbage collection of class byte code.)
 */
final class JavaFileObjectImpl extends SimpleJavaFileObject {
    // If kind == CLASS, this stores byte code from openOutputStream
    private ByteArrayOutputStream byteCode;

    // if kind == SOURCE, this contains the source text
    private final CharSequence source;

    /**
     * Construct a new instance which stores source
     *
     * @param baseName
     *           the base name
     * @param source
     *           the source code
     */
    JavaFileObjectImpl(final String baseName, final CharSequence source) {
        super(CharSequenceJavaCompiler.toURI(baseName + CharSequenceJavaCompiler.JAVA_EXTENSION),
                Kind.SOURCE);
        this.source = source;
    }

    /**
     * Construct a new instance
     *
     * @param name
     *           the file name
     * @param kind
     *           the kind of file
     */
    JavaFileObjectImpl(final String name, final Kind kind) {
        super(CharSequenceJavaCompiler.toURI(name), kind);
        source = null;
    }

    /**
     * Return the source code content
     *
     * @see javax.tools.SimpleJavaFileObject#getCharContent(boolean)
     */
    @Override
    public CharSequence getCharContent(final boolean ignoreEncodingErrors)
            throws UnsupportedOperationException {
        if (source == null)
            throw new UnsupportedOperationException("getCharContent()");
        return source;
    }

    /**
     * Return an input stream for reading the byte code
     *
     * @see javax.tools.SimpleJavaFileObject#openInputStream()
     */
    @Override
    public InputStream openInputStream() {
        return new ByteArrayInputStream(getByteCode());
    }

    /**
     * Return an output stream for writing the bytecode
     *
     * @see javax.tools.SimpleJavaFileObject#openOutputStream()
     */
    @Override
    public OutputStream openOutputStream() {
        byteCode = new ByteArrayOutputStream();
        return byteCode;
    }

    /**
     * @return the byte code generated by the compiler
     */
    byte[] getByteCode() {
        return byteCode.toByteArray();
    }
}

/**
 * A custom ClassLoader which maps class names to JavaFileObjectImpl instances.
 */
final class ClassLoaderImpl extends ClassLoader {
    private final Map<String, JavaFileObject> classes = new HashMap<>();

    ClassLoaderImpl(final ClassLoader parentClassLoader) {
        super(parentClassLoader);
    }

    /**
     * @return An collection of JavaFileObject instances for the classes in the
     *         class loader.
     */
    Collection<JavaFileObject> files() {
        return Collections.unmodifiableCollection(classes.values());
    }

    @Override
    protected Class<?> findClass(final String qualifiedClassName)
            throws ClassNotFoundException {
        JavaFileObject file = classes.get(qualifiedClassName);
        if (file != null) {
            byte[] bytes = ((JavaFileObjectImpl) file).getByteCode();
            return defineClass(qualifiedClassName, bytes, 0, bytes.length);
        }
        try {
            return Class.forName(qualifiedClassName);
        } catch (ClassNotFoundException nf) {
            // Ignore and fall through
        }
        return super.findClass(qualifiedClassName);
    }

    /**
     * Add a class name/JavaFileObject mapping
     *
     * @param qualifiedClassName
     *           the name
     * @param javaFile
     *           the file associated with the name
     */
    void add(final String qualifiedClassName, final JavaFileObject javaFile) {
        classes.put(qualifiedClassName, javaFile);
    }

    @Override
    protected synchronized Class<?> loadClass(final String name, final boolean resolve)
            throws ClassNotFoundException {
        return super.loadClass(name, resolve);
    }

    @Override
    public InputStream getResourceAsStream(final String name) {
        if (name.endsWith(".class")) {
            String qualifiedClassName = name.substring(0,
                    name.length() - ".class".length()).replace('/', '.');
            JavaFileObjectImpl file = (JavaFileObjectImpl) classes.get(qualifiedClassName);
            if (file != null) {
                return new ByteArrayInputStream(file.getByteCode());
            }
        }
        return super.getResourceAsStream(name);
    }
}
