/*
 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/*
 * @test
 * @bug 6930507
 * @summary Symbols for anonymous and local classes made too late for use by java tree API
 */

import java.io.*;
import java.util.*;
import javax.annotation.processing.*;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.*;
import javax.tools.Diagnostic;
import static javax.lang.model.util.ElementFilter.*;

import com.sun.source.tree.*;
import com.sun.source.util.*;

@SupportedOptions({"test", "last"})
@SupportedAnnotationTypes("*")
public class TestGetElement extends AbstractProcessor {
    public static void main(String... args) throws Exception {
        new TestGetElement().run();
    }

    public TestGetElement() { }

    public void run() throws Exception {
        final String testSrc = System.getProperty("test.src");
        final String testClasses = System.getProperty("test.classes");
        final String myClassName = getClass().getName();
        final String mySrc = new File(testSrc, myClassName + ".java").getPath();

        final int NUM_TESTS = 90; // #decls in this source file
        for (int i = 1; i <= NUM_TESTS; i++) {
            System.err.println("test " + i);
            File testDir = new File("test" + i);
            File classesDir = new File(testDir, "classes");
            classesDir.mkdirs();
            String[] args = {
                "-d", classesDir.getPath(),
                "-processorpath", testClasses,
                "-processor", myClassName,
                "-proc:only",
                "-Atest=" + i,
                "-Alast=" + (i == NUM_TESTS),
                mySrc
            };

//            System.err.println("compile: " + Arrays.asList(args));

            StringWriter sw = new StringWriter();
            PrintWriter pw = new PrintWriter(sw);
            int rc = com.sun.tools.javac.Main.compile(args, pw);
            pw.close();
            String out = sw.toString();
            if (out != null)
                System.err.println(out);
            if (rc != 0) {
                System.err.println("compilation failed: rc=" + rc);
                errors++;
            }
        }

        if (errors > 0)
            throw new Exception(errors + " errors occurred");
    }


    int errors;

    public boolean process(Set<? extends TypeElement> annotations,
                           RoundEnvironment roundEnvironment)
    {
        if (roundEnvironment.processingOver())
            return true;

        Map<String,String> options = processingEnv.getOptions();
        int test = Integer.parseInt(options.get("test"));
        boolean _last = Boolean.parseBoolean(options.get("last"));

        Trees trees = Trees.instance(processingEnv);
        Scanner scanner = new Scanner(trees, _last);
        int nelems = 0;
        for (TypeElement e : typesIn(roundEnvironment.getRootElements())) {
            nelems += scanner.scan(trees.getPath(e), test);
        }

        Messager m = processingEnv.getMessager();
        int EXPECT = 1;
        if (nelems != EXPECT) {
            m.printMessage(Diagnostic.Kind.ERROR,
                    "Unexpected number of elements found: " + nelems + " expected: " + EXPECT);
        }
        return true;
    }

    @Override
    public SourceVersion getSupportedSourceVersion() {
        return SourceVersion.latest();
    }

    class Scanner extends TreePathScanner<Integer,Integer> {
        final Trees trees;
        final boolean last;
        int count;

        Scanner(Trees trees, boolean last) {
            this.trees = trees;
            this.last = last;
        }

        @Override
        public Integer visitClass(ClassTree tree, Integer test) {
            return reduce(check(test), super.visitClass(tree, test));
        }

        @Override
        public Integer visitMethod(MethodTree tree, Integer test) {
            return reduce(check(test), super.visitMethod(tree, test));
        }

        @Override
        public Integer visitVariable(VariableTree tree, Integer test) {
            return reduce(check(test), super.visitVariable(tree, test));
        }

        @Override
        public Integer reduce(Integer i1, Integer i2) {
            if (i1 == null || i1.intValue() == 0)
                return i2;
            if (i2 == null || i2.intValue() == 0)
                return i1;
            return (i1 + i2);
        }

        int check(int test) {
            count++;

            if (count != test)
                return 0;

            TreePath p = getCurrentPath();
            Element e = trees.getElement(p);

            String text = p.getLeaf().toString().replaceAll("\\s+", " ").trim();
            int MAXLEN = 40;
            if (text.length() > MAXLEN)
                text = text.substring(0, MAXLEN - 3) + "...";

            System.err.println(String.format("%3d: %-" + MAXLEN + "s -- %s",
                    count, text,
                    (e == null ? "null" : e.getKind() + " " + e)));

            Messager m = processingEnv.getMessager();
            if (e == null) {
                m.printMessage(Diagnostic.Kind.ERROR, "Null element found for " + text);
                return 0;
            }

            if (last && !e.getSimpleName().contentEquals("last")) {
                m.printMessage(Diagnostic.Kind.ERROR, "Unexpected name in last test: "
                        + e.getSimpleName() + ", expected: last");
            }

            return 1;
        }
    }

    // following are all fodder for the test

    class MemberClass {
        class NestedMemberClass { }
    }

    {
        class InnerClassInInit { }
        Object o = new Object() { };
    }

    TestGetElement(TestGetElement unused) {
        class InnerClassInConstr { }
        Object o = new Object() { };
    }

    void m() {
        class InnerClassInMethod { }
        Object o = new Object() { };

        class C {
            class MemberClass {
                class NestedMemberClass { }
            }

            {
                class InnerClassInInit { }
                Object o = new Object() { };
            }

            C(Object unused) {
                class InnerClassInConstr { }
                Object o = new Object() { };
            }

            void m() {
                class InnerClassInMethod { }
                Object o = new Object() { };
            }
        }
    }

    int last; // this name is verified by the test to make sure that all decls are checked
}
