// 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.accessesField;
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.NeverInline;
import com.android.tools.r8.NeverMerge;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
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 org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

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

  private final TestParameters parameters;

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

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

  @Test
  public void test() throws Exception {
    String expectedOutput =
        StringUtils.lines(
            "In A.<clinit>()",
            "In B.<clinit>()",
            "In A.inlineable1()",
            "In B.inlineable2()",
            "In C.<clinit>()",
            "In C.inlineableWithInitClass()");

    testForJvm().addTestClasspath().run(TestClass.class).assertSuccessWithOutput(expectedOutput);

    CodeInspector inspector =
        testForR8(parameters.getBackend())
            .addInnerClasses(InliningFromCurrentClassTest.class)
            .addKeepMainRule(TestClass.class)
            .enableInliningAnnotations()
            .enableMergeAnnotations()
            .setMinApi(parameters.getApiLevel())
            .run(parameters.getRuntime(), TestClass.class)
            .assertSuccessWithOutput(expectedOutput)
            .inspector();

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

    ClassSubject classB = inspector.clazz(B.class);
    assertThat(classB, isPresent());

    ClassSubject classC = inspector.clazz(C.class);
    assertThat(classC, isPresent());

    MethodSubject testMethod = classB.uniqueMethodWithName("test");
    assertThat(testMethod, isPresent());

    MethodSubject inlineable1Method = classA.uniqueMethodWithName("inlineable1");
    assertThat(inlineable1Method, not(isPresent()));

    MethodSubject inlineable2Method = classB.uniqueMethodWithName("inlineable2");
    assertThat(inlineable2Method, not(isPresent()));

    MethodSubject inlineableWithInitClassMethod =
        classC.uniqueMethodWithName("inlineableWithInitClass");
    assertThat(inlineableWithInitClassMethod, not(isPresent()));
    assertThat(testMethod, accessesField(classC.uniqueFieldWithName("$r8$clinit")));
  }

  static class TestClass {

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

  @NeverMerge
  static class A {

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

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

  @NeverMerge
  static class B extends A {

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

    @NeverInline
    static void test() {
      A.inlineable1();
      B.inlineable2();
      C.inlineableWithInitClass();
    }

    static void inlineable2() {
      System.out.println("In B.inlineable2()");
    }
  }

  static class C extends B {

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

    static void inlineableWithInitClass() {
      System.out.println("In C.inlineableWithInitClass()");
    }
  }
}
