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

import org.mozilla.gecko.annotationProcessors.AnnotationInfo;
import org.mozilla.gecko.annotationProcessors.classloader.AnnotatableEntity;
import org.mozilla.gecko.annotationProcessors.classloader.ClassWithOptions;

import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Iterator;

/**
 * Iterator over the methods in a given method list which have the WrappedJNIMethod
 * annotation. Returns an object containing both the annotation (Which may contain interesting
 * parameters) and the argument.
 */
public class GeneratableElementIterator implements Iterator<AnnotatableEntity> {
    private final ClassWithOptions mClass;
    private final Member[] mObjects;
    private AnnotatableEntity mNextReturnValue;
    private int mElementIndex;

    private boolean mIterateEveryEntry;

    public GeneratableElementIterator(ClassWithOptions annotatedClass) {
        mClass = annotatedClass;

        final Class<?> aClass = annotatedClass.wrappedClass;
        // Get all the elements of this class as AccessibleObjects.
        Member[] aMethods = aClass.getDeclaredMethods();
        Member[] aFields = aClass.getDeclaredFields();
        Member[] aCtors = aClass.getDeclaredConstructors();

        // Shove them all into one buffer.
        Member[] objs = new Member[aMethods.length + aFields.length + aCtors.length];

        int offset = 0;
        System.arraycopy(aMethods, 0, objs, 0, aMethods.length);
        offset += aMethods.length;
        System.arraycopy(aFields, 0, objs, offset, aFields.length);
        offset += aFields.length;
        System.arraycopy(aCtors, 0, objs, offset, aCtors.length);

        // Sort the elements to ensure determinism.
        Arrays.sort(objs, new AlphabeticAnnotatableEntityComparator<Member>());
        mObjects = objs;

        // Check for "Wrap ALL the things" flag.
        for (Annotation annotation : aClass.getDeclaredAnnotations()) {
            final String annotationTypeName = annotation.annotationType().getName();
            if (annotationTypeName.equals("org.mozilla.gecko.annotation.WrapForJNI")) {
                mIterateEveryEntry = true;
                break;
            }
        }

        findNextValue();
    }

    private Class<?>[] getFilteredInnerClasses() {
        // Go through all inner classes and see which ones we want to generate.
        final Class<?>[] candidates = mClass.wrappedClass.getDeclaredClasses();
        int count = 0;

        for (int i = 0; i < candidates.length; ++i) {
            final GeneratableElementIterator testIterator
                    = new GeneratableElementIterator(new ClassWithOptions(candidates[i], null));
            if (testIterator.hasNext()
                    || testIterator.getFilteredInnerClasses() != null) {
                count++;
                continue;
            }
            // Clear out ones that don't match.
            candidates[i] = null;
        }
        return count > 0 ? candidates : null;
    }

    public ClassWithOptions[] getInnerClasses() {
        final Class<?>[] candidates = getFilteredInnerClasses();
        if (candidates == null) {
            return new ClassWithOptions[0];
        }

        int count = 0;
        for (Class<?> candidate : candidates) {
            if (candidate != null) {
                count++;
            }
        }

        final ClassWithOptions[] ret = new ClassWithOptions[count];
        count = 0;
        for (Class<?> candidate : candidates) {
            if (candidate != null) {
                ret[count++] = new ClassWithOptions(
                        candidate, mClass.generatedName + "::" + candidate.getSimpleName());
            }
        }
        assert ret.length == count;

        Arrays.sort(ret, new Comparator<ClassWithOptions>() {
            @Override public int compare(ClassWithOptions lhs, ClassWithOptions rhs) {
                return lhs.generatedName.compareTo(rhs.generatedName);
            }
        });
        return ret;
    }

