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

import static com.android.tools.r8.apimodel.ApiModelingTestHelper.setMockApiLevelForClass;
import static com.android.tools.r8.apimodel.ApiModelingTestHelper.verifyThat;
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.NoHorizontalClassMerging;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.utils.AndroidApiLevel;
import java.lang.reflect.Method;
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 ApiModelInlineMethodWithApiTypeTest extends TestBase {

  private final TestParameters parameters;

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

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

  @Test
  public void testR8() throws Exception {
    Method apiCallerApiLevel22 = ApiCaller.class.getDeclaredMethod("apiLevel22");
    Method apiCallerCallerApiLevel22 = ApiCallerCaller.class.getDeclaredMethod("apiLevel22");
    testForR8(parameters.getBackend())
        .addProgramClasses(ApiCaller.class, ApiCallerCaller.class, OtherCaller.class, Main.class)
        .addLibraryClasses(ApiType.class)
        .addDefaultRuntimeLibrary(parameters)
        .setMinApi(parameters.getApiLevel())
        .addKeepMainRule(Main.class)
        .enableNoHorizontalClassMergingAnnotations()
        .apply(setMockApiLevelForClass(ApiType.class, AndroidApiLevel.L_MR1))
        .apply(ApiModelingTestHelper::enableApiCallerIdentification)
        .compile()
        .addRunClasspathClasses(ApiType.class)
        .run(parameters.getRuntime(), Main.class)
        .assertSuccessWithOutputLines(ApiType.class.getName())
        .inspect(
            inspector -> {
              verifyThat(inspector, parameters, apiCallerApiLevel22)
                  .inlinedInto(apiCallerCallerApiLevel22);
              assertThat(inspector.clazz(OtherCaller.class), not(isPresent()));
            });
  }

  public static class ApiType {}

  @NoHorizontalClassMerging
  public static class ApiCaller {

    public static ApiType apiLevel22() throws Exception {
      // The reflective call here is to ensure that the setting of A's api level is not based on
      // a method reference to `Api` and only because of the type reference in the field `api`.
      Class<?> reflectiveCall =
          Class.forName(
              "com.android.tools.r8.apimodel.ApiModelInlineMethodWithApiTypeTest_ApiType"
                  .replace("_", "$"));
      return (ApiType) reflectiveCall.getDeclaredConstructor().newInstance();
    }
  }

  @NoHorizontalClassMerging
  public static class ApiCallerCaller {

    public static void apiLevel22() throws Exception {
      // This is referencing the proto of ApiCaller.foo and thus have a reference to ApiType. It is
      // therefore OK to inline ApiCaller.foo() into ApiCallerCaller.bar().
      System.out.println(ApiCaller.apiLevel22().getClass().getName());
    }
  }

  @NoHorizontalClassMerging
  public static class OtherCaller {

    public static void apiLevel1() throws Exception {
      // ApiCallerCaller.apiLevel22 should never be inlined here.
      ApiCallerCaller.apiLevel22();
    }
  }

  public static class Main {

    public static void main(String[] args) throws Exception {
      OtherCaller.apiLevel1();
    }
  }
}
