// Copyright (c) 2018, 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.bridgeremoval;

import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;

import com.android.tools.r8.KeepConstantArguments;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.code.InvokeVirtual;
import com.android.tools.r8.code.ReturnVoid;
import com.android.tools.r8.graph.DexCode;
import com.android.tools.r8.jasmin.JasminBuilder;
import com.android.tools.r8.jasmin.JasminBuilder.ClassBuilder;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
import com.google.common.collect.ImmutableList;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

@RunWith(Parameterized.class)
public class B77836766 extends TestBase {

  private final TestParameters parameters;

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

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

  /**
   * The below Jasmin code mimics the following Kotlin code:
   *
   * package java_pkg;
   *
   * public interface Itf1 {
   *   void foo(String arg);
   * }
   *
   * public interface Itf2 {
   *   void foo(Integer arg);
   * }
   *
   * package kt_pkg;
   *
   * internal abstract class AbsCls<T> {
   *   void foo(T obj) { ... }
   * }
   *
   * internal class Cls1() : AbsCls<String>(), Itf1
   *
   * internal class Cls2() : AbsCls<Integer>(), Itf2
   *
   *
   * kotlinc introduced bridge methods Cls?#foo to AbsCls#foo:
   *
   * class Cls1 extends AbsCls implements Itf1 {
   *   public bridge synthetic void foo(String arg) {
   *     invoke-virtual Cls1#foo(Object)V
   *   }
   * }
   *
   * Note that we can't write such code in Java because javac requires Itf?#foo, which are
   * technically abstract methods, to be explicitly overridden.
   */
  @Test
  public void test_bridgeTargetInBase_differentBridges() throws Exception {
    JasminBuilder jasminBuilder = new JasminBuilder();

    ClassBuilder absCls = jasminBuilder.addClass("AbsCls");
    absCls.setAccess("public abstract");
    absCls.addFinalMethod("foo", ImmutableList.of("Ljava/lang/Object;"), "V",
        ".limit stack 3",
        ".limit locals 2",
        "getstatic java/lang/System/out Ljava/io/PrintStream;",
        "aload_1",
        "invokevirtual java/io/PrintStream/print(Ljava/lang/Object;)V",
        "return");

    ClassBuilder itf1 = jasminBuilder.addInterface("Itf1");
    itf1.addAbstractMethod("foo", ImmutableList.of("Ljava/lang/String;"), "V");

    ClassBuilder cls1 = jasminBuilder.addClass("Cls1", absCls.name, itf1.name);
    // Mimic Kotlin's "internal" class
    cls1.setAccess("");
    cls1.addRuntimeInvisibleAnnotation(KeepConstantArguments.class.getTypeName());
    cls1.addBridgeMethod("foo", ImmutableList.of("Ljava/lang/String;"), "V",
        ".limit stack 2",
        ".limit locals 2",
        "aload_0",
        "aload_1",
        "invokevirtual " + cls1.name + "/foo(Ljava/lang/Object;)V",
        "return");

    ClassBuilder itf2 = jasminBuilder.addInterface("Itf2");
    itf2.addAbstractMethod("foo", ImmutableList.of("Ljava/lang/Integer;"), "V");

    ClassBuilder cls2Class = jasminBuilder.addClass("Cls2", absCls.name, itf2.name);
    // Mimic Kotlin's "internal" class
    cls2Class.setAccess("");
    cls2Class.addBridgeMethod(
        "foo",
        ImmutableList.of("Ljava/lang/Integer;"),
        "V",
        ".limit stack 2",
        ".limit locals 2",
        "aload_0",
        "aload_1",
        "invokevirtual " + cls2Class.name + "/foo(Ljava/lang/Object;)V",
        "return");

    ClassBuilder mainClass = jasminBuilder.addClass("Main");
    mainClass.addMainMethod(
        ".limit stack 5",
        ".limit locals 2",
        "new " + cls1.name,
        "dup",
        "invokespecial " + cls1.name + "/<init>()V",
        "astore_0",
        "aload_0",
        "ldc \"Hello\"",
        "invokevirtual " + cls1.name + "/foo(Ljava/lang/String;)V",
        "new " + cls2Class.name,
        "dup",
        "invokespecial " + cls2Class.name + "/<init>()V",
        "astore_0",
        "aload_0",
        "iconst_0",
        "invokestatic java/lang/Integer/valueOf(I)Ljava/lang/Integer;",
        "invokevirtual " + cls2Class.name + "/foo(Ljava/lang/Integer;)V",
        "return");

    testForR8(parameters.getBackend())
        .addProgramClassFileData(jasminBuilder.buildClasses())
        .addKeepMainRule(mainClass.name)
        .addOptionsModification(this::configure)
        .enableConstantArgumentAnnotations()
        .noHorizontalClassMerging(cls2Class.name)
        .noMinification()
        .setMinApi(parameters.getApiLevel())
        .compile()
        .inspect(
            inspector -> {
              ClassSubject absSubject = inspector.clazz(absCls.name);
              assertThat(absSubject, isPresent());
              ClassSubject cls1Subject = inspector.clazz(cls1.name);
              assertThat(cls1Subject, isPresent());
              ClassSubject cls2Subject = inspector.clazz(cls2Class.name);
              assertThat(cls2Subject, isPresent());

              // Cls1#foo and Cls2#foo should not refer to each other.
              // They can invoke their own bridge method or AbsCls#foo (via member rebinding).

              // Cls2#foo has been moved to AbsCls#foo as a result of bridge hoisting.
              MethodSubject fooInCls2 = cls2Subject.method("void", "foo", "java.lang.Integer");
              assertThat(fooInCls2, not(isPresent()));

              MethodSubject fooFromCls2InAbsCls =
                  absSubject.method("void", "foo", "java.lang.Integer");
              assertThat(fooFromCls2InAbsCls, isPresent());

              // Cls1#foo has been moved to AbsCls#foo as a result of bridge hoisting.
              MethodSubject fooInCls1 = cls1Subject.method("void", "foo", "java.lang.String");
              assertThat(fooInCls1, not(isPresent()));

              MethodSubject fooFromCls1InAbsCls =
                  absSubject.method("void", "foo", "java.lang.String");
              assertThat(fooFromCls1InAbsCls, isPresent());

              if (parameters.isDexRuntime()) {
                DexCode code = fooFromCls2InAbsCls.getMethod().getCode().asDexCode();
                checkInstructions(code, ImmutableList.of(InvokeVirtual.class, ReturnVoid.class));
                InvokeVirtual invoke = (InvokeVirtual) code.instructions[0];
                assertEquals(absSubject.getDexProgramClass().type, invoke.getMethod().holder);

                code = fooFromCls1InAbsCls.getMethod().getCode().asDexCode();
                checkInstructions(code, ImmutableList.of(InvokeVirtual.class, ReturnVoid.class));
                invoke = (InvokeVirtual) code.instructions[0];
                assertEquals(absSubject.getDexProgramClass().type, invoke.getMethod().holder);
              }
            })
        .run(parameters.getRuntime(), mainClass.name)
        .assertSuccessWithOutput("Hello0");
  }

