/*
 * Copyright (c) 2015, 2023, 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.
 */

import java.lang.StackWalker.StackFrame;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.logging.Logger;
import java.util.stream.Collectors;

import static java.lang.StackWalker.Option.*;

/**
 * @test
 * @bug 8140450 8210375
 * @summary Stack Stream Test
 * @modules java.logging
 * @run main/othervm StackStreamTest
 */
public class StackStreamTest {
    public static void main(String[] argv) throws Exception {
        new StackStreamTest().test();
    }

    private static Logger logger = Logger.getLogger("stackstream");
    public StackStreamTest() {
    }

    public void test() {
        A.a();
    }
    static class A {
        public static void a() {
            B.b();
        }
    }
    static class B {
        public static void b() {
            C.c();
        }
    }
    static class C {
        public static void c() {
            D.d();
        }
    }
    static class D {
        public static void d() {
            E.e();
        }
    }
    static class E {
        public static void e() {
            F.f();
        }
    }
    static class F {
        public static void f() {
            logger.severe("log message");
            G.g();
            new K().k();
        }
    }

    private static boolean isTestClass(StackFrame f) {
        // Filter jtreg frames from the end of the stack
        return f.getClassName().startsWith("StackStreamTest");
    }

    static class G {
        static StackWalker STE_WALKER = StackWalker.getInstance();
        static StackWalker DEFAULT_WALKER = StackWalker.getInstance();

        private static final List<String> GOLDEN_CLASS_NAMES =
                Arrays.asList("StackStreamTest$G",
                              "StackStreamTest$F",
                              "StackStreamTest$E",
                              "StackStreamTest$D",
                              "StackStreamTest$C",
                              "StackStreamTest$B",
                              "StackStreamTest$A",
                              "StackStreamTest",
                              "StackStreamTest");
        private static final List<String> GOLDEN_METHOD_NAMES =
            Arrays.asList("g", "f", "e", "d", "c", "b", "a", "test", "main");


        public static void g() {

            System.out.println("Thread dump");
            Thread.dumpStack();

            caller();
            firstFrame();

            // Check class names
            System.out.println("check class names");
            List<String> sfs = DEFAULT_WALKER.walk(s -> {
                return s.filter(StackStreamTest::isTestClass)
                        .map(StackFrame::getClassName)
                        .collect(Collectors.toList());
            });
            equalsOrThrow("class names", sfs, GOLDEN_CLASS_NAMES);

            // Check method names
            System.out.println("methodNames()");
            sfs = DEFAULT_WALKER.walk(s -> {
                return s.filter(StackStreamTest::isTestClass)
                        .map(StackFrame::getMethodName)
                        .collect(Collectors.toList());}
            );
            equalsOrThrow("method names", sfs, GOLDEN_METHOD_NAMES);

            Exception exc = new Exception("G.g stack");
            exc.printStackTrace();

            System.out.println("Stream of StackTraceElement");
            StackWalker.getInstance()
                .walk(s ->
                {
                    s.map(StackFrame::toStackTraceElement)
                            .forEach(ste -> System.out.println("STE: " + ste));
                    return null;
                });

            // Do we need this?
            System.out.println("Collect StackTraceElement");
            List<StackTraceElement> stacktrace = STE_WALKER.walk(s ->
            {
                // Filter out jtreg frames
                return s.filter(StackStreamTest::isTestClass)
                        .collect(Collectors.mapping(StackFrame::toStackTraceElement, Collectors.toList()));
            });
            int i=0;
            for (StackTraceElement s : stacktrace) {
                System.out.format("  %d: %s%n", i++, s);
            }

            // Check STEs for correctness
            checkStackTraceElements(GOLDEN_CLASS_NAMES, GOLDEN_METHOD_NAMES, stacktrace);

            System.out.println("Collect classes");
            List<Class<?>> classes = StackWalker.getInstance(Set.of(DROP_METHOD_INFO, RETAIN_CLASS_REFERENCE))
                    .walk(s -> {
                        return s.map(StackFrame::getDeclaringClass).collect(Collectors.toList());
                    });
            for (i=0; i < GOLDEN_CLASS_NAMES.size(); i++) {
                Class<?> c = classes.get(i);
                if (!GOLDEN_CLASS_NAMES.get(i).equals(c.getName())) {
                    throw new RuntimeException("unexpected class at " + i + " " + c.getName() +
                            " expected " + GOLDEN_CLASS_NAMES.get(i));
                }
            }
        }

