// Copyright (c) 2024, 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 jdk17.ir.optimize.interfaces;

import static org.junit.Assert.assertEquals;

import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.InstructionSubject;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;

// This test is also present for base test module and JDK-21 to demonstrate the different javac
// byte code.
@RunWith(Parameterized.class)
public class CastWithMultipleBoundsJavacBytecodeTest extends TestBase {

  @Parameter(0)
  public TestParameters parameters;

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

  @Test
  public void testR8JavacCode() throws Exception {
    parameters.assumeIsOrSimulateNoneRuntime();
    // javac from JDK-17 generates the following code for getLambda with three checkcasts to
    // the two interface types and then to the static return type:
    //
    // static java.io.Serializable getLambda();
    //   descriptor: ()Ljava/io/Serializable;
    //   flags: (0x0008) ACC_STATIC
    //   Code:
    //     stack=1, locals=0, args_size=0
    //        0: invokedynamic #7,  0              // InvokeDynamic #0:run:()Ljava/lang/Runnable;
    //        5: checkcast     #11                 // class java/io/Serializable
    //        8: checkcast     #13                 // class java/lang/Runnable
    //       11: checkcast     #11                 // class java/io/Serializable
    //       14: areturn
    assertEquals(
        3,
        new CodeInspector(ToolHelper.getClassFileForTestClass(TestClass.class))
            .clazz(TestClass.class)
            .uniqueMethodWithOriginalName("getLambda")
            .streamInstructions()
            .filter(InstructionSubject::isCheckCast)
            .count());
  }

  @Test
  public void testR8() throws Exception {
    testForR8(parameters.getBackend())
        .addInnerClassesAndStrippedOuter(getClass())
        .addKeepMainRule(TestClass.class)
        .setMinApi(parameters)
        .addKeepMainRule(TestClass.class)
        .run(parameters.getRuntime(), TestClass.class);
  }

  static class TestClass {
    static void invokeLambda(Object o)
        throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
      Method runMethod = o.getClass().getMethod("run");
      runMethod.invoke(o);
    }

    static Serializable getLambda() {
      return (Runnable & Serializable) () -> System.out.println("base lambda");
    }

    public static void main(String[] args) throws Exception {
      invokeLambda(getLambda());
    }
  }
}
