// 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;

import static com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification.JDK11;
import static com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification.JDK11_LEGACY;
import static com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification.JDK11_MINIMAL;
import static com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification.JDK11_PATH;
import static com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification.JDK8;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import com.android.tools.r8.StringResource;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibrarySpecification;
import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibrarySpecificationParser;
import com.android.tools.r8.ir.desugar.desugaredlibrary.lint.GenerateHtmlDoc;
import com.android.tools.r8.ir.desugar.desugaredlibrary.lint.GenerateLintFiles;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.FileUtils;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.Reporter;
import com.google.common.collect.ImmutableList;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

@RunWith(Parameterized.class)
public class LintFilesTest extends DesugaredLibraryTestBase {

  private final LibraryDesugaringSpecification libraryDesugaringSpecification;

  private List<String> lintContents;

  @Parameters(name = "{1}")
  public static List<Object[]> data() {
    return buildParameters(
        getTestParameters().withNoneRuntime().build(),
        ImmutableList.of(JDK8, JDK11_MINIMAL, JDK11, JDK11_PATH, JDK11_LEGACY));
  }

  public LintFilesTest(
      TestParameters parameters, LibraryDesugaringSpecification libraryDesugaringSpecification) {
    assert parameters.isNoneRuntime();
    this.libraryDesugaringSpecification = libraryDesugaringSpecification;
  }

  private boolean supportsAllMethodsOf(String type) {
    return lintContents.contains(type);
  }

  private boolean supportsMethodButNotAllMethodsInClass(String method) {
    assert method.contains("#");
    return !supportsAllMethodsOf(method.split("#")[0]) && lintContents.contains(method);
  }

  private void checkFileContent(AndroidApiLevel minApiLevel, Path lintFile) throws Exception {
    // Just do some light probing in the generated lint files.
    lintContents = FileUtils.readAllLines(lintFile);

    // All methods supported on CHM.
    assertEquals(
        libraryDesugaringSpecification != JDK8,
        supportsAllMethodsOf("java/util/concurrent/ConcurrentHashMap"));

    // All methods supported on BiFunction with maintain prefix.
    assertTrue(supportsAllMethodsOf("java/util/function/BiFunction"));

    if (libraryDesugaringSpecification == JDK11_MINIMAL) {
      return;
    }

    // All methods supported on Optional*.
    assertTrue(supportsAllMethodsOf("java/util/Optional"));
    assertTrue(supportsAllMethodsOf("java/util/OptionalInt"));

    // No parallel* methods pre L, Stream are never fully supported due to takeWhile/dropWhile.
    assertEquals(
        minApiLevel == AndroidApiLevel.L,
        supportsMethodButNotAllMethodsInClass(
            "java/util/Collection#parallelStream()Ljava/util/stream/Stream;"));
    assertEquals(
        minApiLevel == AndroidApiLevel.L,
        supportsMethodButNotAllMethodsInClass(
            "java/util/stream/DoubleStream#parallel()Ljava/util/stream/DoubleStream;"));
    assertEquals(
        minApiLevel == AndroidApiLevel.L,
        supportsMethodButNotAllMethodsInClass(
            "java/util/stream/BaseStream#parallel()Ljava/util/stream/BaseStream;"));
    assertTrue(
        supportsMethodButNotAllMethodsInClass(
            "java/util/stream/DoubleStream#allMatch(Ljava/util/function/DoublePredicate;)Z"));

    assertEquals(
        libraryDesugaringSpecification != JDK8, supportsAllMethodsOf("java/util/concurrent/Flow"));

    // Checks specific methods are supported or not in JDK8, all is supported in JDK11.
    if (libraryDesugaringSpecification == JDK8) {
      // Supported methods on ConcurrentHashMap.
      assertTrue(
          supportsMethodButNotAllMethodsInClass(
              "java/util/concurrent/ConcurrentHashMap#getOrDefault(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"));

      // Don't include constructors.
      assertFalse(
          supportsMethodButNotAllMethodsInClass(
              "java/util/concurrent/ConcurrentHashMap#<init>()V"));

      // Unsupported methods on ConcurrentHashMap.
      assertFalse(
          supportsMethodButNotAllMethodsInClass(
              "java/util/concurrent/ConcurrentHashMap#reduce(JLjava/util/function/BiFunction;Ljava/util/function/BiFunction;)Ljava/lang/Object;"));
      assertFalse(
          supportsMethodButNotAllMethodsInClass(
              "java/util/concurrent/ConcurrentHashMap#newKeySet()Ljava/util/concurrent/ConcurrentHashMap$KeySetView;"));
    }

    // Maintain type.
    assertEquals(
        libraryDesugaringSpecification != JDK8 && libraryDesugaringSpecification != JDK11_LEGACY,
        supportsAllMethodsOf("java/io/UncheckedIOException"));

    // Retarget method.
    assertTrue(
        supportsMethodButNotAllMethodsInClass(
            "java/util/Arrays#spliterator([I)Ljava/util/Spliterator$OfInt;"));

    // Emulated interface default method.
    assertTrue(
        supportsMethodButNotAllMethodsInClass(
            "java/util/List#spliterator()Ljava/util/Spliterator;"));

    // Emulated interface static method.
    assertTrue(
        supportsMethodButNotAllMethodsInClass(
            "java/util/Map$Entry#comparingByValue()Ljava/util/Comparator;"));

    // No no-default method from emulated interface.
    assertFalse(supportsMethodButNotAllMethodsInClass("java/util/List#size()I"));

    // File should be sorted.
    List<String> sorted = new ArrayList<>(lintContents);
    sorted.sort(Comparator.naturalOrder());
    assertEquals(lintContents, sorted);
  }

