// Copyright (c) 2016, 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;

import static org.junit.Assert.assertEquals;

import com.android.tools.r8.ToolHelper.DexVm;
import com.android.tools.r8.ToolHelper.DexVm.Version;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.TestDescriptionWatcher;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

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

  @Rule
  public ExpectedException thrown = ExpectedException.none();

  @Parameters(name = "{0}: {1}")
  public static Collection<Object[]> data() {
    return buildParameters(
        getTestParameters().withDexRuntimesAndAllApiLevels().build(), tests.keySet());
  }

  private static final String SMALI_DIR = ToolHelper.SMALI_BUILD_DIR;

  private static Map<String, String> tests;

  static {
    ImmutableMap.Builder<String, String> testsBuilder = ImmutableMap.builder();
    testsBuilder
        .put(
            "arithmetic",
            StringUtils.lines(
                "-1", "3", "2", "3", "3.0", "1", "0", "-131580", "-131580", "2", "4", "-2"))
        .put(
            "controlflow",
            StringUtils.lines("2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2"))
        .put("fibonacci", StringUtils.lines("55", "55", "55", "55"))
        .put("fill-array-data", "[1, 2, 3][4, 5, 6]")
        .put("filled-new-array", "[1, 2, 3][4, 5, 6][1, 2, 3, 4, 5, 6][6, 5, 4, 3, 2, 1]")
        .put("packed-switch", "12345")
        .put("sparse-switch", "12345")
        .put("unreachable-code-1", "777")
        .put(
            "multiple-returns",
            StringUtils.lines("TFtf", "1", "4611686018427387904", "true", "false"))
        .put("try-catch", "")
        .put("phi-removal-regression", StringUtils.lines("returnBoolean"))
        .put(
            "overlapping-long-registers",
            StringUtils.lines("-9151314442816847872", "-9151314442816319488"))
        .put(
            "type-confusion-regression",
            StringUtils.lines("java.lang.RuntimeException: Test.<init>()"))
        .put(
            "type-confusion-regression2",
            StringUtils.lines("java.lang.NullPointerException: Attempt to read from null array"))
        .put(
            "type-confusion-regression3",
            StringUtils.lines(
                "java.lang.NullPointerException: Attempt to read from field 'byte[] Test.a'"
                    + " on a null object reference"))
        .put("type-confusion-regression4", "")
        .put(
            "type-confusion-regression5", StringUtils.lines("java.lang.RuntimeException: getId()I"))
        .put("chain-of-loops", StringUtils.lines("java.lang.RuntimeException: f(II)"))
        .put("new-instance-and-init", StringUtils.lines("Test(0)", "Test(0)", "Test(0)"))
        .put(
            "bad-codegen",
            StringUtils.lines(
                "java.lang.NullPointerException: Attempt to read from field "
                    + "'Test Test.a' on a null object reference"))
        .put(
            "merge-blocks-regression",
            StringUtils.lines(
                "java.lang.NullPointerException: Attempt to invoke virtual"
                    + " method 'Test Test.bW_()' on a null object reference"))
        .put("self-is-catch-block", StringUtils.lines("100", "-1"))
        .put("infinite-loop", "")
        .put(
            "regression/33336471",
            StringUtils.lines(
                "START", "0", "2", "LOOP", "1", "2", "LOOP", "2", "2", "DONE", "START", "0", "2",
                "LOOP", "1", "2", "LOOP", "2", "2", "DONE"))
        .put("regression/33846227", "")
        .put("illegal-invokes", StringUtils.lines("ICCE", "ICCE"))
        .build();
    tests = testsBuilder.build();
  }

  private static Set<String> invokeErrors = ImmutableSet.of("bad-codegen", "illegal-invokes");

  private static Map<String, Set<String>> missingClasses =
      ImmutableMap.of(
          "try-catch", ImmutableSet.of("test.X"),
          "type-confusion-regression5", ImmutableSet.of("jok", "jol"),
          "bad-codegen", ImmutableSet.of("java.util.LTest"));

  // Tests where the original smali code fails on Art, but runs after R8 processing.
  private static final Map<DexVm.Version, List<String>> originalFailingOnArtVersions =
      ImmutableMap.of(
          Version.V5_1_1,
              ImmutableList.of(
                  // Smali code contains an empty switch payload.
                  "sparse-switch", "regression/33846227"),
          Version.V4_4_4,
              ImmutableList.of(
                  // Smali code contains an empty switch payload.
                  "sparse-switch", "regression/33846227"),
          Version.V4_0_4,
              ImmutableList.of(
                  // Smali code contains an empty switch payload.
                  "sparse-switch", "regression/33846227"));

  // Tests where the output has a different output than the original on certain VMs.
  private static final Map<DexVm.Version, Map<String, String>> customProcessedOutputExpectation =
      ImmutableMap.of(
          Version.V4_4_4,
          ImmutableMap.of(
              "bad-codegen", "java.lang.NullPointerException\n",
              "type-confusion-regression2", "java.lang.NullPointerException\n",
              "type-confusion-regression3", "java.lang.NullPointerException\n",
              "merge-blocks-regression", "java.lang.NullPointerException\n"),
          Version.V4_0_4,
          ImmutableMap.of(
              "bad-codegen", "java.lang.NullPointerException\n",
              "type-confusion-regression2", "java.lang.NullPointerException\n",
              "type-confusion-regression3", "java.lang.NullPointerException\n",
              "merge-blocks-regression", "java.lang.NullPointerException\n"),
          Version.V13_0_0,
          ImmutableMap.of(
              "bad-codegen",
              StringUtils.lines(
                  "java.lang.NullPointerException: Attempt to read from field 'Test Test.a'"
                      + " on a null object reference in method 'Test TestObject.a(Test,"
                      + " Test, Test, Test, boolean)'"),
              "type-confusion-regression3",
              StringUtils.lines(
                  "java.lang.NullPointerException: Attempt to read from field 'byte[]"
                      + " Test.a' on a null object reference in method 'int"
                      + " TestObject.a(Test, Test)'")),
          Version.V14_0_0,
          ImmutableMap.of(
              "bad-codegen",
                  StringUtils.lines(
                      "java.lang.NullPointerException: Attempt to read from field 'Test Test.a'"
                          + " on a null object reference in method 'Test TestObject.a(Test,"
                          + " Test, Test, Test, boolean)'"),
              "type-confusion-regression3",
                  StringUtils.lines(
                      "java.lang.NullPointerException: Attempt to read from field 'byte[]"
                          + " Test.a' on a null object reference in method 'int"
                          + " TestObject.a(Test, Test)'")));

  // Tests where the input fails with a verification error on Dalvik instead of the
  // expected runtime exception.
  private static final Map<DexVm.Version, List<String>> dalvikVerificationErrors =
      ImmutableMap.of(
          Version.V4_4_4,
              ImmutableList.of(
                  // The invokes are in fact invalid, but the test expects the current Art behavior
                  // of throwing an IncompatibleClassChange exception. Dalvik fails to verify.
                  "illegal-invokes"),
          Version.V4_0_4,
              ImmutableList.of(
                  // The invokes are in fact invalid, but the test expects the current Art behavior
                  // of throwing an IncompatibleClassChange exception. Dalvik fails to verify.
                  "illegal-invokes"));

  private Set<String> failingOnX8 = ImmutableSet.of(
      // Contains use of register as both an int and a float.
      "regression/33336471"
  );

  @Rule
  public TestDescriptionWatcher watcher = new TestDescriptionWatcher();

  private final TestParameters parameters;
  private final String directoryName;
  private final String dexFileName;
  private final String expectedOutput;

  public R8RunSmaliTestsTest(TestParameters parameters, String name) {
    this.parameters = parameters;
    String expectedOutput = tests.get(name);
    if (customProcessedOutputExpectation.containsKey(parameters.asDexRuntime().getVersion())
        && customProcessedOutputExpectation
            .get(parameters.asDexRuntime().getVersion())
            .containsKey(name)) {
      // If the original and the processed code have different expected output, only run
      // the code produced by R8.
      expectedOutput =
          customProcessedOutputExpectation.get(parameters.asDexRuntime().getVersion()).get(name);
    }
    this.directoryName = name;
    this.dexFileName = name.substring(name.lastIndexOf('/') + 1) + ".dex";
    this.expectedOutput = expectedOutput;
  }

  @Test
  public void SmaliTest() throws Exception {
    Path originalDexFile = Paths.get(SMALI_DIR, directoryName, dexFileName);

    if (failingOnX8.contains(directoryName)) {
      thrown.expect(CompilationFailedException.class);
    }

    Version version = parameters.asDexRuntime().getVersion();
    boolean dalvikVerificationError =
        dalvikVerificationErrors.containsKey(version)
            && dalvikVerificationErrors.get(version).contains(directoryName);
    boolean originalFailing =
        (originalFailingOnArtVersions.containsKey(version)
            && originalFailingOnArtVersions.get(version).contains(directoryName));
    Path testJar = Paths.get(SMALI_DIR, directoryName, "Test.jar");
    boolean testJarExists = testJar.toFile().exists();
    Path testJarDex = null;
    if (testJarExists) {
      testJarDex =
          testForD8(Backend.DEX)
              .setMinApi(parameters)
              .addProgramFiles(testJar)
              .compile()
              .writeToZip();
    }
    testForR8(parameters.getBackend())
        .addKeepAllClassesRule()
        .addProgramDexFileData(Files.readAllBytes(originalDexFile))
        .applyIf(testJarExists, p -> p.addProgramFiles(testJar))
        .addDontWarn(missingClasses.getOrDefault(directoryName, Collections.emptySet()))
        .addOptionsModification(
            options ->
                options.getTestingOptions().allowInvokeErrors =
                    invokeErrors.contains(directoryName))
        .setMinApi(parameters)
        .compile()
        .run(parameters.getRuntime(), "Test")
        .applyIf(
            dalvikVerificationError,
            r -> r.assertFailureWithErrorThatThrows(VerifyError.class),
            r -> r.assertSuccessWithOutput(expectedOutput));

    // Also run the original DEX if possible.
    if (!dalvikVerificationError && !originalFailing) {
      ImmutableList.Builder<String> dexListBuilder = ImmutableList.builder();
      dexListBuilder.add(originalDexFile.toString());
      if (testJarExists) {
        dexListBuilder.add(testJarDex.toString());
      }
      String originalOutput =
          ToolHelper.runArtNoVerificationErrors(
              dexListBuilder.build(), "Test", null, parameters.getRuntime().asDex().getVm());
      assertEquals(expectedOutput, originalOutput);
    }
  }
}
