// 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.ir.optimize.inliner;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import com.android.tools.r8.NeverInline;
import com.android.tools.r8.R8TestRunResult;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.ToolHelper.DexVm.Version;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Streams;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

/** This test extends that of Regress131349148 for other API-introduced exceptions. */
@RunWith(Parameterized.class)
public class InlineCatchHandlerWithLibraryTypeTest extends TestBase {

  private static final String TEMPLATE_CODE_EXCEPTION_BINARY_NAME = "java/lang/RuntimeException";

  // A subset of exception types introduced in API levels between 16 to 24.
  private static final Map<String, Integer> EXCEPTIONS =
      ImmutableMap.<String, Integer>builder()
          // VM 4.0.4 (api 15) is the first VM we have so no need to go prior to that.
          .put("android.media.MediaCryptoException", 16)
          .put("android.view.WindowManager$InvalidDisplayException", 17)
          .put("android.media.DeniedByServerException", 18)
          .put("android.media.ResourceBusyException", 19)
          .put("java.lang.ReflectiveOperationException", 19)
          .put("javax.crypto.AEADBadTagException", 19)
          .put("android.system.ErrnoException", 21)
          .put("android.media.MediaDrmResetException", 23)
          .put("java.io.UncheckedIOException", 24)
          .put("java.util.concurrent.CompletionException", 24)
          // Verify error was fixed in 21 so up to 24 should catch post-fix issues.
          .build();

  private static final String EXPECTED = StringUtils.lines("Done...");

  private final TestParameters parameters;
  private final String exception;

  @Parameters(name = "{0}, {1}")
  public static List<Object[]> params() {
    return buildParameters(
        getTestParameters().withAllRuntimesAndApiLevels().build(),
        new TreeSet<>(EXCEPTIONS.keySet()));
  }

  public InlineCatchHandlerWithLibraryTypeTest(TestParameters parameters, String exception) {
    this.parameters = parameters;
    this.exception = exception;
  }

  private String getExceptionBinaryName() {
    return DescriptorUtils.getBinaryNameFromJavaType(exception);
  }

  private byte[] getClassWithCatchHandler() throws IOException {
    return transformer(ClassWithCatchHandler.class)
        .transformTryCatchBlock(
            "methodWithCatch",
            (start, end, handler, type, continuation) -> {
              String newType =
                  type.equals(TEMPLATE_CODE_EXCEPTION_BINARY_NAME)
                      ? getExceptionBinaryName()
                      : type;
              continuation.visitTryCatchBlock(start, end, handler, newType);
            })
        .transform();
  }

  private boolean compilationTargetIsMissingExceptionType() {
    // A CF target could target any API in the end.
    return parameters.isCfRuntime()
        || parameters.getApiLevel().getLevel() < EXCEPTIONS.get(exception);
  }

  private boolean compileTargetHasVerificationBug() {
    // A CF target could target any API in the end.
    return parameters.isCfRuntime() || parameters.getApiLevel().isLessThan(AndroidApiLevel.L);
  }

  @Test
  public void test() throws Exception {
    testForR8(parameters.getBackend())
        .enableInliningAnnotations()
        .addProgramClasses(TestClass.class)
        .addProgramClassFileData(getClassWithCatchHandler())
        .addKeepMainRule(TestClass.class)
        .setMinApi(parameters.getApiLevel())
        // Use the latest library so that all of the exceptions are defined.
        .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.LATEST))
        .compile()
        .inspect(this::checkInlined)
        .run(parameters.getRuntime(), TestClass.class)
        .apply(this::checkResult);
  }

  private void checkResult(R8TestRunResult runResult) {
    // The bootclasspath for our build of 4.4.4 does not contain various bits. Allow verify error.
    if (!compilationTargetIsMissingExceptionType()
        && parameters.getRuntime().asDex().getVm().getVersion().equals(Version.V4_4_4)
        && (exception.startsWith("android.media") || exception.startsWith("android.view"))) {
      runResult.assertFailureWithErrorThatThrows(VerifyError.class);
      return;
    }
    // Correct compilation should ensure that all programs run without error.
    runResult.assertSuccessWithOutput(EXPECTED);
  }

  private void checkInlined(CodeInspector inspector) {
    ClassSubject classSubject = inspector.clazz(TestClass.class);
    boolean mainHasInlinedCatchHandler =
        Streams.stream(classSubject.mainMethod().iterateTryCatches())
            .anyMatch(tryCatch -> tryCatch.isCatching(exception));
    if (compileTargetHasVerificationBug() && compilationTargetIsMissingExceptionType()) {
      assertFalse(mainHasInlinedCatchHandler);
    } else {
      assertTrue(mainHasInlinedCatchHandler);
    }
  }

  static class TestClass {

    public static void main(String[] args) {
      if (args.length == 200) {
        // Never called
        ClassWithCatchHandler.methodWithCatch();
      }
      System.out.println("Done...");
    }
  }

  static class ClassWithCatchHandler {

    @NeverInline
    public static void maybeThrow() {
      if (System.nanoTime() > 0) {
        throw new RuntimeException();
      }
    }

    public static void methodWithCatch() {
      try {
        maybeThrow();
      } catch (RuntimeException e) {
        // We must use the exception, otherwise there is no move-exception that triggers the
        // verification error.
        System.out.println(e.getClass().getName());
      }
    }
  }
}
