// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.cf.methodhandles;

import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assume.assumeTrue;

import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.ToolHelper.DexVm.Version;
import com.android.tools.r8.references.Reference;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.StringUtils;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

/**
 * This test is a refactoring of the InvokePolymorphic test code run by the various AndroidOTest
 * runners.
 */
@RunWith(Parameterized.class)
public class InvokePolymorphicTypesTest extends TestBase {

  static final String EXPECTED =
      StringUtils.lines(
          "N-1-string",
          "2-a--1-1.1-2.24-12345678-N-1-string",
          "false",
          "h",
          "56",
          "72",
          "2147483689",
          "0.56",
          "100.0",
          "hello",
          "goodbye",
          "true");

  private final TestParameters parameters;

  @Parameterized.Parameters(name = "{0}")
  public static TestParametersCollection data() {
    return getTestParameters().withAllRuntimes().withAllApiLevelsAlsoForCf().build();
  }

  public InvokePolymorphicTypesTest(TestParameters parameters) {
    this.parameters = parameters;
  }

  @Test
  public void testD8() throws Exception {
    boolean hasCompileSupport =
        parameters.getApiLevel().isGreaterThanOrEqualTo(apiLevelWithInvokePolymorphicSupport());
    boolean hasRuntimeSupport =
        parameters.isCfRuntime()
            || parameters.asDexRuntime().getVersion().isNewerThanOrEqual(Version.V8_1_0);
    testForD8(parameters.getBackend())
        .addProgramClasses(Data.class, TestClass.class)
        .setMinApi(parameters.getApiLevel())
        .run(parameters.getRuntime(), TestClass.class)
        .applyIf(
            hasCompileSupport,
            r -> r.assertSuccessWithOutput(EXPECTED),
            hasRuntimeSupport,
            r ->
                r.assertSuccess()
                    .assertStderrMatches(
                        containsString(
                            "Instruction is unrepresentable in DEX V35: invoke-polymorphic")),
            r -> r.assertFailureWithErrorThatThrows(NoClassDefFoundError.class));
  }

  @Test
  public void testR8() throws Exception {
    assumeTrue(parameters.isDexRuntime() || parameters.getApiLevel().equals(AndroidApiLevel.B));
    boolean hasCompileSupport =
        parameters.isCfRuntime()
            || parameters
                .getApiLevel()
                .isGreaterThanOrEqualTo(apiLevelWithInvokePolymorphicSupport());
    boolean hasRuntimeSupport =
        parameters.isCfRuntime()
            || parameters.asDexRuntime().getVersion().isNewerThanOrEqual(Version.V8_1_0);
    testForR8(parameters.getBackend())
        .addProgramClasses(Data.class, TestClass.class)
        .setMinApi(parameters.getApiLevel())
        .applyIf(
            !hasCompileSupport,
            b ->
                b.addDontWarn(
                    MethodType.class,
                    MethodHandle.class,
                    MethodHandles.class,
                    MethodHandles.Lookup.class))
        .addKeepMainRule(TestClass.class)
        .addKeepMethodRules(
            Reference.methodFromMethod(Data.class.getDeclaredConstructor()),
            Reference.methodFromMethod(
                TestClass.class.getDeclaredMethod(
                    "buildString", Integer.class, int.class, String.class)),
            Reference.methodFromMethod(
                TestClass.class.getDeclaredMethod(
                    "buildString",
                    byte.class,
                    char.class,
                    short.class,
                    float.class,
                    double.class,
                    long.class,
                    Integer.class,
                    int.class,
                    String.class)),
            Reference.methodFromMethod(
                TestClass.class.getDeclaredMethod(
                    "testWithAllTypes",
                    boolean.class,
                    char.class,
                    short.class,
                    int.class,
                    long.class,
                    float.class,
                    double.class,
                    String.class,
                    Object.class)))
        .allowDiagnosticMessages()
        .run(parameters.getRuntime(), TestClass.class)
        .applyIf(
            hasCompileSupport,
            r -> r.assertSuccessWithOutput(EXPECTED),
            hasRuntimeSupport,
            r ->
                r.assertSuccess()
                    .assertStderrMatches(
                        containsString(
                            "Instruction is unrepresentable in DEX V35: invoke-polymorphic")),
            r -> r.assertFailureWithErrorThatThrows(NoClassDefFoundError.class));
  }