        static void checkStackTraceElements(List<String> classNames,
                                            List<String> methodNames,
                                            List<StackTraceElement> stes) {
            if (classNames.size() != methodNames.size() ) {
                throw new RuntimeException("Test error: classNames and methodNames should be same size");
            }
            if (classNames.size() != stes.size()) {
                dumpSTEInfo(classNames, methodNames, stes);
                throw new RuntimeException("wrong number of elements in stes");
            }
            for (int i = 0; i < classNames.size() ; i++) {
                if (!classNames.get(i).equals(stes.get(i).getClassName()) ||
                    !methodNames.get(i).equals(stes.get(i).getMethodName())) {
                    dumpSTEInfo(classNames, methodNames, stes);
                    throw new RuntimeException("class & method names don't match");
                }
            }
        }

        static void dumpSTEInfo(List<String> classNames, List<String> methodNames,
                                List<StackTraceElement> stes) {
            System.out.println("Observed class, method names:");
            for (StackTraceElement ste : stes) {
                System.out.println("  " + ste.getClassName() + ", " + ste.getMethodName());
            }
            System.out.println("Expected class, method names:");
            for (int i = 0; i < classNames.size(); i++) {
                System.out.println("  " + classNames.get(i) + ", " + methodNames.get(i));
            }
        }

        static void firstFrame() {
            System.out.println("first frame()");
            StackWalker sw = StackWalker.getInstance(RETAIN_CLASS_REFERENCE);
            sw.forEach(e -> {
                System.out.println(e.getClassName() + "," + e.getMethodName());
            });
            System.out.println("\n");
            Optional<StackFrame> frame = sw.walk(s ->
            {
                 return s.filter(e -> {
                            System.err.println(e.getClassName() + " == " +
                                               e.getClassName().equals("StackStreamTest"));
                            return e.getClassName().equals("StackStreamTest");
                        }).findFirst();
            });
            Class<?> c = frame.get().getDeclaringClass();
            System.out.println("\nfirst frame: " + c);
            if (c != StackStreamTest.class) {
                throw new RuntimeException("Unexpected first caller class " + c);
            }
        }
    }

    private static <T> void equalsOrThrow(String label, List<T> list, List<T> expected) {
        System.out.println("List:     " + list);
        System.out.println("Expected: " + expected);
        if (!list.equals(expected)) {
            System.err.println("Observed " + label);
            for (T s1 : list) {
                System.out.println("  " + s1);
            }
            System.err.println("Expected " + label);
            for (T s2 : expected) {
                System.out.println("  " + s2);
            }
            throw new RuntimeException("Error with " + label);
        }
    }


    static class K {
        void k() {
            k1();
        }
        void k1() {
            k2();
        }
        void k2() {
            k3();
        }
        void k3() {
            k4();
        }
        void k4() {
            k5();
        }
        void k5() {
            k6();
        }
        void k6() {
            k7();
        }
        void k7() {
            k8();
        }
        void k8() {
            k9();
        }
        void k9() {
            k10();
        }
        void k10() {
            k20();
        }
        void k20() {
            new Caller().test();
        }

        class Caller {
            void test() {
                Class<?> c = StackWalker.getInstance(RETAIN_CLASS_REFERENCE).getCallerClass();
                System.out.println("\nTesting K class : " + c);
                Thread.dumpStack();
                if (c != K.class) {
                    throw new RuntimeException("Unexpected caller class "+ c);
                }
            }
        }
    }

    static void caller() {
        Class<?> c = StackWalker.getInstance(RETAIN_CLASS_REFERENCE).getCallerClass();
        System.out.println("\ncaller class : " + c);
        if (c != G.class) {
            throw new RuntimeException("Unexpected caller class "+ c);
        }
    }

}
