// Copyright (c) 2017, 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 com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
import static com.android.tools.r8.utils.FileUtils.ZIP_EXTENSION;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeFalse;

import com.android.tools.r8.ToolHelper.DexVm;
import com.android.tools.r8.ir.desugar.itf.InterfaceMethodRewriter;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.TestDescriptionWatcher;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;

public abstract class RunExamplesJava9Test
    <B extends BaseCommand.Builder<? extends BaseCommand, B>> {

  private static final String EXAMPLE_DIR = ToolHelper.EXAMPLES_JAVA9_BUILD_DIR;

  abstract class TestRunner<C extends TestRunner<C>> {
    final String testName;
    final String packageName;
    final String mainClass;
    final List<String> args = new ArrayList<>();

    final List<Consumer<InternalOptions>> optionConsumers = new ArrayList<>();
    final List<Consumer<CodeInspector>> dexInspectorChecks = new ArrayList<>();
    final List<UnaryOperator<B>> builderTransformations = new ArrayList<>();

    TestRunner(String testName, String packageName, String mainClass) {
      this.testName = testName;
      this.packageName = packageName;
      this.mainClass = mainClass;
    }

    abstract C self();

    C withDexCheck(Consumer<CodeInspector> check) {
      dexInspectorChecks.add(check);
      return self();
    }

    C withArg(String arg) {
      args.add(arg);
      return self();
    }

    void combinedOptionConsumer(InternalOptions options) {
      for (Consumer<InternalOptions> consumer : optionConsumers) {
        consumer.accept(options);
      }
    }

    C withBuilderTransformation(UnaryOperator<B> builderTransformation) {
      builderTransformations.add(builderTransformation);
      return self();
    }

    Path getInputJar() {
      return Paths.get(EXAMPLE_DIR, packageName + JAR_EXTENSION);
    }

    void run() throws Throwable {
      if (minSdkErrorExpected(testName)) {
        thrown.expect(CompilationFailedException.class);
      }

      String qualifiedMainClass = packageName + "." + mainClass;
      Path inputFile = getInputJar();
      Path out = temp.getRoot().toPath().resolve(testName + ZIP_EXTENSION);

      build(inputFile, out);

      if (!ToolHelper.artSupported() && !ToolHelper.dealsWithGoldenFiles()) {
        return;
      }

      if (!dexInspectorChecks.isEmpty()) {
        CodeInspector inspector = new CodeInspector(out);
        for (Consumer<CodeInspector> check : dexInspectorChecks) {
          check.accept(inspector);
        }
      }

      execute(testName, qualifiedMainClass, new Path[]{inputFile}, new Path[]{out}, args);
    }

    abstract C withMinApiLevel(int minApiLevel);

    C withKeepAll() {
      return self();
    }

    abstract void build(Path inputFile, Path out) throws Throwable;
  }

  private static List<String> minSdkErrorExpected =
      ImmutableList.of("varhandle-error-due-to-min-sdk");

  private static Map<DexVm.Version, List<String>> failsOn;

  static {
    ImmutableMap.Builder<DexVm.Version, List<String>> builder = ImmutableMap.builder();
    builder
        .put(DexVm.Version.V4_0_4, ImmutableList.of(
            "native-private-interface-methods", // Dex version not supported
            "varhandle"
        ))
        .put(DexVm.Version.V4_4_4, ImmutableList.of(
            "native-private-interface-methods", // Dex version not supported
            "varhandle"
        ))
        .put(DexVm.Version.V5_1_1, ImmutableList.of(
            "native-private-interface-methods", // Dex version not supported
            "varhandle"
        ))
        .put(DexVm.Version.V6_0_1, ImmutableList.of(
            "native-private-interface-methods", // Dex version not supported
            "varhandle"
        ))
        .put(DexVm.Version.V7_0_0, ImmutableList.of(
            // Dex version not supported
            "varhandle"
        ))
        .put(DexVm.Version.V8_1_0, ImmutableList.of(
            // Dex version not supported
            "varhandle"
        ))
        .put(DexVm.Version.DEFAULT, ImmutableList.of(
            // TODO(b/72536415): Update runtime when the support will be ready
            "varhandle"
        ));
    failsOn = builder.build();
  }

  // Defines methods failing on JVM, specifies the output to be used for comparison.
  private static Map<String, String> expectedJvmResult =
      ImmutableMap.of(
          "twr-close-resource",
          "A\nE\nG\nH\nI\nJ\nK\n"
              + "iA\niE\niG\niH\niI\niJ\niK\n"
              + "1\n2\n3\n4\n5\n6\n7\n8\n99\n"
              + "i1\ni2\ni3\ni4\ni5\ni6\ni7\ni8\ni99\n",
          "native-private-interface-methods",
          "0: s>i>a\n"
              + "1: d>i>s>i>a\n"
              + "2: l>i>s>i>a\n"
              + "3: x>s\n"
              + "4: c>d>i>s>i>a\n",
          "desugared-private-interface-methods",
          "0: s>i>a\n"
              + "1: d>i>s>i>a\n"
              + "2: l>i>s>i>a\n"
              + "3: x>s\n"
              + "4: c>d>i>s>i>a\n",
          "varhandle",
          "true\nfalse\n"
      );

  @Rule
  public TemporaryFolder temp = ToolHelper.getTemporaryFolderForTest();

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

  @Rule
  public TestDescriptionWatcher watcher = new TestDescriptionWatcher();

  private boolean failsOn(Map<DexVm.Version, List<String>> failsOn, String name) {
    DexVm.Version vmVersion = ToolHelper.getDexVm().getVersion();
    return failsOn.containsKey(vmVersion)
        && failsOn.get(vmVersion).contains(name);
  }

  private boolean expectedToFail(String name) {
    return failsOn(failsOn, name);
  }

  private boolean minSdkErrorExpected(String testName) {
    return minSdkErrorExpected.contains(testName);
  }

  @Test
  public void nativePrivateInterfaceMethods() throws Throwable {
    test("native-private-interface-methods",
        "privateinterfacemethods", "PrivateInterfaceMethods")
        .withMinApiLevel(AndroidApiLevel.N.getLevel())
        .withKeepAll()
        .run();
  }

  @Test
  public void desugaredPrivateInterfaceMethods() throws Throwable {
    assumeFalse("CF backend does not desugar", this instanceof R8CFRunExamplesJava9Test);
    final String iName = "privateinterfacemethods.I";
    test("desugared-private-interface-methods",
        "privateinterfacemethods", "PrivateInterfaceMethods")
        .withMinApiLevel(AndroidApiLevel.M.getLevel())
        .withKeepAll()
        .withDexCheck(dexInspector -> {
          ClassSubject companion = dexInspector.clazz(
              iName + InterfaceMethodRewriter.COMPANION_CLASS_NAME_SUFFIX);
          assertThat(companion, isPresent());
          MethodSubject iFoo = companion.method(
              "java.lang.String",
              InterfaceMethodRewriter.PRIVATE_METHOD_PREFIX + "iFoo",
              ImmutableList.of(iName, "boolean"));
          assertThat(iFoo, isPresent());
          assertTrue(iFoo.getMethod().isPublicMethod());
        })
        .run();
  }

  @Test
  public void varHandle() throws Throwable {
    test("varhandle", "varhandle", "VarHandleTests")
        .withMinApiLevel(AndroidApiLevel.P.getLevel())
        .withKeepAll()
        .run();
  }

  @Test
  public void varHandleErrorDueToMinSdk() throws Throwable {
    test("varhandle-error-due-to-min-sdk", "varhandle", "VarHandleTests")
        .withMinApiLevel(AndroidApiLevel.O.getLevel())
        .withKeepAll()
        .run();
  }

  @Test
  public void testTwrCloseResourceMethod() throws Throwable {
    TestRunner<?> test = test("twr-close-resource", "twrcloseresource", "TwrCloseResourceTest");
    test
        .withMinApiLevel(AndroidApiLevel.I.getLevel())
        .withKeepAll()
        .withArg(test.getInputJar().toAbsolutePath().toString())
        .run();
  }

  abstract RunExamplesJava9Test<B>.TestRunner<?> test(String testName, String packageName,
      String mainClass);

  void execute(String testName,
      String qualifiedMainClass, Path[] jars, Path[] dexes, List<String> args) throws IOException {

    boolean expectedToFail = expectedToFail(testName);
    if (expectedToFail) {
      thrown.expect(Throwable.class);
    }
    String output = ToolHelper.runArtNoVerificationErrors(
        Arrays.stream(dexes).map(Path::toString).collect(Collectors.toList()),
        qualifiedMainClass,
        builder -> {
          for (String arg : args) {
            builder.appendProgramArgument(arg);
          }
        });
    String jvmResult = null;
    if (expectedJvmResult.containsKey(testName)) {
      jvmResult = expectedJvmResult.get(testName);
    } else if (!expectedToFail) {
      ToolHelper.ProcessResult javaResult =
          ToolHelper.runJava(ImmutableList.copyOf(jars), qualifiedMainClass);
      assertEquals("JVM run failed", javaResult.exitCode, 0);
      jvmResult = javaResult.stdout;
    }

    if (jvmResult != null) {
      assertTrue(
          "JVM output does not match art output.\n\tjvm: "
              + jvmResult
              + "\n\tart: "
              + output.replace("\r", ""),
          output.equals(jvmResult.replace("\r", "")));
    }
  }

}