  static class Data {}

  static class TestClass {

    public String buildString(Integer i1, int i2, String s) {
      return (i1 == null ? "N" : "!N") + "-" + i2 + "-" + s;
    }

    public void testInvokePolymorphic() {
      MethodType mt = MethodType.methodType(String.class, Integer.class, int.class, String.class);
      MethodHandles.Lookup lk = MethodHandles.lookup();

      try {
        MethodHandle mh = lk.findVirtual(getClass(), "buildString", mt);
        System.out.println(mh.invoke(this, null, 1, "string"));
      } catch (Throwable t) {
        t.printStackTrace();
      }
    }

    public String buildString(
        byte b, char c, short s, float f, double d, long l, Integer i1, int i2, String str) {
      return b
          + "-"
          + c
          + "-"
          + s
          + "-"
          + f
          + "-"
          + d
          + "-"
          + l
          + "-"
          + (i1 == null ? "N" : "!N")
          + "-"
          + i2
          + "-"
          + str;
    }

    public void testInvokePolymorphicRange() {
      MethodType mt =
          MethodType.methodType(
              String.class,
              byte.class,
              char.class,
              short.class,
              float.class,
              double.class,
              long.class,
              Integer.class,
              int.class,
              String.class);
      MethodHandles.Lookup lk = MethodHandles.lookup();

      try {
        MethodHandle mh = lk.findVirtual(getClass(), "buildString", mt);
        System.out.println(
            mh.invoke(
                this, (byte) 2, 'a', (short) 0xFFFF, 1.1f, 2.24d, 12345678L, null, 1, "string"));
      } catch (Throwable t) {
        t.printStackTrace();
      }
    }

    public static void testWithAllTypes(
        boolean z, char a, short b, int c, long d, float e, double f, String g, Object h) {
      System.out.println(z);
      System.out.println(a);
      System.out.println(b);
      System.out.println(c);
      System.out.println(d);
      System.out.println(e);
      System.out.println(f);
      System.out.println(g);
      System.out.println(h);
    }

    public void testInvokePolymorphicWithAllTypes() {
      try {
        MethodHandle mth =
            MethodHandles.lookup()
                .findStatic(
                    TestClass.class,
                    "testWithAllTypes",
                    MethodType.methodType(
                        void.class,
                        boolean.class,
                        char.class,
                        short.class,
                        int.class,
                        long.class,
                        float.class,
                        double.class,
                        String.class,
                        Object.class));
        mth.invokeExact(
            false,
            'h',
            (short) 56,
            72,
            Integer.MAX_VALUE + 42l,
            0.56f,
            100.0d,
            "hello",
            (Object) "goodbye");
      } catch (Throwable t) {
        t.printStackTrace();
      }
    }

    public MethodHandle testInvokePolymorphicWithConstructor() {
      MethodHandle mh = null;
      MethodType mt = MethodType.methodType(void.class);
      MethodHandles.Lookup lk = MethodHandles.lookup();

      try {
        mh = lk.findConstructor(Data.class, mt);
        System.out.println(mh.invoke().getClass() == Data.class);
      } catch (Throwable t) {
        t.printStackTrace();
      }

      return mh;
    }

    public static void main(String[] args) {
      TestClass invokePolymorphic = new TestClass();
      invokePolymorphic.testInvokePolymorphic();
      invokePolymorphic.testInvokePolymorphicRange();
      invokePolymorphic.testInvokePolymorphicWithAllTypes();
      invokePolymorphic.testInvokePolymorphicWithConstructor();
    }
  }
}
