// Copyright (c) 2022, 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.desugar.jdk8272564;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;

import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.TestRuntime.CfVm;
import com.android.tools.r8.examples.jdk18.jdk8272564.Jdk8272564;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.InstructionSubject;
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 Jdk8272564Test extends TestBase {

  @Parameters(name = "{0}")
  public static TestParametersCollection data() {
    // TODO(b/218293990): Right now the JDK 18 tests are built with -target 17, as our Gradle
    //  version does not know of -target 18.
    return getTestParameters()
        .withCfRuntimesStartingFromIncluding(CfVm.JDK17)
        .withDexRuntimes()
        .withAllApiLevelsAlsoForCf()
        .build();
  }

  @Parameter(0)
  public TestParameters parameters;

  // With the fix for JDK-8272564 there are no invokevirtual instructions.
  private void assertJdk8272564FixedCode(CodeInspector inspector) {
    assertTrue(
        inspector
            .clazz(Jdk8272564.Main.typeName())
            .uniqueMethodWithName("f")
            .streamInstructions()
            .noneMatch(InstructionSubject::isInvokeVirtual));
    assertTrue(
        inspector
            .clazz(Jdk8272564.Main.typeName())
            .uniqueMethodWithName("g")
            .streamInstructions()
            .noneMatch(InstructionSubject::isInvokeVirtual));
  }

  // Without the fix for JDK-8272564 there is one invokeinterface and 2 invokevirtual instructions.
  private void assertJdk8272564NotFixedCode(
      CodeInspector inspector, int invokeVirtualCount, int getClassCount) {
    assertEquals(
        1,
        inspector
            .clazz(Jdk8272564.Main.typeName())
            .uniqueMethodWithName("f")
            .streamInstructions()
            .filter(InstructionSubject::isInvokeInterface)
            .count());
    assertEquals(
        2,
        inspector
            .clazz(Jdk8272564.Main.typeName())
            .uniqueMethodWithName("f")
            .streamInstructions()
            .filter(InstructionSubject::isInvokeVirtual)
            .count());
    assertEquals(
        2,
        inspector
            .clazz(Jdk8272564.Main.typeName())
            .uniqueMethodWithName("g")
            .streamInstructions()
            .filter(InstructionSubject::isInvokeInterface)
            .count());
    assertEquals(
        2,
        inspector
            .clazz(Jdk8272564.Main.typeName())
            .uniqueMethodWithName("g")
            .streamInstructions()
            .filter(InstructionSubject::isInvokeInterface)
            .count());
    assertEquals(
        invokeVirtualCount,
        inspector
            .clazz(Jdk8272564.Main.typeName())
            .uniqueMethodWithName("g")
            .streamInstructions()
            .filter(InstructionSubject::isInvokeVirtual)
            .count());
    assertEquals(
        getClassCount,
        inspector
            .clazz(Jdk8272564.Main.typeName())
            .uniqueMethodWithName("g")
            .streamInstructions()
            .filter(InstructionSubject::isInvoke)
            .filter(instruction -> instruction.getMethod().getName().toString().equals("getClass"))
            .count());
  }

  private void assertJdk8272564NotFixedCode(CodeInspector inspector) {
    assertJdk8272564NotFixedCode(inspector, 22, 3);
  }

  private void assertJdk8272564NotFixedCodeR8(CodeInspector inspector) {
    assertJdk8272564NotFixedCode(inspector, 19, 0);
  }

  private boolean isDefaultCfParameters() {
    return parameters.isCfRuntime() && parameters.getApiLevel().equals(AndroidApiLevel.B);
  }

  @Test
  // See https://bugs.openjdk.java.net/browse/JDK-8272564.
  public void testJdk8272564Compiler() throws Exception {
    assumeTrue(isDefaultCfParameters());
    // Ensure that the test is running with CF input from fixing JDK-8272564.
    assertJdk8272564FixedCode(new CodeInspector(Jdk8272564.jar()));
  }

  @Test
  public void testJvm() throws Exception {
    assumeTrue(isDefaultCfParameters());
    testForJvm()
        .addRunClasspathFiles(Jdk8272564.jar())
        .run(parameters.getRuntime(), Jdk8272564.Main.typeName())
        .assertSuccess();
  }

  @Test
  public void testD8() throws Exception {
    testForDesugaring(parameters)
        .addProgramFiles(Jdk8272564.jar())
        .run(parameters.getRuntime(), Jdk8272564.Main.typeName())
        .applyIf(
            parameters.isDexRuntime() && parameters.getApiLevel().isLessThan(AndroidApiLevel.P),
            b -> b.inspect(this::assertJdk8272564NotFixedCode),
            b -> b.inspect(this::assertJdk8272564FixedCode))
        .assertSuccess();
  }

  @Test
  public void testR8() throws Exception {
    assumeTrue(parameters.isDexRuntime() || isDefaultCfParameters());
    // The R8 lens code rewriter rewrites to the code prior to fixing JDK-8272564.
    testForR8(parameters.getBackend())
        .addProgramFiles(Jdk8272564.jar())
        .setMinApi(parameters.getApiLevel())
        .noTreeShaking()
        .addKeepClassAndMembersRules(Jdk8272564.Main.typeName())
        .run(parameters.getRuntime(), Jdk8272564.Main.typeName())
        .inspect(this::assertJdk8272564NotFixedCodeR8)
        .assertSuccess();
  }
}
