/*
 * Copyright (c) 2012, 2013, 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 8003280
 * @summary Add lambda tests
 *  Check that self/forward references from lambda expressions behave
 *          consistently w.r.t. local inner classes
 */

import java.net.URI;
import java.util.Arrays;
import javax.tools.Diagnostic;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import com.sun.source.util.JavacTask;

public class TestSelfRef {

    static int checkCount = 0;

    enum RefKind {
        SELF_LAMBDA("SAM s = x->{ System.out.println(s); };", true, false),
        FORWARD_LAMBDA("SAM s = x->{ System.out.println(f); };\nObject f = null;", false, true),
        SELF_ANON("Object s = new Object() { void test() { System.out.println(s); } };", true, false),
        FORWARD_ANON("Object s = new Object() { void test() { System.out.println(f); } }; Object f = null;", false, true);

        String refStr;
        boolean selfRef;
        boolean forwardRef;

        private RefKind(String refStr, boolean selfRef, boolean forwardRef) {
            this.refStr = refStr;
            this.selfRef = selfRef;
            this.forwardRef = forwardRef;
        }
    }

    enum EnclosingKind {
        TOPLEVEL("class C { #S }"),
        MEMBER_INNER("class Outer { class C { #S } }"),
        NESTED_INNER("class Outer { static class C { #S } }");

        String enclStr;

        private EnclosingKind(String enclStr) {
            this.enclStr = enclStr;
        }
    }

    enum InnerKind {
        NONE("#R"),
        LOCAL_NONE("class Local { #R }"),
        LOCAL_MTH("class Local { void test() { #R } }"),
        ANON_NONE("new Object() { #R };"),
        ANON_MTH("new Object() { void test() { #R } };");

        String innerStr;

        private InnerKind(String innerStr) {
            this.innerStr = innerStr;
        }

        boolean inMethodContext(SiteKind sk) {
            switch (this) {
                case LOCAL_MTH:
                case ANON_MTH: return true;
                case NONE: return sk != SiteKind.NONE;
                default:
                    return false;
            }
        }
    }

    enum SiteKind {
        NONE("#I"),
        STATIC_INIT("static { #I }"),
        INSTANCE_INIT("{ #I }"),
        CONSTRUCTOR("C() { #I }"),
        METHOD("void test() { #I }");

        String siteStr;

        private SiteKind(String siteStr) {
            this.siteStr = siteStr;
        }
    }

    public static void main(String... args) throws Exception {

        //create default shared JavaCompiler - reused across multiple compilations
        JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
        StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);

        for (EnclosingKind ek : EnclosingKind.values()) {
            for (SiteKind sk : SiteKind.values()) {
                if (sk == SiteKind.STATIC_INIT && ek == EnclosingKind.MEMBER_INNER)
                    continue;
                for (InnerKind ik : InnerKind.values()) {
                    if (ik != InnerKind.NONE && sk == SiteKind.NONE)
                        break;
                    for (RefKind rk : RefKind.values()) {
                        new TestSelfRef(ek, sk, ik, rk).run(comp, fm);
                    }
                }
            }
        }
        System.out.println("Total check executed: " + checkCount);
    }

    EnclosingKind ek;
    SiteKind sk;
    InnerKind ik;
    RefKind rk;
    JavaSource source;
    DiagnosticChecker diagChecker;

    TestSelfRef(EnclosingKind ek, SiteKind sk, InnerKind ik, RefKind rk) {
        this.ek = ek;
        this.sk = sk;
        this.ik = ik;
        this.rk = rk;
        this.source = new JavaSource();
        this.diagChecker = new DiagnosticChecker();
    }

    class JavaSource extends SimpleJavaFileObject {

        String bodyTemplate = "interface SAM { void test(Object o); }\n#B";
        String source;

        public JavaSource() {
            super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
            source = bodyTemplate.replace("#B",
                    ek.enclStr.replace("#S", sk.siteStr.replace("#I", ik.innerStr.replace("#R", rk.refStr))));
        }

        @Override
        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
            return source;
        }
    }

    void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
        JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
                null, null, Arrays.asList(source));
        try {
            ct.analyze();
        } catch (Throwable ex) {
            throw new AssertionError("Error thron when compiling the following code:\n" + source.getCharContent(true));
        }
        check();
    }

    boolean isErrorExpected() {
        //illegal forward ref
        boolean result = ik.inMethodContext(sk) && (rk.selfRef || rk.forwardRef);
        result |= (rk == RefKind.SELF_LAMBDA || rk == RefKind.FORWARD_LAMBDA);
        return result;
    }

    void check() {
        checkCount++;
        boolean errorExpected = isErrorExpected();
        if (diagChecker.errorFound != errorExpected) {
            throw new Error("invalid diagnostics for source:\n" +
                source.getCharContent(true) +
                "\nFound error: " + diagChecker.errorFound +
                "\nExpected error: " + errorExpected);
        }
    }

    static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {

        boolean errorFound;

        public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
            if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
                errorFound = true;
            }
        }
    }
}