    /**
     * Find and cache the next appropriately annotated method, plus the annotation parameter, if
     * one exists. Otherwise cache null, so hasNext returns false.
     */
    private void findNextValue() {
        while (mElementIndex < mObjects.length) {
            Member candidateElement = mObjects[mElementIndex];
            mElementIndex++;
            for (Annotation annotation : ((AnnotatedElement) candidateElement).getDeclaredAnnotations()) {
                // WrappedJNIMethod has parameters. Use Reflection to obtain them.
                Class<? extends Annotation> annotationType = annotation.annotationType();
                final String annotationTypeName = annotationType.getName();
                if (annotationTypeName.equals("org.mozilla.gecko.annotation.WrapForJNI")) {
                    String stubName = null;
                    boolean isMultithreadedStub = false;
                    boolean noThrow = false;
                    boolean narrowChars = false;
                    boolean catchException = false;
                    try {
                        // Determine the explicitly-given name of the stub to generate, if any.
                        final Method stubNameMethod = annotationType.getDeclaredMethod("stubName");
                        stubNameMethod.setAccessible(true);
                        stubName = (String) stubNameMethod.invoke(annotation);

                        // Determine if the generated stub is to allow calls from multiple threads.
                        final Method multithreadedStubMethod = annotationType.getDeclaredMethod("allowMultithread");
                        multithreadedStubMethod.setAccessible(true);
                        isMultithreadedStub = (Boolean) multithreadedStubMethod.invoke(annotation);

                        // Determine if ignoring exceptions
                        final Method noThrowMethod = annotationType.getDeclaredMethod("noThrow");
                        noThrowMethod.setAccessible(true);
                        noThrow = (Boolean) noThrowMethod.invoke(annotation);

                        // Determine if strings should be wide or narrow
                        final Method narrowCharsMethod = annotationType.getDeclaredMethod("narrowChars");
                        narrowCharsMethod.setAccessible(true);
                        narrowChars = (Boolean) narrowCharsMethod.invoke(annotation);

                        // Determine if we should catch exceptions
                        final Method catchExceptionMethod = annotationType.getDeclaredMethod("catchException");
                        catchExceptionMethod.setAccessible(true);
                        catchException = (Boolean) catchExceptionMethod.invoke(annotation);

                    } catch (NoSuchMethodException e) {
                        System.err.println("Unable to find expected field on WrapForJNI annotation. Did the signature change?");
                        e.printStackTrace(System.err);
                        System.exit(3);
                    } catch (IllegalAccessException e) {
                        System.err.println("IllegalAccessException reading fields on WrapForJNI annotation. Seems the semantics of Reflection have changed...");
                        e.printStackTrace(System.err);
                        System.exit(4);
                    } catch (InvocationTargetException e) {
                        System.err.println("InvocationTargetException reading fields on WrapForJNI annotation. This really shouldn't happen.");
                        e.printStackTrace(System.err);
                        System.exit(5);
                    }

                    // If the method name was not explicitly given in the annotation generate one...
                    if (stubName.isEmpty()) {
                        stubName = Utils.getNativeName(candidateElement);
                    }

                    AnnotationInfo annotationInfo = new AnnotationInfo(
                        stubName, isMultithreadedStub, noThrow, narrowChars, catchException);
                    mNextReturnValue = new AnnotatableEntity(candidateElement, annotationInfo);
                    return;
                }
            }

            // If no annotation found, we might be expected to generate anyway
            // using default arguments, thanks to the "Generate everything" annotation.
            if (mIterateEveryEntry) {
                AnnotationInfo annotationInfo = new AnnotationInfo(
                    Utils.getNativeName(candidateElement),
                    /* multithreaded */ true,
                    /* noThrow */ false,
                    /* narrowChars */ false,
                    /* catchException */ false);
                mNextReturnValue = new AnnotatableEntity(candidateElement, annotationInfo);
                return;
            }
        }
        mNextReturnValue = null;
    }

    @Override
    public boolean hasNext() {
        return mNextReturnValue != null;
    }

    @Override
    public AnnotatableEntity next() {
        AnnotatableEntity ret = mNextReturnValue;
        findNextValue();
        return ret;
    }

    @Override
    public void remove() {
        throw new UnsupportedOperationException("Removal of methods from GeneratableElementIterator not supported.");
    }
}