  /**
   * class Base {
   *   void foo(Object o) {...}
   * }
   * interface ItfInteger {
   *   void foo(Integer o);
   * }
   * class DerivedInteger extends Base implements ItfInteger {
   *   // Bridge method deferring to Base#foo(Object):
   *   public bridge synthetic void foo(Integer o) {
   *     foo((Object) o);
   *   } }
   * class DerivedString extends Base {
   *   // Regular non-bridge method calling Base#foo(Object):
   *   public void bar(String o) {
   *     foo(o);
   *   } }
   */
  @Test
  public void test_bridgeTargetInBase_bridgeAndNonBridge() throws Exception {
    JasminBuilder jasminBuilder = new JasminBuilder();

    ClassBuilder baseCls = jasminBuilder.addClass("Base");
    baseCls.addVirtualMethod("foo", ImmutableList.of("Ljava/lang/Object;"), "V",
        ".limit stack 3",
        ".limit locals 2",
        "getstatic java/lang/System/out Ljava/io/PrintStream;",
        "aload_1",
        "invokevirtual java/io/PrintStream/print(Ljava/lang/Object;)V",
        "return");

    ClassBuilder itf = jasminBuilder.addInterface("ItfInteger");
    itf.addAbstractMethod("foo", ImmutableList.of("Ljava/lang/Integer;"), "V");

    ClassBuilder derivedIntegerClass =
        jasminBuilder.addClass("DerivedInteger", baseCls.name, itf.name);
    derivedIntegerClass.addBridgeMethod(
        "foo",
        ImmutableList.of("Ljava/lang/Integer;"),
        "V",
        ".limit stack 2",
        ".limit locals 2",
        "aload_0",
        "aload_1",
        "invokevirtual " + derivedIntegerClass.name + "/foo(Ljava/lang/Object;)V",
        "return");

    ClassBuilder cls2 = jasminBuilder.addClass("DerivedString", baseCls.name);
    cls2.addRuntimeInvisibleAnnotation(KeepConstantArguments.class.getTypeName());
    cls2.addVirtualMethod("bar", ImmutableList.of("Ljava/lang/String;"), "V",
        ".limit stack 2",
        ".limit locals 2",
        "aload_0",
        "aload_1",
        "invokevirtual " + cls2.name + "/foo(Ljava/lang/Object;)V",
        "return");

    ClassBuilder mainClass = jasminBuilder.addClass("Main");
    mainClass.addMainMethod(
        ".limit stack 5",
        ".limit locals 2",
        "new " + derivedIntegerClass.name,
        "dup",
        "invokespecial " + derivedIntegerClass.name + "/<init>()V",
        "astore_0",
        "aload_0",
        "iconst_0",
        "invokestatic java/lang/Integer/valueOf(I)Ljava/lang/Integer;",
        "invokevirtual " + derivedIntegerClass.name + "/foo(Ljava/lang/Integer;)V",
        "new " + cls2.name,
        "dup",
        "invokespecial " + cls2.name + "/<init>()V",
        "astore_0",
        "aload_0",
        "ldc \"Bar\"",
        "invokevirtual " + cls2.name + "/bar(Ljava/lang/String;)V",
        "return");

    testForR8(parameters.getBackend())
        .addProgramClassFileData(jasminBuilder.buildClasses())
        .addKeepMainRule(mainClass.name)
        .addOptionsModification(this::configure)
        .enableConstantArgumentAnnotations()
        .noHorizontalClassMerging(derivedIntegerClass.name)
        .noMinification()
        .setMinApi(parameters.getApiLevel())
        .compile()
        .inspect(
            inspector -> {
              ClassSubject baseSubject = inspector.clazz(baseCls.name);
              assertThat(baseSubject, isPresent());
              ClassSubject cls1Subject = inspector.clazz(derivedIntegerClass.name);
              assertThat(cls1Subject, isPresent());
              ClassSubject cls2Subject = inspector.clazz(cls2.name);
              assertThat(cls2Subject, isPresent());

              // Cls1#foo and Cls2#bar should refer to Base#foo.

              MethodSubject barInCls2 = cls2Subject.method("void", "bar", "java.lang.String");
              assertThat(barInCls2, isPresent());

              // Cls1#foo has been moved to Base#foo as a result of bridge hoisting.
              MethodSubject fooInCls1 = cls1Subject.method("void", "foo", "java.lang.Integer");
              assertThat(fooInCls1, not(isPresent()));

              MethodSubject fooInBase = baseSubject.method("void", "foo", "java.lang.Integer");
              assertThat(fooInBase, isPresent());

              if (parameters.isDexRuntime()) {
                DexCode code = barInCls2.getMethod().getCode().asDexCode();
                checkInstructions(code, ImmutableList.of(InvokeVirtual.class, ReturnVoid.class));
                InvokeVirtual invoke = (InvokeVirtual) code.instructions[0];
                assertEquals(baseSubject.getDexProgramClass().type, invoke.getMethod().holder);

                code = fooInBase.getMethod().getCode().asDexCode();
                checkInstructions(code, ImmutableList.of(InvokeVirtual.class, ReturnVoid.class));
                invoke = (InvokeVirtual) code.instructions[0];
                assertEquals(baseSubject.getDexProgramClass().type, invoke.getMethod().holder);
              }
            })
        .run(parameters.getRuntime(), mainClass.name)
        .assertSuccessWithOutput("0Bar");
  }

