/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

package org.mozilla.gecko.annotationProcessors;

import org.mozilla.gecko.annotationProcessors.classloader.AnnotatableEntity;
import org.mozilla.gecko.annotationProcessors.classloader.ClassWithOptions;
import org.mozilla.gecko.annotationProcessors.classloader.IterableJarLoadingURLClassLoader;
import org.mozilla.gecko.annotationProcessors.utils.GeneratableElementIterator;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.Iterator;

public class AnnotationProcessor {
    public static final String SOURCE_FILE = "GeneratedJNIWrappers.cpp";
    public static final String HEADER_FILE = "GeneratedJNIWrappers.h";
    public static final String NATIVES_FILE = "GeneratedJNINatives.h";

    public static final String GENERATED_COMMENT =
            "// GENERATED CODE\n" +
            "// Generated by the Java program at /build/annotationProcessors at compile time\n" +
            "// from annotations on Java methods. To update, change the annotations on the\n" +
            "// corresponding Java methods and rerun the build. Manually updating this file\n" +
            "// will cause your build to fail.\n" +
            "\n";

    private static final StringBuilder headerFile = new StringBuilder(GENERATED_COMMENT);
    private static final StringBuilder implementationFile = new StringBuilder(GENERATED_COMMENT);
    private static final StringBuilder nativesFile = new StringBuilder(GENERATED_COMMENT);

    public static void main(String[] args) {
        // We expect a list of jars on the commandline. If missing, whinge about it.
        if (args.length <= 1) {
            System.err.println("Usage: java AnnotationProcessor jarfiles ...");
            System.exit(1);
        }

        System.out.println("Processing annotations...");

        // We want to produce the same output as last time as often as possible. Ordering of
        // generated statements, therefore, needs to be consistent.
        Arrays.sort(args);

        // Start the clock!
        long s = System.currentTimeMillis();

        // Get an iterator over the classes in the jar files given...
        Iterator<ClassWithOptions> jarClassIterator = IterableJarLoadingURLClassLoader.getIteratorOverJars(args);

        headerFile.append(
                "#ifndef " + getHeaderGuardName(HEADER_FILE) + "\n" +
                "#define " + getHeaderGuardName(HEADER_FILE) + "\n" +
                "\n" +
                "#include \"mozilla/jni/Refs.h\"\n" +
                "\n" +
                "namespace mozilla {\n" +
                "namespace widget {\n" +
                "\n");

        implementationFile.append(
                "#include \"GeneratedJNIWrappers.h\"\n" +
                "#include \"mozilla/jni/Accessors.h\"\n" +
                "\n" +
                "namespace mozilla {\n" +
                "namespace widget {\n" +
                "\n");

        nativesFile.append(
                "#ifndef " + getHeaderGuardName(NATIVES_FILE) + "\n" +
                "#define " + getHeaderGuardName(NATIVES_FILE) + "\n" +
                "\n" +
                "#include \"GeneratedJNIWrappers.h\"\n" +
                "#include \"mozilla/jni/Natives.h\"\n" +
                "\n" +
                "namespace mozilla {\n" +
                "namespace widget {\n" +
                "\n");

        while (jarClassIterator.hasNext()) {
            generateClass(jarClassIterator.next());
        }

        implementationFile.append(
                "} /* widget */\n" +
                "} /* mozilla */\n");

        headerFile.append(
                "} /* widget */\n" +
                "} /* mozilla */\n" +
                "#endif // " + getHeaderGuardName(HEADER_FILE) + "\n");

        nativesFile.append(
                "} /* widget */\n" +
                "} /* mozilla */\n" +
                "#endif // " + getHeaderGuardName(NATIVES_FILE) + "\n");

        writeOutputFile(SOURCE_FILE, implementationFile);
        writeOutputFile(HEADER_FILE, headerFile);
        writeOutputFile(NATIVES_FILE, nativesFile);

        long e = System.currentTimeMillis();
        System.out.println("Annotation processing complete in " + (e - s) + "ms");
    }

    private static void generateClass(final ClassWithOptions annotatedClass) {
        // Get an iterator over the appropriately generated methods of this class
        final GeneratableElementIterator methodIterator
                = new GeneratableElementIterator(annotatedClass);
        final ClassWithOptions[] innerClasses = methodIterator.getInnerClasses();

        if (!methodIterator.hasNext() && innerClasses.length == 0) {
            return;
        }

        final CodeGenerator generatorInstance = new CodeGenerator(annotatedClass);
        generatorInstance.generateClasses(innerClasses);

        // Iterate all annotated members in this class..
        while (methodIterator.hasNext()) {
            AnnotatableEntity aElementTuple = methodIterator.next();
            switch (aElementTuple.mEntityType) {
                case METHOD:
                    generatorInstance.generateMethod(aElementTuple);
                    break;
                case NATIVE:
                    generatorInstance.generateNative(aElementTuple);
                    break;
                case FIELD:
                    generatorInstance.generateField(aElementTuple);
                    break;
                case CONSTRUCTOR:
                    generatorInstance.generateConstructor(aElementTuple);
                    break;
            }
        }

        headerFile.append(generatorInstance.getHeaderFileContents());
        implementationFile.append(generatorInstance.getWrapperFileContents());
        nativesFile.append(generatorInstance.getNativesFileContents());

        for (ClassWithOptions innerClass : innerClasses) {
            generateClass(innerClass);
        }
    }

    private static String getHeaderGuardName(final String name) {
        return name.replaceAll("\\W", "_");
    }

    private static void writeOutputFile(final String name,
                                        final StringBuilder content) {
        FileOutputStream outStream = null;
        try {
            outStream = new FileOutputStream(name);
            outStream.write(content.toString().getBytes());
        } catch (IOException e) {
            System.err.println("Unable to write " + name + ". Perhaps a permissions issue?");
            e.printStackTrace(System.err);
        } finally {
            if (outStream != null) {
                try {
                    outStream.close();
                } catch (IOException e) {
                    System.err.println("Unable to close outStream due to "+e);
                    e.printStackTrace(System.err);
                }
            }
        }
    }
}
