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

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.StringTokenizer;

import org.apache.jasper.JasperException;
import org.apache.jasper.runtime.ExceptionUtils;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.internal.compiler.ClassFile;
import org.eclipse.jdt.internal.compiler.Compiler;
import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
import org.eclipse.jdt.internal.compiler.ICompilerRequestor;
import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy;
import org.eclipse.jdt.internal.compiler.IProblemFactory;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
import org.eclipse.jdt.internal.compiler.lookup.ModuleBinding;
import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;

/**
 * JDT class compiler. This compiler will load source dependencies from the context classloader, reducing dramatically
 * disk access during the compilation process. Based on code from Cocoon2.
 */
public class JDTCompiler extends org.apache.jasper.compiler.Compiler {

    /**
     * Constructs a new JDTCompiler.
     */
    public JDTCompiler() {
    }

    private final Log log = LogFactory.getLog(JDTCompiler.class); // must not be static

    @Override
    protected void generateClass(Map<String,SmapStratum> smaps)
            throws FileNotFoundException, JasperException, Exception {

        long t1 = 0;
        if (log.isDebugEnabled()) {
            t1 = System.currentTimeMillis();
        }

        final String sourceFile = ctxt.getServletJavaFileName();
        final String outputDir = ctxt.getOptions().getScratchDir().getAbsolutePath();
        String packageName = ctxt.getServletPackageName();
        final String targetClassName =
                ((!packageName.isEmpty()) ? (packageName + ".") : "") + ctxt.getServletClassName();
        final ClassLoader classLoader = ctxt.getJspLoader();
        String[] fileNames = new String[] { sourceFile };
        String[] classNames = new String[] { targetClassName };
        final List<JavacErrorDetail> problemList = new ArrayList<>();

        class CompilationUnit implements ICompilationUnit {

            private final String className;
            private final String sourceFile;

            CompilationUnit(String sourceFile, String className) {
                this.className = className;
                this.sourceFile = sourceFile;
            }

            @Override
            public char[] getFileName() {
                return sourceFile.toCharArray();
            }

            @Override
            public char[] getContents() {
                char[] result;
                try (FileInputStream is = new FileInputStream(sourceFile);
                        InputStreamReader isr = new InputStreamReader(is, ctxt.getOptions().getJavaEncoding());
                        Reader reader = new BufferedReader(isr)) {
                    char[] chars = new char[8192];
                    StringBuilder buf = new StringBuilder();
                    int count;
                    while ((count = reader.read(chars, 0, chars.length)) > 0) {
                        buf.append(chars, 0, count);
                    }
                    result = new char[buf.length()];
                    buf.getChars(0, result.length, result, 0);
                } catch (IOException ioe) {
                    log.error(Localizer.getMessage("jsp.error.compilation.source", sourceFile), ioe);
                    result = new char[0];
                }
                return result;
            }

            @Override
            public char[] getMainTypeName() {
                int dot = className.lastIndexOf('.');
                if (dot > 0) {
                    return className.substring(dot + 1).toCharArray();
                }
                return className.toCharArray();
            }

            @Override
            public char[][] getPackageName() {
                StringTokenizer izer = new StringTokenizer(className, ".");
                char[][] result = new char[izer.countTokens() - 1][];
                for (int i = 0; i < result.length; i++) {
                    String tok = izer.nextToken();
                    result[i] = tok.toCharArray();
                }
                return result;
            }

            @Override
            public boolean ignoreOptionalProblems() {
                return false;
            }

            @Override
            public ModuleBinding module(LookupEnvironment environment) {
                return environment.getModule(ModuleBinding.UNNAMED);
            }

            @Override
            public char[] getModuleName() {
                return ModuleBinding.UNNAMED;
            }
        }

        final INameEnvironment env = new INameEnvironment() {

            @Override
            public NameEnvironmentAnswer findType(char[][] compoundTypeName) {
                StringBuilder result = new StringBuilder();
                for (int i = 0; i < compoundTypeName.length; i++) {
                    if (i > 0) {
                        result.append('.');
                    }
                    result.append(compoundTypeName[i]);
                }
                return findType(result.toString());
            }

            @Override
            public NameEnvironmentAnswer findType(char[] typeName, char[][] packageName) {
                StringBuilder result = new StringBuilder();
                int i = 0;
                for (; i < packageName.length; i++) {
                    if (i > 0) {
                        result.append('.');
                    }
                    result.append(packageName[i]);
                }
                if (i > 0) {
                    result.append('.');
                }
                result.append(typeName);
                return findType(result.toString());
            }

            private NameEnvironmentAnswer findType(String className) {

                if (className.equals(targetClassName)) {
                    ICompilationUnit compilationUnit = new CompilationUnit(sourceFile, className);
                    return new NameEnvironmentAnswer(compilationUnit, null);
                }

                String resourceName = className.replace('.', '/') + ".class";

                try (InputStream is = classLoader.getResourceAsStream(resourceName)) {
                    if (is != null) {
                        byte[] classBytes;
                        byte[] buf = new byte[8192];
                        ByteArrayOutputStream baos = new ByteArrayOutputStream(buf.length);
                        int count;
                        while ((count = is.read(buf, 0, buf.length)) > 0) {
                            baos.write(buf, 0, count);
                        }
                        baos.flush();
                        classBytes = baos.toByteArray();
                        char[] fileName = className.toCharArray();
                        ClassFileReader classFileReader = new ClassFileReader(classBytes, fileName, true);
                        return new NameEnvironmentAnswer(classFileReader, null);
                    }
                } catch (IOException | ClassFormatException exc) {
                    log.error(Localizer.getMessage("jsp.error.compilation.dependent", className), exc);
                }
                return null;
            }

            private boolean isPackage(String result) {
                if (result.equals(targetClassName) || result.startsWith(targetClassName + '$')) {
                    return false;
                }
                /*
                 * This might look heavy-weight but, with only the ClassLoader API available, trying to load the
                 * resource as a class is the only reliable way found so far to differentiate between a class and a
                 * package. Other options, such as getResource(), fail for some edge cases on case insensitive file
                 * systems. As this code is only called at compile time, the performance impact is not a significant
                 * concern.
                 */
                try {
                    classLoader.loadClass(result);
                } catch (Throwable t) {
                    ExceptionUtils.handleThrowable(t);
                    return true;
                }
                return false;
            }

            @Override
            public boolean isPackage(char[][] parentPackageName, char[] packageName) {
                StringBuilder result = new StringBuilder();
                int i = 0;
                if (parentPackageName != null) {
                    for (; i < parentPackageName.length; i++) {
                        if (i > 0) {
                            result.append('.');
                        }
                        result.append(parentPackageName[i]);
                    }
                }

                if (Character.isUpperCase(packageName[0])) {
                    if (!isPackage(result.toString())) {
                        return false;
                    }
                }
                if (i > 0) {
                    result.append('.');
                }
                result.append(packageName);

                return isPackage(result.toString());
            }

            @Override
            public void cleanup() {
            }

        };

        final IErrorHandlingPolicy policy = DefaultErrorHandlingPolicies.proceedWithAllProblems();

        final Map<String,String> settings = new HashMap<>();
        settings.put(CompilerOptions.OPTION_LineNumberAttribute, CompilerOptions.GENERATE);
        settings.put(CompilerOptions.OPTION_SourceFileAttribute, CompilerOptions.GENERATE);
        settings.put(CompilerOptions.OPTION_ReportDeprecation, CompilerOptions.IGNORE);
        if (ctxt.getOptions().getJavaEncoding() != null) {
            settings.put(CompilerOptions.OPTION_Encoding, ctxt.getOptions().getJavaEncoding());
        }
        if (ctxt.getOptions().getClassDebugInfo()) {
            settings.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.GENERATE);
        }

