/*
 * Copyright (c) 2022, 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 8291769
 * @summary Check expected translation of various pattern related constructs
 * @library /tools/lib
 * @modules jdk.compiler/com.sun.tools.javac.api
 *          jdk.compiler/com.sun.tools.javac.comp
 *          jdk.compiler/com.sun.tools.javac.main
 *          jdk.compiler/com.sun.tools.javac.tree
 *          jdk.compiler/com.sun.tools.javac.util
 * @build toolbox.ToolBox toolbox.JavacTask
 * @run main TranslationTest
*/

import com.sun.tools.javac.api.JavacTaskImpl;
import com.sun.tools.javac.comp.AttrContext;
import com.sun.tools.javac.comp.Env;
import com.sun.tools.javac.comp.TransPatterns;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCCase;
import com.sun.tools.javac.tree.JCTree.JCSwitch;
import com.sun.tools.javac.tree.JCTree.JCSwitchExpression;
import com.sun.tools.javac.tree.JCTree.Tag;
import com.sun.tools.javac.tree.TreeMaker;
import com.sun.tools.javac.tree.TreeScanner;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Context.Factory;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

import toolbox.TestRunner;
import toolbox.JavacTask;
import toolbox.Task;
import toolbox.ToolBox;

public class TranslationTest extends TestRunner {

    ToolBox tb;

    public static void main(String... args) throws Exception {
        new TranslationTest().runTests();
    }

    TranslationTest() {
        super(System.err);
        tb = new ToolBox();
    }

    public void runTests() throws Exception {
        runTests(m -> new Object[] { Paths.get(m.getName()) });
    }

    @Test
    public void testSimple(Path base) throws Exception {
        doTest(base,
               new String[]{"""
                            package lib;
                            public record Box(Object o) {}
                            """},
               """
               package test;
               import lib.*;
               public class Test {
                   private int test(Object obj) {
                       return switch (obj) {
                           case Box(String s) -> 0;
                           case Box(Integer i) -> 0;
                           case Box(Number n) -> 0;
                           case Box(CharSequence cs) -> 0;

                           default -> -1;
                       };
                   }
               }
               """,
               toplevel -> printSwitchStructure(toplevel),
               """
               switch
                   case
                       switch
                           case
                           case
                           case
                           case
                           case ..., default
                   default
               """);
    }

    @Test
    public void testMultiComponent(Path base) throws Exception {
        doTest(base,
               new String[]{"""
                            package lib;
                            public record Pair(Object o1, Object o2) {}
                            """,
                            """
                            package lib;
                            public record Triplet(Object o1, Object o2, Object o3) {}
                            """},
               """
               package test;
               import lib.*;
               public class Test {
                   private int test(Object obj) {
                       return switch (obj) {
                           case Pair(String c1, Pair(String o2, String s2)) -> 0;
                           case Pair(String c1, Pair(String o2, Integer s2)) -> 0;
                           case Pair(String c1, Pair(Integer o2, String s2)) -> 0;
                           case Pair(String c1, Pair(Integer o2, Integer s2)) -> 0;

                           case Pair(Integer c1, Pair(String o2, String s2)) -> 0;
                           case Pair(Integer c1, Pair(String o2, Integer s2)) -> 0;
                           case Pair(Integer c1, Pair(Integer o2, String s2)) -> 0;
                           case Pair(Integer c1, Pair(Integer o2, Integer s2)) -> 0;

                           default -> -1;
                       };
                   }
               }
               """,
               toplevel -> printSwitchStructure(toplevel),
               """
               switch
                   case
                       switch
                           case
                               switch
                                   case
                                       switch
                                           case
                                               switch
                                                   case
                                                   case
                                                   case ..., default
                                           case
                                               switch
                                                   case
                                                   case
                                                   case ..., default
                                           case ..., default
                                   case ..., default
                           case
                               switch
                                   case
                                       switch
                                           case
                                               switch
                                                   case
                                                   case
                                                   case ..., default
                                           case
                                               switch
                                                   case
                                                   case
                                                   case ..., default
                                           case ..., default
                                   case ..., default
                           case ..., default
                   default
               """);
    }