  /**
   * class Base {
   *   protected void foo(Object o) { ... }
   *   // Bridge method deferring to Base#foo(Object):
   *   public bridge synthetic void foo(Integer o) {
   *     foo((Object) o);
   *   } }
   * class DerivedString extends Base {
   *   // Regular non-bridge method calling Base#foo(Object):
   *   public void bar(String o) {
   *     foo(o);
   *   } }
   */
  @Test
  public void test_nonBridgeInSubType() throws Exception {
    JasminBuilder jasminBuilder = new JasminBuilder();

    ClassBuilder baseCls = jasminBuilder.addClass("Base");
    baseCls.addVirtualMethod("foo", ImmutableList.of("Ljava/lang/Object;"), "V",
        ".limit stack 3",
        ".limit locals 2",
        "getstatic java/lang/System/out Ljava/io/PrintStream;",
        "aload_1",
        "invokevirtual java/io/PrintStream/print(Ljava/lang/Object;)V",
        "return");
    baseCls.addBridgeMethod("foo", ImmutableList.of("Ljava/lang/Integer;"), "V",
        ".limit stack 2",
        ".limit locals 2",
        "aload_0",
        "aload_1",
        "invokevirtual " + baseCls.name + "/foo(Ljava/lang/Object;)V",
        "return");

    ClassBuilder subCls = jasminBuilder.addClass("DerivedString", baseCls.name);
    subCls.addRuntimeInvisibleAnnotation(KeepConstantArguments.class.getTypeName());
    subCls.addVirtualMethod("bar", ImmutableList.of("Ljava/lang/String;"), "V",
        ".limit stack 2",
        ".limit locals 2",
        "aload_0",
        "aload_1",
        "invokevirtual " + subCls.name + "/foo(Ljava/lang/Object;)V",
        "return");

    ClassBuilder mainClass = jasminBuilder.addClass("Main");
    mainClass.addMainMethod(
        ".limit stack 5",
        ".limit locals 2",
        "new " + baseCls.name,
        "dup",
        "invokespecial " + baseCls.name + "/<init>()V",
        "astore_0",
        "aload_0",
        "iconst_0",
        "invokestatic java/lang/Integer/valueOf(I)Ljava/lang/Integer;",
        "invokevirtual " + baseCls.name + "/foo(Ljava/lang/Integer;)V",
        "new " + subCls.name,
        "dup",
        "invokespecial " + subCls.name + "/<init>()V",
        "astore_0",
        "aload_0",
        "ldc \"Bar\"",
        "invokevirtual " + subCls.name + "/bar(Ljava/lang/String;)V",
        "return"
    );

    testForR8(parameters.getBackend())
        .addProgramClassFileData(jasminBuilder.buildClasses())
        .addKeepMainRule(mainClass.name)
        .addOptionsModification(this::configure)
        .enableConstantArgumentAnnotations()
        .noMinification()
        .setMinApi(parameters.getApiLevel())
        .compile()
        .inspect(
            inspector -> {
              ClassSubject baseSubject = inspector.clazz(baseCls.name);
              assertThat(baseSubject, isPresent());
              ClassSubject subSubject = inspector.clazz(subCls.name);
              assertThat(subSubject, isPresent());

              // DerivedString2#bar should refer to Base#foo.

              MethodSubject barInSub = subSubject.method("void", "bar", "java.lang.String");
              assertThat(barInSub, isPresent());

              if (parameters.isDexRuntime()) {
                DexCode code = barInSub.getMethod().getCode().asDexCode();
                checkInstructions(code, ImmutableList.of(InvokeVirtual.class, ReturnVoid.class));
                InvokeVirtual invoke = (InvokeVirtual) code.instructions[0];
                assertEquals(baseSubject.getDexProgramClass().type, invoke.getMethod().holder);
              }
            })
        .run(parameters.getRuntime(), mainClass.name)
        .assertSuccessWithOutput("0Bar");
  }

