// 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.memberrebinding;

import static com.android.tools.r8.apimodel.ApiModelingTestHelper.setMockApiLevelForMethod;
import static com.android.tools.r8.utils.codeinspector.CodeMatchers.invokesMethod;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static java.util.Collections.emptyList;
import static org.hamcrest.MatcherAssert.assertThat;

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 com.android.tools.r8.utils.codeinspector.MethodSubject;
import com.google.common.collect.ImmutableList;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Collection;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;

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

  private static Path oldRuntimeJar;
  private static Path newRuntimeJar;

  @Parameter(0)
  public TestParameters parameters;

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

  @BeforeClass
  public static void compileCustomLib() throws Exception {
    oldRuntimeJar =
        createJar(
            ImmutableList.of(LibraryI.class, LibraryB.class, LibraryC.class),
            getProgramClassFileDataWithoutMethods(LibraryA.class));
    newRuntimeJar =
        createJar(ImmutableList.of(LibraryI.class, LibraryA.class, LibraryB.class, LibraryC.class));
  }

  // Tests old android.jar with old runtime.
  @Test
  public void testEmptyAAtCompileTimeAndRuntime() throws Exception {
    test(oldRuntimeJar, oldRuntimeJar);
  }

  // Tests new android.jar with new runtime.
  @Test
  public void testNonEmptyAAtCompileTimeAndRuntime() throws Exception {
    test(newRuntimeJar, newRuntimeJar);
  }

  // Tests old android.jar with new runtime.
  @Test
  public void testEmptyAAtCompileTime() throws Exception {
    test(oldRuntimeJar, newRuntimeJar);
  }

  // Tests new android.jar with old runtime.
  @Test
  public void testEmptyAAtRuntimeTime() throws Exception {
    test(newRuntimeJar, oldRuntimeJar);
  }

  private void test(Path compileTimeLibrary, Path runtimeLibrary) throws Exception {
    testForR8(parameters.getBackend())
        .addProgramClasses(Main.class)
        .addKeepClassAndMembersRules(Main.class)
        .addLibraryFiles(compileTimeLibrary)
        .addDefaultRuntimeLibrary(parameters)
        .apply(setMockApiLevelForMethod(LibraryI.class.getDeclaredMethod("m"), AndroidApiLevel.B))
        .apply(setMockApiLevelForMethod(LibraryC.class.getDeclaredMethod("m"), AndroidApiLevel.B))
        .apply(setMockApiLevelForMethod(LibraryA.class.getDeclaredMethod("m"), AndroidApiLevel.N))
        .setMinApi(parameters.getApiLevel())
        .compile()
        .inspect(
            inspector -> {
              MethodSubject testMethodSubject =
                  inspector.clazz(Main.class).uniqueMethodWithName("test");
              assertThat(testMethodSubject, isPresent());
              assertThat(
                  testMethodSubject,
                  invokesMethod(
                      "int",
                      getExpectedMemberRebindingTarget(compileTimeLibrary).getTypeName(),
                      "m",
                      emptyList()));
            })
        .addRunClasspathFiles(buildOnDexRuntime(parameters, runtimeLibrary))
        .run(parameters.getRuntime(), Main.class)
        .applyIf(
            // Compiling to an API level above the API where LibraryA.m() was defined with a new
            // android.jar, and running this on an older runtime (correctly) results in a NSME.
            parameters.isDexRuntime()
                && parameters.getApiLevel().isGreaterThanOrEqualTo(AndroidApiLevel.N)
                && compileTimeLibrary == newRuntimeJar
                && runtimeLibrary == oldRuntimeJar,
            runResult -> runResult.assertFailureWithErrorThatThrows(NoSuchMethodError.class),
            runResult -> runResult.assertSuccessWithOutputLines("42"));
  }

  private Class<?> getExpectedMemberRebindingTarget(Path compileTimeLibrary) {
    if (compileTimeLibrary == newRuntimeJar) {
      // If we are compiling to a new runtime with a new android.jar, we should rebind to LibraryA.
      if (parameters.isDexRuntime()
          && parameters.getApiLevel().isGreaterThanOrEqualTo(AndroidApiLevel.N)) {
        return LibraryA.class;
      }
      // If we are compiling to an old runtime with a new android.jar, we should rebind to LibraryB.
      return LibraryB.class;
    }
    // Otherwise, we are compiling to an old android.jar, in which case we should rebind to
    // LibraryI.
    return LibraryI.class;
  }

  private static Path createJar(Collection<Class<?>> programClasses, byte[]... programClassFileData)
      throws Exception {
    return testForR8(getStaticTemp(), Backend.CF)
        .addProgramClasses(programClasses)
        .addProgramClassFileData(programClassFileData)
        .addKeepAllClassesRule()
        .compile()
        .writeToZip();
  }

  private static byte[] getProgramClassFileDataWithoutMethods(Class<?> clazz) throws IOException {
    return transformer(clazz)
        .removeMethods(
            (int access, String name, String descriptor, String signature, String[] exceptions) ->
                !name.equals("<init>"))
        .transform();
  }

  public static class Main {

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

    private static void test(LibraryB b) {
      System.out.println(b.m());
    }
  }

  public interface LibraryI {

    int m();
  }

  public static class LibraryA {

    // Added in API N, so we can't rebind to this in APIs < N.
    public int m() {
      return 42;
    }
  }

  public abstract static class LibraryB extends LibraryA implements LibraryI {}

  public static class LibraryC extends LibraryB {

    @Override
    public int m() {
      return 42;
    }
  }
}
