// Copyright (c) 2019, 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.desugaredlibrary.desugaredlibraryjdktests;

import static com.android.tools.r8.ToolHelper.JDK_TESTS_BUILD_DIR;
import static com.android.tools.r8.utils.FileUtils.CLASS_EXTENSION;
import static com.android.tools.r8.utils.FileUtils.JAVA_EXTENSION;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import com.android.tools.r8.D8TestCompileResult;
import com.android.tools.r8.D8TestRunResult;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.TestRuntime.CfVm;
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.StringUtils;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.junit.Assume;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

@RunWith(Parameterized.class)
public class Jdk11StreamTests extends Jdk11CoreLibTestBase {

  private final TestParameters parameters;

  @Parameterized.Parameters(name = "{0}")
  public static TestParametersCollection data() {
    // TODO(134732760): Support Dalvik VMs, currently fails because libjavacrypto is required and
    // present only in ART runtimes.
    return getTestParameters()
        .withDexRuntimesStartingFromIncluding(Version.V5_1_1)
        .withAllApiLevels()
        .build();
  }

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

  private static final Path JDK_11_STREAM_TEST_CLASSES_DIR =
      Paths.get(ToolHelper.JDK_11_TESTS_CLASSES_DIR + "Stream");
  private static final Path JDK_11_STREAM_TEST_FILES_DIR =
      Paths.get("third_party/openjdk/jdk-11-test/java/util/stream/test");
  private static Path[] JDK_11_STREAM_TEST_COMPILED_FILES;

  private static Path[] getJdk11StreamTestFiles() throws Exception {
    Path[] files = getAllFilesWithSuffixInDirectory(JDK_11_STREAM_TEST_FILES_DIR, JAVA_EXTENSION);
    assert files.length > 0;
    return files;
  }

  private static String[] RUNNABLE_TESTS =
      new String[]{
          // Disabled because explicit cast done on a wrapped value.
          //"org/openjdk/tests/java/util/SplittableRandomTest.java",

          // Working tests
          "org/openjdk/tests/java/util/MapTest.java",
          "org/openjdk/tests/java/util/FillableStringTest.java",
          "org/openjdk/tests/java/util/stream/ForEachOpTest.java",
          "org/openjdk/tests/java/util/stream/CollectionAndMapModifyStreamTest.java",
          "org/openjdk/tests/java/util/stream/GroupByOpTest.java",
          // Disabled because time to run > 1 min.
          // "org/openjdk/tests/java/util/stream/InfiniteStreamWithLimitOpTest.java",
          "org/openjdk/tests/java/util/stream/PrimitiveAverageOpTest.java",
          "org/openjdk/tests/java/util/stream/TeeOpTest.java",
          "org/openjdk/tests/java/util/stream/MinMaxTest.java",
          "org/openjdk/tests/java/util/stream/ConcatTest.java",
          // Disabled because time to run > 1 min.
          // "org/openjdk/tests/java/util/stream/CountLargeTest.java",
          "org/openjdk/tests/java/util/stream/StreamParSeqTest.java",
          "org/openjdk/tests/java/util/stream/ReduceByOpTest.java",
          "org/openjdk/tests/java/util/stream/ConcatOpTest.java",
          "org/openjdk/tests/java/util/stream/IntReduceTest.java",
          "org/openjdk/tests/java/util/stream/SortedOpTest.java",
          "org/openjdk/tests/java/util/stream/MatchOpTest.java",
          // Disabled because time to run > 1 min.
          // "org/openjdk/tests/java/util/stream/RangeTest.java",
          "org/openjdk/tests/java/util/stream/IntSliceOpTest.java",
          "org/openjdk/tests/java/util/stream/SequentialOpTest.java",
          "org/openjdk/tests/java/util/stream/PrimitiveSumTest.java",
          "org/openjdk/tests/java/util/stream/IterateTest.java",
          "org/openjdk/tests/java/util/stream/ReduceTest.java",
          "org/openjdk/tests/java/util/stream/IntUniqOpTest.java",

          // J9 failure
          "org/openjdk/tests/java/util/stream/SpliteratorTest.java",
          // Disabled because time to run > 1 min.
          // "org/openjdk/tests/java/util/stream/CollectorsTest.java",
          "org/openjdk/tests/java/util/stream/WhileOpStatefulTest.java",
          "org/openjdk/tests/java/util/stream/WhileOpTest.java",

          // J9 security
          "org/openjdk/tests/java/util/stream/CountTest.java",
          // Disabled because time to run > 1 min.
          // "org/openjdk/tests/java/util/stream/FlatMapOpTest.java",
          "org/openjdk/tests/java/util/stream/StreamCloseTest.java",
          "org/openjdk/tests/java/util/stream/DoublePrimitiveOpsTests.java",
          // Disabled because time to run > 1 min.
          // "org/openjdk/tests/java/util/stream/StreamSpliteratorTest.java",
          "org/openjdk/tests/java/util/stream/CollectAndSummaryStatisticsTest.java",

          // Foreach problem
          // Disabled because time to run > 1 min.
          // "org/openjdk/tests/java/util/stream/StreamLinkTest.java",
          "org/openjdk/tests/java/util/stream/FindFirstOpTest.java",
          "org/openjdk/tests/java/util/stream/FindAnyOpTest.java",
          // Disabled because time to run > 1 min.
          // "org/openjdk/tests/java/util/stream/StreamBuilderTest.java",
          // Disabled because time to run > 1 min.
          // "org/openjdk/tests/java/util/stream/SliceOpTest.java",
          "org/openjdk/tests/java/util/stream/DistinctOpTest.java",
          "org/openjdk/tests/java/util/stream/MapOpTest.java",
          // Disabled because time to run > 1 min.
          // "org/openjdk/tests/java/util/stream/ToArrayOpTest.java",

          // J9 Random problem
          "org/openjdk/tests/java/util/stream/LongPrimitiveOpsTests.java",
          "org/openjdk/tests/java/util/stream/IntPrimitiveOpsTests.java"
      };