    private void doTest(Path base, String[] libraryCode, String testCode,
                        Callback callback, String expectedOutput) throws IOException {
        Path current = base.resolve(".");
        Path libClasses = current.resolve("libClasses");

        Files.createDirectories(libClasses);

        if (libraryCode.length != 0) {
            Path libSrc = current.resolve("lib-src");

            for (String code : libraryCode) {
                tb.writeJavaFiles(libSrc, code);
            }

            new JavacTask(tb)
                    .outdir(libClasses)
                    .files(tb.findJavaFiles(libSrc))
                    .run();
        }

        Path src = current.resolve("src");
        tb.writeJavaFiles(src, testCode);

        Path classes = current.resolve("libClasses");

        Files.createDirectories(libClasses);

        List<String> output = new ArrayList<>();

        new JavacTask(tb)
            .options("-Xlint:-preview",
                     "--class-path", libClasses.toString(),
                     "-XDshould-stop.at=FLOW")
            .outdir(classes)
            .files(tb.findJavaFiles(src))
            .callback(task -> {
                 Context ctx = ((JavacTaskImpl) task).getContext();

                 TestTransPatterns.preRegister(ctx, callback, output);
             })
            .run()
            .writeAll()
            .getOutputLines(Task.OutputKind.DIRECT);

        if (output.size() != 1 || !expectedOutput.equals(output.get(0))) {
            throw new AssertionError("Unexpected output:\n" + output);
        }
    }

    private String printSwitchStructure(JCTree topLevel) {
        StringBuilder structure = new StringBuilder();

        new TreeScanner() {
            private static final int INDENT = 4;
            private int indent = 0;
            @Override
            public void visitSwitch(JCSwitch node) {
                int prevIndent = indent;
                appendLine("switch");
                try {
                    indent += INDENT;
                    super.visitSwitch(node);
                } finally {
                    indent = prevIndent;
                }
            }

            @Override
            public void visitSwitchExpression(JCSwitchExpression node) {
                int prevIndent = indent;
                appendLine("switch");
                try {
                    indent += INDENT;
                    super.visitSwitchExpression(node);
                } finally {
                    indent = prevIndent;
                }
            }
            @Override
            public void visitCase(JCCase node) {
                int prevIndent = indent;
                if (node.labels.size() == 1 && node.labels.head.hasTag(Tag.DEFAULTCASELABEL)) {
                    appendLine("default");
                } else if (node.labels.stream().anyMatch(l -> l.hasTag(Tag.DEFAULTCASELABEL))) {
                    appendLine("case ..., default");
                } else {
                    appendLine("case");
                }
                try {
                    indent += INDENT;
                    super.visitCase(node);
                } finally {
                    indent = prevIndent;
                }
            }
            private void appendLine(String what) {
                for (int i = 0; i < indent; i++) {
                    structure.append(' ');
                }
                structure.append(what);
                structure.append('\n');
            }
        }.scan(topLevel);

        return structure.toString();
    }

    public interface Callback {
        public String patternsTranslated(JCTree topLevel);
    }

    private static final class TestTransPatterns extends TransPatterns {

        public static void preRegister(Context ctx, Callback validator, List<String> output) {
            ctx.put(transPatternsKey, (Factory<TransPatterns>) c -> new TestTransPatterns(c, validator, output));
        }

        private final Callback callback;
        private final List<String> output;

        public TestTransPatterns(Context context, Callback callback, List<String> output) {
            super(context);
            this.callback = callback;
            this.output = output;
        }

        @Override
        public JCTree translateTopLevelClass(Env<AttrContext> env, JCTree cdef, TreeMaker make) {
            JCTree result = super.translateTopLevelClass(env, cdef, make);
            output.add(callback.patternsTranslated(cdef));
            return result;
        }

    }
}