        // Source JVM
        if (ctxt.getOptions().getCompilerSourceVM() != null) {
            String opt = ctxt.getOptions().getCompilerSourceVM();
            switch (opt) {
                case "1.1" -> settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_1);
                case "1.2" -> settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_2);
                case "1.3" -> settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_3);
                case "1.4" -> settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_4);
                case "1.5" -> settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_5);
                case "1.6" -> settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_6);
                case "1.7" -> settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_7);
                case "1.8" -> settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_8);

                // Version format changed from Java 9 onwards.
                // Support old format that was used in EA implementation as well
                case "9", "1.9" -> settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_9);
                case "10" -> settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_10);
                case "11" -> settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_11);
                case "12" -> settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12);
                case "13" -> settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_13);
                case "14" -> settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_14);
                case "15" -> settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_15);
                case "16" -> settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_16);
                case "17" -> settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_17);
                case "18" -> settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_18);
                case "19" -> settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_19);
                case "20" -> settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_20);
                case "21" -> settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_21);
                case "22" -> settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_22);
                case "23" -> settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_23);
                case "24" -> settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_24);
                case "25" -> settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_25);
                case "26" -> settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_26);
                case "27" ->
                        // Constant not available in latest ECJ version shipped with
                        // Tomcat. May be supported in a snapshot build.
                        // This is checked against the actual version below.
                        settings.put(CompilerOptions.OPTION_Source, "27");
                case "28" ->
                        // Constant not available in latest ECJ version shipped with
                        // Tomcat. May be supported in a snapshot build.
                        // This is checked against the actual version below.
                        settings.put(CompilerOptions.OPTION_Source, "28");
                default -> {
                    log.warn(Localizer.getMessage("jsp.warning.unknown.sourceVM", opt));
                    settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_21);
                }
            }
        } else {
            // Default to 21
            settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_21);
        }

        // Target JVM
        if (ctxt.getOptions().getCompilerTargetVM() != null) {
            String opt = ctxt.getOptions().getCompilerTargetVM();
            switch (opt) {
                case "1.1" -> settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_1);
                case "1.2" -> settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_2);
                case "1.3" -> settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_3);
                case "1.4" -> settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4);
                case "1.5" -> {
                    settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5);
                    settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_5);
                }
                case "1.6" -> {
                    settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6);
                    settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_6);
                }
                case "1.7" -> {
                    settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_7);
                    settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_7);
                }
                case "1.8" -> {
                    settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_8);
                    settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_8);
                    // Version format changed from Java 9 onwards.
                    // Support old format that was used in EA implementation as well
                }
                case "9", "1.9" -> {
                    settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_9);
                    settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_9);
                }
                case "10" -> {
                    settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_10);
                    settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_10);
                }
                case "11" -> {
                    settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_11);
                    settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_11);
                }
                case "12" -> {
                    settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12);
                    settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12);
                }
                case "13" -> {
                    settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_13);
                    settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_13);
                }
                case "14" -> {
                    settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_14);
                    settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_14);
                }
                case "15" -> {
                    settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_15);
                    settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_15);
                }
                case "16" -> {
                    settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_16);
                    settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_16);
                }
                case "17" -> {
                    settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_17);
                    settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_17);
                }
                case "18" -> {
                    settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_18);
                    settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_18);
                }
                case "19" -> {
                    settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_19);
                    settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_19);
                }
                case "20" -> {
                    settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_20);
                    settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_20);
                }
                case "21" -> {
                    settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_21);
                    settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_21);
                }
                case "22" -> {
                    settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_22);
                    settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_22);
                }
                case "23" -> {
                    settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_23);
                    settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_23);
                }
                case "24" -> {
                    settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_24);
                    settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_24);
                }
                case "25" -> {
                    settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_25);
                    settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_25);
                }
                case "26" -> {
                    settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_26);
                    settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_26);
                }
                case "27" -> {
                    // Constant not available in latest ECJ version shipped with
                    // Tomcat. May be supported in a snapshot build.
                    // This is checked against the actual version below.
                    settings.put(CompilerOptions.OPTION_TargetPlatform, "27");
                    settings.put(CompilerOptions.OPTION_Compliance, "27");
                }
                case "28" -> {
                    // Constant not available in latest ECJ version shipped with
                    // Tomcat. May be supported in a snapshot build.
                    // This is checked against the actual version below.
                    settings.put(CompilerOptions.OPTION_TargetPlatform, "28");
                    settings.put(CompilerOptions.OPTION_Compliance, "28");
                }
                default -> {
                    log.warn(Localizer.getMessage("jsp.warning.unknown.targetVM", opt));
                    settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_21);
                }
            }
        } else {
            // Default to 21
            settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_21);
            settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_21);
        }

        final IProblemFactory problemFactory = new DefaultProblemFactory(Locale.getDefault());

        final ICompilerRequestor requestor = result -> {
            try {
                if (result.hasProblems()) {
                    IProblem[] problems = result.getProblems();
                    for (IProblem problem : problems) {
                        if (problem.isError()) {
                            String name = new String(problem.getOriginatingFileName());
                            try {
                                problemList.add(ErrorDispatcher.createJavacError(name, pageNodes,
                                        new StringBuilder(problem.getMessage()), problem.getSourceLineNumber(), ctxt));
                            } catch (JasperException e) {
                                log.error(Localizer.getMessage("jsp.error.compilation.jdtProblemError"), e);
                            }
                        }
                    }
                }
                if (problemList.isEmpty()) {
                    ClassFile[] classFiles = result.getClassFiles();
                    for (ClassFile classFile : classFiles) {
                        char[][] compoundName = classFile.getCompoundName();
                        StringBuilder classFileName = new StringBuilder(outputDir).append('/');
                        for (int j = 0; j < compoundName.length; j++) {
                            if (j > 0) {
                                classFileName.append('/');
                            }
                            classFileName.append(compoundName[j]);
                        }
                        byte[] bytes = classFile.getBytes();
                        classFileName.append(".class");
                        try (FileOutputStream fout = new FileOutputStream(classFileName.toString());
                                BufferedOutputStream bos = new BufferedOutputStream(fout)) {
                            bos.write(bytes);
                        }
                    }
                }
            } catch (IOException ioe) {
                log.error(Localizer.getMessage("jsp.error.compilation.jdt"), ioe);
            }
        };

        ICompilationUnit[] compilationUnits = new ICompilationUnit[classNames.length];
        for (int i = 0; i < compilationUnits.length; i++) {
            String className = classNames[i];
            compilationUnits[i] = new CompilationUnit(fileNames[i], className);
        }
        CompilerOptions cOptions = new CompilerOptions(settings);

        // Check source/target JDK versions as the newest versions are allowed
        // in Tomcat configuration but may not be supported by the ECJ version
        // being used.
        String requestedSource = ctxt.getOptions().getCompilerSourceVM();
        if (requestedSource != null) {
            String actualSource = CompilerOptions.versionFromJdkLevel(cOptions.sourceLevel);
            if (!requestedSource.equals(actualSource)) {
                log.warn(Localizer.getMessage("jsp.warning.unsupported.sourceVM", requestedSource, actualSource));
            }
        }
        String requestedTarget = ctxt.getOptions().getCompilerTargetVM();
        if (requestedTarget != null) {
            String actualTarget = CompilerOptions.versionFromJdkLevel(cOptions.targetJDK);
            if (!requestedTarget.equals(actualTarget)) {
                log.warn(Localizer.getMessage("jsp.warning.unsupported.targetVM", requestedTarget, actualTarget));
            }
        }

        cOptions.parseLiteralExpressionsAsConstants = true;
        Compiler compiler = new Compiler(env, policy, cOptions, requestor, problemFactory);
        compiler.compile(compilationUnits);

        if (!ctxt.keepGenerated()) {
            File javaFile = new File(ctxt.getServletJavaFileName());
            if (!javaFile.delete()) {
                throw new JasperException(Localizer.getMessage("jsp.warning.compiler.javafile.delete.fail", javaFile));
            }
        }

        if (!problemList.isEmpty()) {
            JavacErrorDetail[] jeds = problemList.toArray(new JavacErrorDetail[0]);
            errDispatcher.javacError(jeds);
        }

        if (log.isDebugEnabled()) {
            long t2 = System.currentTimeMillis();
            log.debug(Localizer.getMessage("jsp.compiled", ctxt.getServletJavaFileName(), Long.valueOf(t2 - t1)));
        }

        if (ctxt.isPrototypeMode()) {
            return;
        }

        // JSR45 Support
        if (!options.isSmapSuppressed()) {
            SmapUtil.installSmap(smaps);
        }
    }
}
