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

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

import com.android.tools.r8.NeverClassInline;
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

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

  private final TestParameters parameters;

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

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

  @Test
  public void test() throws Exception {
    expectThrowsWithHorizontalClassMerging();
    testForR8(parameters.getBackend())
        .addProgramClasses(TestClass.class, A.class, B3.class, B4.class)
        .addProgramClassFileData(
            transformer(B1.class)
                .setBridge(B1.class.getDeclaredMethod("superBridge", Object.class))
                .setBridge(B1.class.getDeclaredMethod("virtualBridge", Object.class))
                .transform(),
            transformer(B2.class)
                .setBridge(B2.class.getDeclaredMethod("superBridge", Object.class))
                .setBridge(B2.class.getDeclaredMethod("virtualBridge", Object.class))
                .transform(),
            transformer(B5.class)
                .setBridge(B5.class.getDeclaredMethod("superBridge", Object.class))
                .setBridge(B5.class.getDeclaredMethod("virtualBridge", Object.class))
                .transform())
        .addKeepMainRule(TestClass.class)
        .enableInliningAnnotations()
        .enableNeverClassInliningAnnotations()
        .setMinApi(parameters.getApiLevel())
        .compile()
        .inspect(this::inspect)
        .run(parameters.getRuntime(), TestClass.class)
        .assertSuccessWithOutputLines("Hello world!");
  }

  private void inspect(CodeInspector inspector) {
    ClassSubject aClassSubject = inspector.clazz(A.class);
    assertThat(aClassSubject, isPresent());
    assertThat(aClassSubject.uniqueMethodWithName("m"), isPresent());
    assertThat(aClassSubject.uniqueMethodWithName("superBridge"), isPresent());
    assertThat(aClassSubject.uniqueMethodWithName("virtualBridge"), isPresent());

    ClassSubject b1ClassSubject = inspector.clazz(B1.class);
    assertThat(b1ClassSubject, isPresent());
    assertThat(b1ClassSubject.uniqueMethodWithName("superBridge"), not(isPresent()));
    assertThat(b1ClassSubject.uniqueMethodWithName("virtualBridge"), not(isPresent()));

    ClassSubject b2ClassSubject = inspector.clazz(B2.class);
    assertThat(b2ClassSubject, isPresent());
    assertThat(b2ClassSubject.uniqueMethodWithName("superBridge"), not(isPresent()));
    assertThat(b2ClassSubject.uniqueMethodWithName("virtualBridge"), not(isPresent()));

    ClassSubject b4ClassSubject = inspector.clazz(B4.class);
    assertThat(b4ClassSubject, isPresent());
    assertThat(b4ClassSubject.uniqueMethodWithName("superBridge"), isPresent());
    assertThat(b4ClassSubject.uniqueMethodWithName("virtualBridge"), isPresent());

    ClassSubject b5ClassSubject = inspector.clazz(B5.class);
    assertThat(b5ClassSubject, isPresent());
    assertThat(b5ClassSubject.uniqueMethodWithName("superBridge"), isPresent());
    assertThat(b5ClassSubject.uniqueMethodWithName("virtualBridge"), isPresent());
  }

  static class TestClass {

    public static void main(String[] args) {
      System.out.print(new B1().superBridge("Hel"));
      System.out.print(new B1().virtualBridge("lo"));
      System.out.print(new B2().superBridge(" "));
      System.out.print(new B2().virtualBridge("w"));
      System.out.print(new B3().m("o"));
      System.out.print(new B4().superBridge("r"));
      System.out.print(new B4().virtualBridge("l"));
      System.out.print(new B5().superBridge("d"));
      System.out.println(new B5().virtualBridge("!"));
    }
  }

  static class A {

    @NeverInline
    public Object m(String arg) {
      return System.currentTimeMillis() >= 0 ? arg : null;
    }

    @NeverInline
    public Object m2(String arg) {
      return System.currentTimeMillis() >= 0 ? arg : null;
    }
  }

  @NeverClassInline
  static class B1 extends A {

    // This bridge can be hoisted to A if the invoke-super instruction is rewritten to an
    // invoke-virtual instruction.
    @NeverInline
    public /*bridge*/ String superBridge(Object o) {
      return (String) super.m((String) o);
    }

    // This bridge can be hoisted to A.
    @NeverInline
    public /*bridge*/ String virtualBridge(Object o) {
      return (String) m((String) o);
    }
  }

  @NeverClassInline
  static class B2 extends A {

    // By hoisting B1.superBridge() to A this method bridge redundant.
    @NeverInline
    public /*bridge*/ String superBridge(Object o) {
      return (String) super.m((String) o);
    }

    // By hoisting B1.virtualBridge() to A this method bridge redundant.
    @NeverInline
    public /*bridge*/ String virtualBridge(Object o) {
      return (String) m((String) o);
    }
  }

  // The fact that this class does not declare superBridge() or virtualBridge() should not prevent
  // us from hoisting these bridges from B1/B2 to A.
  //
  // Strictly speaking, there could be an invoke-virtual instruction that targets B3.virtualBridge()
  // and fails with a NoSuchMethodError in the input program. After hoisting B1.virtualBridge() to A
  // such an instruction would no longer fail with a NoSuchMethodError in the generated program.
  //
  // If this ever turns out be an issue, it would be possible to track if there is an invoke
  // instruction targeting B3.virtualBridge() that fails with a NoSuchMethodError in the Enqueuer,
  // but this should never be the case in practice.
  @NeverClassInline
  static class B3 extends A {}

  // The fact that this class declares superBridge() and virtualBridge() should not prevent
  // us from hoisting other bridges to A.
  @NeverClassInline
  static class B4 extends A {

    @NeverInline
    public String superBridge(Object o) {
      return System.currentTimeMillis() >= 0 ? ((String) o) : null;
    }

    @NeverInline
    public String virtualBridge(Object o) {
      return System.currentTimeMillis() >= 0 ? ((String) o) : null;
    }
  }

  // This class declares the same bridges, but with different (bridge) behavior. They are candidates
  // for hoisting, but will not be hoisted because it is better to hoist the bridges declared on B1.
  @NeverClassInline
  static class B5 extends A {

    @NeverInline
    public /*bridge*/ String superBridge(Object o) {
      return (String) super.m2((String) o);
    }

    @NeverInline
    public /*bridge*/ String virtualBridge(Object o) {
      return (String) m2((String) o);
    }
  }
}
