// Copyright (c) 2019, 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.ir.optimize.inliner;

import static com.android.tools.r8.utils.codeinspector.CodeMatchers.invokesMethod;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.IsNot.not;

import com.android.tools.r8.KeepConstantArguments;
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.ToolHelper;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
import java.util.Objects;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

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

  private final TestParameters parameters;

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

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

  @Test
  public void testClass1() throws Exception {
    Class<TestClass1> mainClass = TestClass1.class;
    CodeInspector inspector =
        buildAndRun(
            mainClass,
            StringUtils.lines("In A.<clinit>()", "In A.notInlineable()", "In A.inlineable()"));

    ClassSubject classA = inspector.clazz(A.class);
    assertThat(classA, isPresent());

    MethodSubject inlineableMethod = classA.uniqueMethodWithName("inlineable");
    assertThat(inlineableMethod, not(isPresent()));

    MethodSubject notInlineableMethod = classA.uniqueMethodWithName("notInlineable");
    assertThat(notInlineableMethod, isPresent());

    MethodSubject testMethod = inspector.clazz(mainClass).mainMethod();
    assertThat(testMethod, isPresent());
    assertThat(testMethod, invokesMethod(notInlineableMethod));
  }

  @Test
  public void testClass2() throws Exception {
    Class<TestClass2> mainClass = TestClass2.class;
    CodeInspector inspector =
        buildAndRun(
            mainClass,
            StringUtils.lines("In A.<clinit>()", "Field A.staticField", "In A.inlineable()"));

    ClassSubject classA = inspector.clazz(A.class);
    assertThat(classA, isPresent());

    MethodSubject inlineableMethod = classA.uniqueMethodWithName("inlineable");
    assertThat(inlineableMethod, not(isPresent()));
  }

  @Test
  public void testClass3() throws Exception {
    Class<TestClass3> mainClass = TestClass3.class;
    CodeInspector inspector =
        buildAndRun(mainClass, StringUtils.lines("In A.<clinit>()", "In A.inlineable()"));

    ClassSubject classA = inspector.clazz(A.class);
    assertThat(classA, isPresent());

    MethodSubject inlineableMethod = classA.uniqueMethodWithName("inlineable");
    assertThat(inlineableMethod, not(isPresent()));
  }

  @Test
  public void testClass4() throws Exception {
    Class<TestClass4> mainClass = TestClass4.class;
    CodeInspector inspector =
        buildAndRun(
            mainClass,
            StringUtils.lines("In A.<clinit>()", "Field A.instanceField", "In A.inlineable()"));

    ClassSubject classA = inspector.clazz(A.class);
    assertThat(classA, isPresent());

    MethodSubject inlineableMethod = classA.uniqueMethodWithName("inlineable");
    assertThat(inlineableMethod, not(isPresent()));
  }

  @Test
  public void testClass5() throws Exception {
    Class<TestClass5> mainClass = TestClass5.class;
    CodeInspector inspector =
        buildAndRun(mainClass, StringUtils.lines("In A.<clinit>()", "In A.inlineable()"));

    ClassSubject classA = inspector.clazz(A.class);
    assertThat(classA, isPresent());

    MethodSubject inlineableMethod = classA.uniqueMethodWithName("inlineable");
    assertThat(inlineableMethod, not(isPresent()));
  }

  @Test
  public void testClass6() throws Exception {
    Class<TestClass6> mainClass = TestClass6.class;
    CodeInspector inspector =
        buildAndRun(mainClass, StringUtils.lines("In A.<clinit>()", "In A.notInlineable()"));

    ClassSubject classA = inspector.clazz(A.class);
    assertThat(classA, isPresent());

    MethodSubject notInlineableMethod = classA.uniqueMethodWithName("notInlineable");
    assertThat(notInlineableMethod, isPresent());

    MethodSubject testMethod = inspector.clazz(mainClass).uniqueMethodWithName("test");
    assertThat(testMethod, isPresent());
    assertThat(testMethod, invokesMethod(notInlineableMethod));
  }

  @Test
  public void testClass7() throws Exception {
    Class<TestClass7> mainClass = TestClass7.class;
    CodeInspector inspector =
        buildAndRun(
            mainClass,
            StringUtils.lines(
                "Caught NullPointerException",
                "In A.<clinit>()",
                "Field A.instanceField",
                "In A.inlineable()"));

    ClassSubject classA = inspector.clazz(A.class);
    assertThat(classA, isPresent());

    MethodSubject inlineableMethod = classA.uniqueMethodWithName("inlineable");
    assertThat(inlineableMethod, not(isPresent()));
  }

  @Test
  public void testClass8() throws Exception {
    Class<TestClass8> mainClass = TestClass8.class;
    CodeInspector inspector =
        buildAndRun(
            mainClass,
            StringUtils.lines(
                "In A.<clinit>()", "In A.notInlineable()", "In A.alsoNotInlineable()"));

    ClassSubject classA = inspector.clazz(A.class);
    assertThat(classA, isPresent());

    MethodSubject notInlineableMethod = classA.uniqueMethodWithName("notInlineable");
    assertThat(notInlineableMethod, isPresent());

    MethodSubject alsoNotInlineableMethod = classA.uniqueMethodWithName("alsoNotInlineable");
    assertThat(alsoNotInlineableMethod, isPresent());

    MethodSubject testMethod = inspector.clazz(mainClass).mainMethod();
    assertThat(testMethod, isPresent());
    assertThat(testMethod, invokesMethod(notInlineableMethod));
    assertThat(testMethod, invokesMethod(alsoNotInlineableMethod));
  }

  @Test
  public void testClass9() throws Exception {
    Class<TestClass9> mainClass = TestClass9.class;
    CodeInspector inspector =
        buildAndRun(
            mainClass,
            StringUtils.lines("In A.<clinit>()", "Field A.staticField", "In A.notInlineable()"));

    ClassSubject classA = inspector.clazz(A.class);
    assertThat(classA, isPresent());

    MethodSubject notInlineableMethod = classA.uniqueMethodWithName("notInlineable");
    assertThat(notInlineableMethod, isPresent());

    MethodSubject testMethod = inspector.clazz(mainClass).mainMethod();
    assertThat(testMethod, isPresent());
    assertThat(testMethod, invokesMethod(notInlineableMethod));
  }

  @Test
  public void testClass10() throws Exception {
    Class<TestClass10> mainClass = TestClass10.class;
    CodeInspector inspector =
        buildAndRun(mainClass, StringUtils.lines("In A.<clinit>()", "In A.inlineable()"));

    ClassSubject classA = inspector.clazz(A.class);
    assertThat(classA, isPresent());

    MethodSubject inlineableMethod = classA.uniqueMethodWithName("inlineable");
    assertThat(inlineableMethod, not(isPresent()));
  }

  private CodeInspector buildAndRun(Class<?> mainClass, String expectedOutput) throws Exception {
    if (parameters.isCfRuntime()) {
      testForJvm()
          .addTestClasspath()
          .run(parameters.getRuntime(), mainClass)
          .assertSuccessWithOutput(expectedOutput);
    }

    return testForR8(parameters.getBackend())
        .addInnerClasses(InliningAfterClassInitializationTest.class)
        .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P))
        .addKeepMainRule(mainClass)
        .addOptionsModification(
            options -> options.enableInliningOfInvokesWithClassInitializationSideEffects = false)
        .enableConstantArgumentAnnotations()
        .enableInliningAnnotations()
        .setMinApi(parameters.getApiLevel())
        .run(parameters.getRuntime(), mainClass)
        .assertSuccessWithOutput(expectedOutput)
        .inspector();
  }

  static class TestClass1 {

    public static void main(String[] args) {
      A.notInlineable();

      // Since the previous call will cause the initializer of A to run, we can safely inline this
      // call.
      A.inlineable();
    }
  }

  static class TestClass2 {

    public static void main(String[] args) {
      System.out.println(A.staticField);

      // Since the previous instruction will cause the initializer of A to run, we can safely inline
      // this call.
      A.inlineable();
    }
  }

  static class TestClass3 {

    public static void main(String[] args) {
      A.staticField = "Hello world!";

      // Since the previous instruction will cause the initializer of A to run, we can safely inline
      // this call.
      A.inlineable();

      // Make sure the field is read to prevent the static-put instruction from being removed
      // (b/123553485).
      spuriousFieldRead();
    }

    private static void spuriousFieldRead() {
      if (System.currentTimeMillis() < 0) {
        System.out.println(A.staticField);
      }
    }
  }

  static class TestClass4 {

    public static void main(String[] args) {
      test(new A());
    }

    @NeverInline
    private static void test(A obj) {
      System.out.println(obj.instanceField);

      // Since the previous instruction will cause the initializer of A to run, we can safely inline
      // this call.
      A.inlineable();
    }
  }

  static class TestClass5 {

    public static void main(String[] args) {
      test(new A());
    }

    @NeverInline
    private static void test(A obj) {
      obj.instanceField = "Hello world!";

      // Since the previous instruction will cause the initializer of A to run, we can safely inline
      // this call.
      A.inlineable();

      // Make sure the field is read to prevent the instance-put instruction from being removed.
      spuriousFieldRead(obj);
    }

    private static void spuriousFieldRead(A obj) {
      if (System.currentTimeMillis() < 0) {
        System.out.println(obj.instanceField);
      }
    }
  }

  static class TestClass6 {

    public static void main(String[] args) {
      test(null);
    }

    @KeepConstantArguments
    @NeverInline
    private static void test(A obj) {
      try {
        String value = obj.instanceField;
        System.out.println(value);
      } catch (NullPointerException e) {
        // Ignore.
      }

      // This call cannot be inlined because `obj.field` may throw a NullPointerException, in which
      // case A is not guaranteed to be initialized.
      A.notInlineable();
    }
  }

  static class TestClass7 {

    public static void main(String[] args) {
      test(null);
      test(new A());
    }

    @NeverInline
    private static void test(A obj) {
      try {
        String value = obj.instanceField;
        System.out.println(value);
      } catch (NullPointerException e) {
        // Ignore.
        System.out.println("Caught NullPointerException");
        return;
      }

      // Due to the `return` in the catch handler above, A is guaranteed to be initialized if we
      // reach this line.
      A.inlineable();
    }
  }

  static class TestClass8 {

    public static void main(String[] args) {
      try {
        A.notInlineable();
      } catch (ExceptionInInitializerError e) {
        System.out.println("Caught ExceptionInInitializerError");
      }

      A.alsoNotInlineable();
    }
  }

  static class TestClass9 {

    public static void main(String[] args) {
      try {
        String value = A.staticField;
        System.out.println(value);
      } catch (ExceptionInInitializerError e) {
        System.out.println("Caught ExceptionInInitializerError");
      }

      A.notInlineable();
    }
  }

  static class TestClass10 {

    public static void main(String[] args) {
      test(new A());
    }

    @NeverInline
    private static void test(A obj) {
      Objects.requireNonNull(obj);

      // A is guaranteed to be initialized since requireNonNull() will throw if `obj` is null.
      A.inlineable();
    }
  }

  static class A {

    public String instanceField = "Field A.instanceField";
    public static String staticField =
        System.currentTimeMillis() >= 0 ? "Field A.staticField" : null;

    static {
      System.out.println("In A.<clinit>()");
    }

    static void notInlineable() {
      System.out.println("In A.notInlineable()");
    }

    static void alsoNotInlineable() {
      System.out.println("In A.alsoNotInlineable()");
    }

    static void inlineable() {
      System.out.println("In A.inlineable()");
    }
  }
}
