// 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.graph.initializedclasses;

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.NeverClassInline;
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.NoHorizontalClassMerging;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

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

  private final boolean enableInitializedClassesInInstanceMethodsAnalysis;
  private final TestParameters parameters;

  @Parameters(name = "{1}, enabled: {0}")
  public static List<Object[]> data() {
    return buildParameters(
        BooleanUtils.values(), getTestParameters().withAllRuntimesAndApiLevels().build());
  }

  public InitializedClassesInInstanceMethodsTest(
      boolean enableInitializedClassesInInstanceMethodsAnalysis, TestParameters parameters) {
    this.enableInitializedClassesInInstanceMethodsAnalysis =
        enableInitializedClassesInInstanceMethodsAnalysis;
    this.parameters = parameters;
  }

  @Test
  public void test() throws Exception {
    testForR8(parameters.getBackend())
        .addInnerClasses(InitializedClassesInInstanceMethodsTest.class)
        .addKeepMainRule(TestClass.class)
        .addOptionsModification(
            options -> {
              options.enableInitializedClassesInInstanceMethodsAnalysis =
                  enableInitializedClassesInInstanceMethodsAnalysis;
            })
        .allowAccessModification()
        .enableNeverClassInliningAnnotations()
        .enableNoHorizontalClassMergingAnnotations()
        .enableInliningAnnotations()
        .setMinApi(parameters)
        .compile()
        .inspect(this::verifyOutput)
        .run(parameters.getRuntime(), TestClass.class)
        .assertSuccessWithOutputLines("Hello world!");
  }

  private void verifyOutput(CodeInspector inspector) {
    ClassSubject outerClassSubject = inspector.clazz(Outer.class);
    assertThat(outerClassSubject, isPresent());

    // In any case, Outer.hello(), Outer.world(), and Outer.exclamationMark() should be inlined into
    // the accessibility bridges.
    assertThat(outerClassSubject.uniqueMethodWithOriginalName("hello"), not(isPresent()));
    assertThat(outerClassSubject.uniqueMethodWithOriginalName("world"), not(isPresent()));
    assertThat(outerClassSubject.uniqueMethodWithOriginalName("exclamationMark"), not(isPresent()));

    int numberOfExpectedAccessibilityBridges = 0;
    assertEquals(
        numberOfExpectedAccessibilityBridges,
        outerClassSubject
            .allMethods(method -> method.getOriginalName().contains("access$"))
            .size());
    assertEquals(
        !enableInitializedClassesInInstanceMethodsAnalysis,
        outerClassSubject.uniqueFieldWithOriginalName("$r8$clinit").isPresent());

    ClassSubject aClassSubject = inspector.clazz(Outer.A.class);
    assertThat(aClassSubject, isPresent());
    assertThat(aClassSubject.uniqueMethodWithOriginalName("hello"), isPresent());

    ClassSubject bClassSubject = inspector.clazz(Outer.B.class);
    assertThat(bClassSubject, isPresent());
    assertThat(bClassSubject.uniqueMethodWithOriginalName("world"), isPresent());

    ClassSubject cClassSubject = inspector.clazz(C.class);
    assertThat(cClassSubject, isPresent());
    assertThat(cClassSubject.uniqueMethodWithOriginalName("exclamationMark"), isPresent());
  }

  static class TestClass {

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

  static class Outer {

    static {
      // To ensure that we consider the class initialization of TestClass as having side effects.
      System.out.print("");
    }

    public void test() {
      new A().hello();
      new B().world(this);
      new C().exclamationMark(this);
    }

    private void hello() {
      System.out.print("Hello");
    }

    private void world() {
      System.out.print(" world");
    }

    private void exclamationMark() {
      System.out.println("!");
    }

    @NeverClassInline
    class A {

      @NeverInline
      void hello() {
        Outer.this.hello();
      }
    }

    @NeverClassInline
    @NoHorizontalClassMerging
    static class B {

      @NeverInline
      void world(Outer outer) {
        outer.world();
      }
    }
  }

  @NeverClassInline
  static class C {

    @NeverInline
    void exclamationMark(Outer outer) {
      outer.exclamationMark();
    }
  }
}
