// Copyright (c) 2020, 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.rewrite.assertions;

import static org.junit.Assert.assertEquals;

import com.android.tools.r8.AssertionsConfiguration;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.TestRuntime;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.ToolHelper.ProcessResult;
import com.android.tools.r8.references.Reference;
import com.android.tools.r8.rewrite.assertions.testclasses.A;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import org.junit.Assume;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.objectweb.asm.Opcodes;

@RunWith(Parameterized.class)
public class AssertionsConfigurationJacocoTest extends TestBase implements Opcodes {

  private final TestParameters parameters;

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

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

  private void checkAssertionCodeEnabled(CodeInspector inspector) {
    AssertionsCheckerUtils.checkAssertionCodeEnabled(inspector.clazz(A.class), "m");
  }

  @Test
  public void testD8() throws Exception {
    Assume.assumeTrue(parameters.isDexRuntime());
    testForD8()
        .addProgramClasses(TestClass.class, MockJacocoInit.class)
        .addProgramClassFileData(transformClassWithJacocoInstrumentation(A.class))
        .setMinApi(parameters.getApiLevel())
        .addAssertionsConfiguration(AssertionsConfiguration.Builder::enableAllAssertions)
        .run(parameters.getRuntime(), TestClass.class)
        .inspect(this::checkAssertionCodeEnabled)
        .assertSuccessWithOutputLines("AssertionError in A");
  }

  @Test
  public void testR8() throws Exception {
    testForR8(parameters.getBackend())
        .addProgramClasses(TestClass.class, MockJacocoInit.class)
        .addProgramClassFileData(transformClassWithJacocoInstrumentation(A.class))
        .addKeepMainRule(TestClass.class)
        .addKeepClassAndMembersRules(A.class, MockJacocoInit.class)
        .setMinApi(parameters.getApiLevel())
        .addAssertionsConfiguration(AssertionsConfiguration.Builder::enableAllAssertions)
        .run(parameters.getRuntime(), TestClass.class)
        .inspect(this::checkAssertionCodeEnabled)
        .assertSuccessWithOutputLines("AssertionError in A");
  }

  private byte[] transformClassWithJacocoInstrumentation(Class<?> clazz) throws IOException {
    // Instrument the class with Jacoco.
    Path dir = temp.newFolder().toPath();
    runJacoco(ToolHelper.getClassFileForTestClass(clazz), dir);
    // Rewrite the invocation of Jacoco initialization (getProbes invocation) for class with a Mock.
    Path jacoco =
        dir.resolve(
            A.class.getTypeName().substring(clazz.getPackage().getName().length() + 1) + ".class");
    return transformer(jacoco, Reference.classFromClass(clazz))
        .transformMethodInsnInMethod(
            "$jacocoInit",
            (opcode, owner, name, descriptor, isInterface, continuation) -> {
              assertEquals(INVOKESTATIC, opcode);
              assertEquals("getProbes", name);
              continuation.visitMethodInsn(
                  INVOKESTATIC,
                  DescriptorUtils.getClassBinaryName(MockJacocoInit.class),
                  "getProbes",
                  descriptor,
                  isInterface);
            })
        .transform();
  }

  private void runJacoco(Path input, Path outdir) throws IOException {
    List<String> cmdline = new ArrayList<>();
    cmdline.add(TestRuntime.getSystemRuntime().asCf().getJavaExecutable().toString());
    cmdline.add("-jar");
    cmdline.add(ToolHelper.JACOCO_CLI);
    cmdline.add("instrument");
    cmdline.add(input.toString());
    cmdline.add("--dest");
    cmdline.add(outdir.toString());
    ProcessBuilder builder = new ProcessBuilder(cmdline);
    ProcessResult javacResult = ToolHelper.runProcess(builder);
    assertEquals(javacResult.toString(), 0, javacResult.exitCode);
  }

  public static class MockJacocoInit {

    public static boolean[] getProbes(long a, String b, int c) {
      // For the test class A an array of size 6 is sufficient.
      return new boolean[6];
    }
  }

  static class TestClass {

    public static void main(String[] args) {
      try {
        A.m();
      } catch (AssertionError e) {
        System.out.println("AssertionError in A");
      }
    }
  }

  // The test class A cannot be an inner class of AssertionsConfigurationJacocoTest, as then the
  // desiredAssertionStatus() on the outer AssertionsConfigurationJacocoTest will be used and
  // and that is not part of the input.
}
