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

/*
 * @test
 * @bug 8186046
 * @summary Test bootstrap arguments for condy
 * @library /java/lang/invoke/common
 * @build test.java.lang.invoke.lib.InstructionHelper
 * @run testng CondyStaticArgumentsTest
 * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyStaticArgumentsTest
 */

import org.testng.Assert;
import org.testng.annotations.Test;
import test.java.lang.invoke.lib.InstructionHelper;

import java.lang.constant.*;
import java.lang.invoke.*;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.MathContext;
import java.util.StringJoiner;
import java.util.stream.Stream;

import static java.lang.invoke.MethodType.methodType;

public class CondyStaticArgumentsTest {
    static final MethodHandles.Lookup L = MethodHandles.lookup();
    private static final DirectMethodHandleDesc bigDecimalMhDesc = directMhDesc("bigDecimal");
    private static final DirectMethodHandleDesc mathContextMhDesc = directMhDesc("mathContext");

    static class BSMInfo {
        final String methodName;
        final MethodHandle handle;
        final String descriptor;

        BSMInfo(String name) {
            methodName = name;

            Method m = Stream.of(CondyStaticArgumentsTest.class.getDeclaredMethods())
                    .filter(x -> x.getName().equals(methodName)).findFirst()
                    .get();
            try {
                handle = MethodHandles.lookup().unreflect(m);
            } catch (Exception e) {
                throw new Error(e);
            }
            descriptor = handle.type().toMethodDescriptorString();
        }

        static BSMInfo of(String name) {
            return new BSMInfo(name);
        }
    }

    static String basicArgs(MethodHandles.Lookup l, String name, Class<?> type,
                            int i, long j, float f, double d,
                            Class<?> c, String s,
                            MethodType mt, MethodHandle mh) {
        return new StringJoiner("-")
                .add(name)
                .add(type.getSimpleName())
                .add(Integer.toString(i))
                .add(Long.toString(j))
                .add(Float.toString(f))
                .add(Double.toString(d))
                .add(c.getSimpleName())
                .add(s)
                .add(mt.toString())
                .add(Integer.toString(mh.type().parameterCount()))
                .toString();
    }

    @Test
    public void testBasicArgs() throws Throwable {
        BSMInfo bi = BSMInfo.of("basicArgs");
        MethodHandleInfo mhi = MethodHandles.lookup().revealDirect(bi.handle);

        MethodHandle mh = InstructionHelper.ldcDynamicConstant(
                L, "constant-name", String.class,
                bi.methodName, bi.handle.type(),
                1, 2L, 3.0f, 4.0d,
                ClassDesc.ofDescriptor(Number.class.descriptorString()),
                "something",
                MethodTypeDesc.ofDescriptor("(IJFD)V"),
                MethodHandleDesc.ofMethod(DirectMethodHandleDesc.Kind.valueOf(mhi.getReferenceKind()),
                        ClassDesc.ofDescriptor(mhi.getDeclaringClass().descriptorString()),
                        mhi.getName(), MethodTypeDesc.ofDescriptor(mhi.getMethodType().descriptorString()))
        );

        Assert.assertEquals(mh.invoke(), "constant-name-String-1-2-3.0-4.0-Number-something-(int,long,float,double)void-11");
    }

    static MathContext mathContext(MethodHandles.Lookup l, String value, Class<?> type) {
        switch (value) {
            case "UNLIMITED":
                return MathContext.UNLIMITED;
            case "DECIMAL32":
                return MathContext.DECIMAL32;
            case "DECIMAL64":
                return MathContext.DECIMAL64;
            case "DECIMAL128":
                return MathContext.DECIMAL128;
            default:
                throw new UnsupportedOperationException();
        }
    }

    static BigDecimal bigDecimal(MethodHandles.Lookup l, String name, Class<?> type,
                                 String value, MathContext mc) {
        return new BigDecimal(value, mc);
    }

    static String condyWithCondy(MethodHandles.Lookup l, String name, Class<?> type,
                                 BigDecimal d) {
        return new StringJoiner("-")
                .add(name)
                .add(type.getSimpleName())
                .add(d.toString())
                .add(Integer.toString(d.precision()))
                .toString();
    }

    @Test
    public void testCondyWithCondy() throws Throwable {
        BSMInfo bi = BSMInfo.of("condyWithCondy");

        MethodHandle mh = InstructionHelper.ldcDynamicConstant(
                L, "big-decimal-math-context", String.class,
                bi.methodName, bi.handle.type(),
                DynamicConstantDesc.ofNamed(
                        bigDecimalMhDesc,
                        "big-decimal",
                        InstructionHelper.classDesc(BigDecimal.class),
                        "3.14159265358979323846",
                        DynamicConstantDesc.ofNamed(
                                mathContextMhDesc,
                                "DECIMAL32",
                                InstructionHelper.classDesc(MathContext.class)
                        )
                )
        );
        Assert.assertEquals(mh.invoke(), "big-decimal-math-context-String-3.141593-7");
    }


    static ConstantCallSite indyWithCondy(MethodHandles.Lookup l, String name, MethodType type,
                                          BigDecimal d) {
        String s = new StringJoiner("-")
                .add(name)
                .add(type.toMethodDescriptorString())
                .add(d.toString())
                .add(Integer.toString(d.precision()))
                .toString();
        return new ConstantCallSite(MethodHandles.constant(String.class, s));
    }

    @Test
    public void testIndyWithCondy() throws Throwable {
        BSMInfo bi = BSMInfo.of("indyWithCondy");

        MethodHandle mh = InstructionHelper.invokedynamic(
                L, "big-decimal-math-context", methodType(String.class),
                bi.methodName, bi.handle.type(),
                DynamicConstantDesc.ofNamed(
                        bigDecimalMhDesc,
                        "big-decimal",
                        InstructionHelper.classDesc(BigDecimal.class),
                        "3.14159265358979323846",
                        DynamicConstantDesc.ofNamed(
                                mathContextMhDesc,
                                "DECIMAL32",
                                InstructionHelper.classDesc(MathContext.class)
                        )
                ));
        Assert.assertEquals(mh.invoke(), "big-decimal-math-context-()Ljava/lang/String;-3.141593-7");
    }

    private static DirectMethodHandleDesc directMhDesc(String methodName) {
        MethodHandleInfo mhi = MethodHandles.lookup().revealDirect(BSMInfo.of(methodName).handle);
        return MethodHandleDesc.of(
                DirectMethodHandleDesc.Kind.valueOf(mhi.getReferenceKind()),
                ClassDesc.ofDescriptor(mhi.getDeclaringClass().descriptorString()),
                mhi.getName(),
                mhi.getMethodType().descriptorString()
        );
    }
}