  @Test
  public void testLint() throws Exception {
    Path directory = temp.newFolder().toPath();
    Path jdkLibJar =
        libraryDesugaringSpecification == JDK8
            ? ToolHelper.DESUGARED_JDK_8_LIB_JAR
            : LibraryDesugaringSpecification.getTempLibraryJDK11Undesugar();
    GenerateLintFiles.main(
        new String[] {
          libraryDesugaringSpecification.getSpecification().toString(),
          jdkLibJar.toString(),
          directory.toString()
        });
    InternalOptions options = new InternalOptions(new DexItemFactory(), new Reporter());
    DesugaredLibrarySpecification desugaredLibrarySpecification =
        DesugaredLibrarySpecificationParser.parseDesugaredLibrarySpecification(
            StringResource.fromFile(libraryDesugaringSpecification.getSpecification()),
            options.itemFactory,
            options.reporter,
            false,
            AndroidApiLevel.B.getLevel());

    AndroidApiLevel requiredCompilationApiLevel =
        desugaredLibrarySpecification.getRequiredCompilationApiLevel();
    Path compileApiLevelDirectory =
        directory.resolve("compile_api_level_" + requiredCompilationApiLevel.getLevel());

    assertTrue(Files.exists(compileApiLevelDirectory));
    for (AndroidApiLevel minApiLevel : AndroidApiLevel.values()) {
      String desugaredApisBaseName =
          "desugared_apis_" + requiredCompilationApiLevel.getLevel() + "_" + minApiLevel.getLevel();
      if (minApiLevel == AndroidApiLevel.L || minApiLevel == AndroidApiLevel.B) {
        assertTrue(Files.exists(compileApiLevelDirectory.resolve(desugaredApisBaseName + ".txt")));
        assertTrue(Files.exists(compileApiLevelDirectory.resolve(desugaredApisBaseName + ".jar")));
        checkFileContent(
            minApiLevel, compileApiLevelDirectory.resolve(desugaredApisBaseName + ".txt"));
      } else {
        assertFalse(Files.exists(compileApiLevelDirectory.resolve(desugaredApisBaseName + ".txt")));
        assertFalse(Files.exists(compileApiLevelDirectory.resolve(desugaredApisBaseName + ".jar")));
      }
    }
  }

  @Test
  public void testHTML() throws Exception {
    Path jdkLibJar =
        libraryDesugaringSpecification == JDK8
            ? ToolHelper.DESUGARED_JDK_8_LIB_JAR
            : LibraryDesugaringSpecification.getTempLibraryJDK11Undesugar();

    Path directory2 = temp.newFolder().toPath();
    GenerateHtmlDoc.main(
        new String[] {
          "--generate-api-docs",
          libraryDesugaringSpecification.getSpecification().toString(),
          jdkLibJar.toString(),
          directory2.toString()
        });
    List<String> html = Files.readAllLines(directory2.resolve("apis.html"));
    // The doc has the same content than the lint data that is tested above, this is just a sanity
    // check that the doc generation ran without error and looks sane.
    assertEquals("<tr>", html.get(0));
    assertEquals("</tr>", html.get(html.size() - 2));
    if (libraryDesugaringSpecification == JDK11 || libraryDesugaringSpecification == JDK11_PATH) {
      assertEquals(6, html.stream().filter(s -> s.contains("Flow")).count());
    }
  }

  public static void main(String[] args) throws Exception {
    // Generate all html docs and lint files.
    Path top = Paths.get("generated");
    Path html = top.resolve("html");
    Files.createDirectories(html);
    ImmutableList<LibraryDesugaringSpecification> specs =
        ImmutableList.of(JDK8, JDK11_MINIMAL, JDK11, JDK11_PATH, JDK11_LEGACY);
    for (LibraryDesugaringSpecification spec : specs) {
      Path jdkLibJar =
          spec == JDK8
              ? ToolHelper.DESUGARED_JDK_8_LIB_JAR
              : LibraryDesugaringSpecification.getTempLibraryJDK11Undesugar();
      new GenerateHtmlDoc(spec.getSpecification().toString(), jdkLibJar.toString(), html.toString())
          .run(spec + ".html");
      Path lint = top.resolve("lint_" + spec);
      Files.createDirectories(lint);
      new GenerateLintFiles(
              spec.getSpecification().toString(), jdkLibJar.toString(), lint.toString())
          .run();
    }
  }
}