  private static Map<String, String> getRunnableTests() {
    IdentityHashMap<String, String> pathToName = new IdentityHashMap<>();
    int javaExtSize = JAVA_EXTENSION.length();
    for (String runnableTest : RUNNABLE_TESTS) {
      String nameWithoutJavaExt = runnableTest.substring(0, runnableTest.length() - javaExtSize);
      pathToName.put(
          JDK_11_STREAM_TEST_CLASSES_DIR + "/" + nameWithoutJavaExt + CLASS_EXTENSION,
          nameWithoutJavaExt.replace("/", "."));
    }
    return pathToName;
  }

  private static String[] missingDesugaredMethods() {
    // These methods are from Java 9 and not supported in the current desugared libraries.
    return new String[]{
        // Stream
        "takeWhile(",
        "dropWhile(",
        "iterate(",
        "ofNullable(",
        "range(",
        "doubles(",
        // Collectors
        "filtering(",
        "flatMapping(",
    };
  }

  @BeforeClass
  public static void compileJdk11StreamTests() throws Exception {
    if (!new File(JDK_11_STREAM_TEST_CLASSES_DIR.toString()).exists()) {
      List<String> options =
          Arrays.asList(
              "--add-reads",
              "java.base=ALL-UNNAMED",
              "--patch-module",
              "java.base=" + JDK_11_JAVA_BASE_EXTENSION_CLASSES_DIR);
      ToolHelper.runJavac(
          CfVm.JDK11,
          Collections.singletonList(Paths.get(JDK_TESTS_BUILD_DIR + "testng-6.10.jar")),
          JDK_11_STREAM_TEST_CLASSES_DIR,
          options,
          getJdk11StreamTestFiles());
    }
    JDK_11_STREAM_TEST_COMPILED_FILES =
        getAllFilesWithSuffixInDirectory(JDK_11_STREAM_TEST_CLASSES_DIR, CLASS_EXTENSION);
    assert JDK_11_STREAM_TEST_COMPILED_FILES.length > 0;
  }


  @Test
  public void testStream() throws Exception {
    Assume.assumeTrue(
        "Requires Java base extensions, should add it when not desugaring",
        parameters.getApiLevel().getLevel() < AndroidApiLevel.N.getLevel());
    // TODO(b/137876068): It seems to fail on windows because the method.
    // getAllFilesWithSuffixInDirectory() finds different files on Windows (To be confirmed), so
    // compilation is then different and raises an error.
    Assume.assumeFalse(ToolHelper.isWindows());
    Map<String, String> runnableTests = getRunnableTests();
    String verbosity = "2";
    List<Path> filesToCompile =
        Arrays.stream(JDK_11_STREAM_TEST_COMPILED_FILES)
            .filter(file -> !file.toString().contains("lang/invoke"))
            .collect(Collectors.toList());
    D8TestCompileResult compileResult =
        testForD8()
            .addProgramFiles(filesToCompile)
            .addProgramFiles(getPathsFiles())
            .addProgramFiles(getSafeVarArgsFile())
            .addProgramFiles(testNGSupportProgramFiles())
            .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P))
            .setMinApi(parameters.getApiLevel())
            .enableCoreLibraryDesugaring(parameters.getApiLevel())
            .compile()
            .addDesugaredCoreLibraryRunClassPath(
                this::buildDesugaredLibraryWithJavaBaseExtension, parameters.getApiLevel())
            .withArtFrameworks()
            .withArt6Plus64BitsLib();
    int numSuccesses = 0;
    int numHardFailures = 0;
    for (String path : runnableTests.keySet()) {
      assert runnableTests.get(path) != null;
      D8TestRunResult result =
          compileResult.run(
              parameters.getRuntime(), "TestNGMainRunner", verbosity, runnableTests.get(path));
      if (result.getStdOut().endsWith(StringUtils.lines("SUCCESS"))) {
        assertTrue(
            result
                .getStdOut()
                .endsWith(
                    StringUtils.lines("Tests result in " + runnableTests.get(path) + ": SUCCESS")));
        numSuccesses++;
      } else {
        if (result.getStdOut().contains("java.lang.NoSuchMethodError")
            && Arrays.stream(missingDesugaredMethods())
            .anyMatch(method -> result.getStdOut().contains(method))) {
          // TODO(b/134732760): support Java 9 APIs.
        } else if (result
            .getStdOut()
            .contains("java.lang.NoSuchMethodError: No interface method forEach")) {
          // TODO(b/134732760): fix tests no to use Iterable#forEach
        } else if (result.getStdOut().contains("in class Ljava/util/Random")
            && result.getStdOut().contains("java.lang.NoSuchMethodError")) {
          // TODO(b/134732760): Random Java 9 Apis, support or do not use them.
        } else if (result.getStdOut().contains("java.lang.AssertionError")) {
          // TODO(b/134732760): Investigate and fix these issues.
          numHardFailures++;
        } else {
          String errorMessage = "STDOUT:\n" + result.getStdOut() + "STDERR:\n" + result.getStdErr();
          fail(errorMessage);
        }
      }
    }
    assertTrue(numSuccesses > 20);
    assertTrue(numHardFailures <= 6);
  }
}