  /*
   * public class Base {
   *  public bridge void foo(Integer i) { foo((Object) i); }
   *  public foo(Object o) { print(o); }
   *  public bar(String s) { foo(s); }
   * }
   */
  @Test
  public void test_bridgeTargetInsideTheSameClass() throws Exception {
    JasminBuilder jasminBuilder = new JasminBuilder();

    ClassBuilder cls = jasminBuilder.addClass("Base");
    cls.addBridgeMethod("foo", ImmutableList.of("Ljava/lang/Integer;"), "V",
        ".limit stack 2",
        ".limit locals 2",
        "aload_0",
        "aload_1",
        "invokevirtual " + cls.name + "/foo(Ljava/lang/Object;)V",
        "return");
    cls.addVirtualMethod("foo", ImmutableList.of("Ljava/lang/Object;"), "V",
        ".limit stack 3",
        ".limit locals 2",
        "getstatic java/lang/System/out Ljava/io/PrintStream;",
        "aload_1",
        "invokevirtual java/io/PrintStream/print(Ljava/lang/Object;)V",
        "return");
    cls.addRuntimeInvisibleAnnotation(KeepConstantArguments.class.getTypeName());
    cls.addVirtualMethod("bar", ImmutableList.of("Ljava/lang/String;"), "V",
        ".limit stack 2",
        ".limit locals 2",
        "aload_0",
        "aload_1",
        "invokevirtual " + cls.name + "/foo(Ljava/lang/Object;)V",
        "return");

    ClassBuilder mainClass = jasminBuilder.addClass("Main");
    mainClass.addMainMethod(
        ".limit stack 5",
        ".limit locals 2",
        "new " + cls.name,
        "dup",
        "invokespecial " + cls.name + "/<init>()V",
        "astore_0",
        "aload_0",
        "iconst_0",
        "invokestatic java/lang/Integer/valueOf(I)Ljava/lang/Integer;",
        "invokevirtual " + cls.name + "/foo(Ljava/lang/Integer;)V",
        "new " + cls.name,
        "dup",
        "invokespecial " + cls.name + "/<init>()V",
        "astore_0",
        "aload_0",
        "ldc \"Bar\"",
        "invokevirtual " + cls.name + "/bar(Ljava/lang/String;)V",
        "return"
    );

    testForR8(parameters.getBackend())
        .addProgramClassFileData(jasminBuilder.buildClasses())
        .addKeepMainRule(mainClass.name)
        .addOptionsModification(this::configure)
        .enableConstantArgumentAnnotations()
        .noMinification()
        .setMinApi(parameters.getApiLevel())
        .compile()
        .inspect(
            inspector -> {
              ClassSubject baseSubject = inspector.clazz(cls.name);
              assertThat(baseSubject, isPresent());

              // Base#bar should remain as-is, i.e., refer to Base#foo(Object).

              MethodSubject barInSub = baseSubject.method("void", "bar", "java.lang.String");
              assertThat(barInSub, isPresent());

              if (parameters.isDexRuntime()) {
                DexCode code = barInSub.getMethod().getCode().asDexCode();
                checkInstructions(code, ImmutableList.of(InvokeVirtual.class, ReturnVoid.class));
                InvokeVirtual invoke = (InvokeVirtual) code.instructions[0];
                assertEquals(baseSubject.getDexProgramClass().type, invoke.getMethod().holder);
              }
            })
        .run(parameters.getRuntime(), mainClass.name)
        .assertSuccessWithOutput("0Bar");
  }

  private void configure(InternalOptions options) {
    // Callees are invoked with a simple constant, e.g., "Bar". Propagating it into the callees
    // bothers what the tests want to check, such as exact instructions in the body that include
    // invocation kinds, like virtual call to a bridge.
    // Disable inlining to avoid the (short) tested method from being inlined and then removed.
    options.enableInlining = false;
  }
}
