/*
 * Copyright (c) 2021, 2024, 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.io.Serializable;
import java.lang.Enum.EnumDesc;
import java.lang.constant.ClassDesc;
import java.lang.constant.ConstantDescs;
import java.lang.constant.MethodTypeDesc;
import java.lang.invoke.CallSite;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.AccessFlag;
import java.lang.runtime.SwitchBootstraps;
import java.util.concurrent.atomic.AtomicBoolean;
import java.lang.classfile.ClassFile;

import org.testng.annotations.Test;

import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;

/**
 * @test
 * @bug 8318144
 * @enablePreview
 * @compile SwitchBootstrapsTest.java
 * @run testng/othervm SwitchBootstrapsTest
 */
@Test
public class SwitchBootstrapsTest {

    public static final MethodHandle BSM_TYPE_SWITCH;
    public static final MethodHandle BSM_ENUM_SWITCH;

    static {
        try {
            BSM_TYPE_SWITCH = MethodHandles.lookup().findStatic(SwitchBootstraps.class, "typeSwitch",
                                                                MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, Object[].class));
            BSM_ENUM_SWITCH = MethodHandles.lookup().findStatic(SwitchBootstraps.class, "enumSwitch",
                                                                MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, Object[].class));
        }
        catch (ReflectiveOperationException e) {
            throw new AssertionError("Should not happen", e);
        }
    }

    private void testType(Object target, int start, int result, Object... labels) throws Throwable {
        MethodType switchType = MethodType.methodType(int.class, Object.class, int.class);
        MethodHandle indy = ((CallSite) BSM_TYPE_SWITCH.invoke(MethodHandles.lookup(), "", switchType, labels)).dynamicInvoker();
        assertEquals((int) indy.invoke(target, start), result);
        assertEquals(-1, (int) indy.invoke(null, start));
    }

    private void testPrimitiveType(Object target, Class<?> targetType, int start, int result, Object... labels) throws Throwable {
        MethodType switchType = MethodType.methodType(int.class, targetType, int.class);
        MethodHandle indy = ((CallSite) BSM_TYPE_SWITCH.invoke(MethodHandles.lookup(), "", switchType, labels)).dynamicInvoker();
        assertEquals((int) indy.invoke(target, start), result);
    }

    private void testEnum(Enum<?> target, int start, int result, Object... labels) throws Throwable {
        testEnum(target.getClass(), target, start, result, labels);
    }

    private void testEnum(Class<?> targetClass, Enum<?> target, int start, int result, Object... labels) throws Throwable {
        MethodType switchType = MethodType.methodType(int.class, targetClass, int.class);
        MethodHandle indy = ((CallSite) BSM_ENUM_SWITCH.invoke(MethodHandles.lookup(), "", switchType, labels)).dynamicInvoker();
        assertEquals((int) indy.invoke(target, start), result);
        assertEquals(-1, (int) indy.invoke(null, start));
    }

    public enum E1 {
        A,
        B;
    }

    public enum E2 {
        C;
    }

    public void testTypes() throws Throwable {
        testType("", 0, 0, String.class, Object.class);
        testType("", 0, 0, Object.class);
        testType("", 0, 1, Integer.class);
        testType("", 0, 1, Integer.class, Serializable.class);
        testType(E1.A, 0, 0, E1.class, Object.class);
        testType(E2.C, 0, 1, E1.class, Object.class);
        testType(new Serializable() { }, 0, 1, Comparable.class, Serializable.class);
        testType("", 0, 0, "", String.class);
        testType("", 1, 1, "", String.class);
        testType("a", 0, 1, "", String.class);
        testType(1, 0, 0, 1, Integer.class);
        testType(2, 0, 1, 1, Integer.class);
        testType(Byte.valueOf((byte) 1), 0, 0, 1, Integer.class);
        testType(Short.valueOf((short) 1), 0, 0, 1, Integer.class);
        testType(Character.valueOf((char) 1), 0, 0, 1, Integer.class);
        testType(Integer.valueOf((int) 1), 0, 0, 1, Integer.class);
        testType(1, 0, 1, 1.0d, Integer.class);
        testType(1, 0, 1, 1.0f, Integer.class);
        testType(1, 0, 1, true, Integer.class);
        testType("", 0, 0, String.class, String.class, String.class, String.class, String.class);
        testType("", 1, 1, String.class, String.class, String.class, String.class, String.class);
        testType("", 2, 2, String.class, String.class, String.class, String.class, String.class);
        testType("", 3, 3, String.class, String.class, String.class, String.class, String.class);
        testType("", 3, 3, String.class, String.class, String.class, String.class, String.class);
        testType("", 4, 4, String.class, String.class, String.class, String.class, String.class);
        testType("", 0, 0);
        testType(new Object() {
            @Override
            public boolean equals(Object obj) {
                if (obj instanceof Long i) {
                    return i == 1;
                }
                return super.equals(obj);
            }
        }, 0, 1, 1L);
    }

    public void testPrimitiveTypes() throws Throwable {
        testPrimitiveType((short) 1, short.class, 0, 1, String.class);
        testPrimitiveType((byte) 1, byte.class,0, 1, String.class, byte.class);
        testPrimitiveType(true, boolean.class,0, 1, false, boolean.class);
        testPrimitiveType(1, int.class,0, 1, String.class);
        testPrimitiveType(1, int.class,0, 1, true);
        testPrimitiveType(true, boolean.class,0, 1, false);
        testPrimitiveType((byte) 1, byte.class,0, 1, boolean.class, byte.class);
        testPrimitiveType((byte) 1, byte.class,0, 1, Boolean.class, byte.class);
        testPrimitiveType(true, boolean.class,0, 1, String.class, boolean.class);
    }

    public void testEnums() throws Throwable {
        testEnum(E1.A, 0, 2, "B", "C", "A", E1.class);
        testEnum(E1.B, 0, 0, "B", "C", "A", E1.class);
        testEnum(E1.B, 1, 3, "B", "C", "A", E1.class);
        try {
            testEnum(E1.B, 1, 3, "B", "C", "A", E2.class);
            fail("Didn't get the expected exception.");
        } catch (IllegalArgumentException ex) {
            //OK
        }
        try {
            testEnum(E1.B, 1, 3, "B", "C", "A", String.class);
            fail("Didn't get the expected exception.");
        } catch (IllegalArgumentException ex) {
            //OK
        }
        testEnum(E1.B, 0, 0, "B", "A");
        testEnum(E1.A, 0, 1, "B", "A");
        testEnum(E1.A, 0, 0, "A", "A", "B");
        testEnum(E1.A, 1, 1, "A", "A", "B");
        testEnum(E1.A, 2, 3, "A", "A", "B");
        testEnum(E1.A, 0, 0);
    }

    public void testEnumsWithConstants() throws Throwable {
        enum E {
            A {},
            B {},
            C {}
        }
        ClassDesc eDesc = E.class.describeConstable().get();
        Object[] typeParams = new Object[] {
            EnumDesc.of(eDesc, "A"),
            EnumDesc.of(eDesc, "B"),
            EnumDesc.of(eDesc, "C"),
            "a",
            String.class
        };
        testType(E.A, 0, 0, typeParams);
        testType(E.B, 0, 1, typeParams);
        testType(E.C, 0, 2, typeParams);
        testType("a", 0, 3, typeParams);
        testType("x", 0, 4, typeParams);
        testType('a', 0, 5, typeParams);
        testEnum(E.class, E.A, 0, 0, "A", "B", "C");
        testEnum(E.class, E.B, 0, 1, "A", "B", "C");
        testEnum(E.class, E.C, 0, 2, "A", "B", "C");
    }

    public void testWrongSwitchTypes() throws Throwable {
        MethodType[] switchTypes = new MethodType[] {
            MethodType.methodType(int.class, Object.class),
            MethodType.methodType(int.class, Object.class, Integer.class)
        };
        for (MethodType switchType : switchTypes) {
            try {
                BSM_TYPE_SWITCH.invoke(MethodHandles.lookup(), "", switchType);
                fail("Didn't get the expected exception.");
            } catch (IllegalArgumentException ex) {
                //OK, expected
            }
        }
        MethodType[] enumSwitchTypes = new MethodType[] {
            MethodType.methodType(int.class, Enum.class),
            MethodType.methodType(int.class, Object.class, int.class),
            MethodType.methodType(int.class, double.class, int.class),
            MethodType.methodType(int.class, Enum.class, Integer.class)
        };
        for (MethodType enumSwitchType : enumSwitchTypes) {
            try {
                BSM_ENUM_SWITCH.invoke(MethodHandles.lookup(), "", enumSwitchType);
                fail("Didn't get the expected exception.");
            } catch (IllegalArgumentException ex) {
                //OK, expected
            }
        }
    }

    public void testSwitchLabelTypes() throws Throwable {
        enum E {A}
        try {
            testType(E.A, 0, -1, E.A);
            fail("Didn't get the expected exception.");
        } catch (IllegalArgumentException ex) {
            //OK, expected
        }
    }

    public void testSwitchQualifiedEnum() throws Throwable {
        enum E {A, B, C}
        Object[] labels = new Object[] {
            EnumDesc.of(ClassDesc.of(E.class.getName()), "A"),
            EnumDesc.of(ClassDesc.of(E.class.getName()), "B"),
            EnumDesc.of(ClassDesc.of(E.class.getName()), "C")
        };
        testType(E.A, 0, 0, labels);
        testType(E.B, 0, 1, labels);
        testType(E.C, 0, 2, labels);
    }

    public void testNullLabels() throws Throwable {
        MethodType switchType = MethodType.methodType(int.class, Object.class, int.class);
        try {
            BSM_TYPE_SWITCH.invoke(MethodHandles.lookup(), "", switchType, (Object[]) null);
            fail("Didn't get the expected exception.");
        } catch (NullPointerException ex) {
            //OK
        }
        try {
            BSM_TYPE_SWITCH.invoke(MethodHandles.lookup(), "", switchType,
                                   new Object[] {1, null, String.class});
            fail("Didn't get the expected exception.");
        } catch (IllegalArgumentException ex) {
            //OK
        }
        MethodType enumSwitchType = MethodType.methodType(int.class, E1.class, int.class);
        try {
            BSM_TYPE_SWITCH.invoke(MethodHandles.lookup(), "", enumSwitchType, (Object[]) null);
            fail("Didn't get the expected exception.");
        } catch (NullPointerException ex) {
            //OK
        }
        try {
            BSM_TYPE_SWITCH.invoke(MethodHandles.lookup(), "", enumSwitchType,
                                   new Object[] {1, null, String.class});
            fail("Didn't get the expected exception.");
        } catch (IllegalArgumentException ex) {
            //OK
        }
    }

    private static AtomicBoolean enumInitialized = new AtomicBoolean();
    public void testEnumInitialization1() throws Throwable {
        enumInitialized.set(false);

        enum E {
            A;

            static {
                enumInitialized.set(true);
            }
        }

        MethodType enumSwitchType = MethodType.methodType(int.class, E.class, int.class);

        CallSite invocation = (CallSite) BSM_ENUM_SWITCH.invoke(MethodHandles.lookup(), "", enumSwitchType, new Object[] {"A"});
        assertFalse(enumInitialized.get());
        assertEquals(invocation.dynamicInvoker().invoke(null, 0), -1);
        assertFalse(enumInitialized.get());
        E e = E.A;
        assertTrue(enumInitialized.get());
        assertEquals(invocation.dynamicInvoker().invoke(e, 0), 0);
    }

    public void testEnumInitialization2() throws Throwable {
        enumInitialized.set(false);

        enum E {
            A;

            static {
                enumInitialized.set(true);
            }
        }

        MethodType switchType = MethodType.methodType(int.class, Object.class, int.class);
        Object[] labels = new Object[] {
            EnumDesc.of(ClassDesc.of(E.class.getName()), "A"),
            "test"
        };
        CallSite invocation = (CallSite) BSM_TYPE_SWITCH.invoke(MethodHandles.lookup(), "", switchType, labels);
        assertFalse(enumInitialized.get());
        assertEquals(invocation.dynamicInvoker().invoke(null, 0), -1);
        assertFalse(enumInitialized.get());
        assertEquals(invocation.dynamicInvoker().invoke("test", 0), 1);
        assertFalse(enumInitialized.get());
        E e = E.A;
        assertTrue(enumInitialized.get());
        assertEquals(invocation.dynamicInvoker().invoke(e, 0), 0);
    }

    public void testIncorrectEnumLabels() throws Throwable {
        try {
            testEnum(E1.B, 0, -1, "B", 1);
            fail("Didn't get the expected exception.");
        } catch (IllegalArgumentException ex) {
            //OK
        }
        try {
            testEnum(E1.B, 0, -1, "B", null);
            fail("Didn't get the expected exception.");
        } catch (IllegalArgumentException ex) {
            //OK
        }
    }

    public void testIncorrectEnumStartIndex() throws Throwable {
        try {
            testEnum(E1.B, -1, -1, "B");
            fail("Didn't get the expected exception.");
        } catch (IndexOutOfBoundsException ex) {
            //OK
        }
        try {
            testEnum(E1.B, 2, -1, "B");
            fail("Didn't get the expected exception.");
        } catch (IndexOutOfBoundsException ex) {
            //OK
        }
    }

    public void testIncorrectTypeStartIndex() throws Throwable {
        try {
            testType("", -1, -1, "");
            fail("Didn't get the expected exception.");
        } catch (IndexOutOfBoundsException ex) {
            //OK
        }
        try {
            testType("", 2, -1, "");
            fail("Didn't get the expected exception.");
        } catch (IndexOutOfBoundsException ex) {
            //OK
        }
    }

    public void testHiddenClassAsCaseLabel() throws Throwable {
        MethodHandles.Lookup lookup = MethodHandles.lookup();
        byte[] classBytes = createClass();
        Class<?> classA = lookup.defineHiddenClass(classBytes, false).lookupClass();
        Class<?> classB = lookup.defineHiddenClass(classBytes, false).lookupClass();
        Object[] labels = new Object[] {
            classA,
            classB,
        };
        testType(classA.getConstructor().newInstance(), 0, 0, labels);
        testType(classB.getConstructor().newInstance(), 0, 1, labels);
    }

    private static byte[] createClass() {
        return ClassFile.of().build(ClassDesc.of("C"), clb -> {
            clb.withFlags(AccessFlag.SYNTHETIC)
               .withMethodBody("<init>",
                               MethodTypeDesc.of(ConstantDescs.CD_void),
                               ClassFile.ACC_PUBLIC,
                               cb -> {
                                   cb.aload(0);
                                   cb.invokespecial(ConstantDescs.CD_Object,
                                                    "<init>",
                                                    MethodTypeDesc.of(ConstantDescs.CD_void));
                                   cb.return_();
                               });
                    });
    }
}
