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

import static com.android.tools.r8.DiagnosticsMatcher.diagnosticMessage;
import static java.util.stream.Collectors.toList;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.FileUtils;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.ZipUtils;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
import org.junit.Assume;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

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

  private final TestParameters parameters;
  private final String mainDexRulesForMainDexFile1AndMainDexFile2 =
      StringUtils.lines(
          "-keep class " + MainDexFile1.class.getTypeName() + " {",
          "  *;",
          "}",
          "-keep class " + MainDexFile2.class.getTypeName() + " {",
          "  *;",
          "}");
  private final String mainDexRulesForMainDexFile3 =
      "-keep class " + MainDexFile3.class.getTypeName();

  @Parameterized.Parameters(name = "{0}")
  public static TestParametersCollection data() {
    return getTestParameters().withDexRuntimes().withAllApiLevels().build();
  }

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

  private Path mainDexListForMainDexFile1AndMainDexFile2() throws IOException {
    Path mainDexPath = temp.newFile("mylist1.txt").toPath();
    String mainDexList =
        StringUtils.lines(toMainDexFormat(MainDexFile1.class), toMainDexFormat(MainDexFile2.class));
    Files.write(mainDexPath, mainDexList.getBytes());
    return mainDexPath;
  }

  private Path mainDexListForMainDexFile3() throws IOException {
    Path mainDexPath = temp.newFile("mylist2.txt").toPath();
    String mainDexList = StringUtils.lines(toMainDexFormat(MainDexFile3.class));
    Files.write(mainDexPath, mainDexList.getBytes());
    return mainDexPath;
  }

  private Path newMainDexRulesPath1() throws IOException {
    Path mainDexPath = temp.newFile("myrules1.txt").toPath();
    Files.write(mainDexPath, mainDexRulesForMainDexFile1AndMainDexFile2.getBytes());
    return mainDexPath;
  }

  private Path newMainDexRulesPath2() throws IOException {
    Path mainDexPath = temp.newFile("myrules2.txt").toPath();
    Files.write(mainDexPath, mainDexRulesForMainDexFile3.getBytes());
    return mainDexPath;
  }

  private static String toMainDexFormat(Class<?> clazz) {
    return clazz.getName().replace(".", "/") + FileUtils.CLASS_EXTENSION;
  }

  @Test
  public void testD8MainDexList() throws Exception {
    Assume.assumeTrue(
        "pre-native-multidex only",
        parameters.getApiLevel().isLessThanOrEqualTo(AndroidApiLevel.K));
    Path dumpDir = temp.newFolder().toPath();
    // Pre-compile to DEX and do main-dex list on DEX inputs only.
    Path dexed =
        testForD8()
            .addInnerClasses(DumpMainDexInputsTest.class)
            .setMinApi(parameters.getApiLevel())
            .compile()
            .writeToZip();

    testForD8()
        .addProgramFiles(dexed)
        .setMinApi(parameters.getApiLevel())
        .addMainDexListFiles(
            mainDexListForMainDexFile1AndMainDexFile2(), mainDexListForMainDexFile3())
        .addMainDexListClasses(MainDexClass1.class, MainDexClass2.class, TestClass.class)
        .addOptionsModification(options -> options.dumpInputToDirectory = dumpDir.toString())
        .compileWithExpectedDiagnostics(
            diagnostics ->
                diagnostics
                    .assertNoErrors()
                    .assertInfosMatch(
                        diagnosticMessage(containsString("Dumped compilation inputs to:")))
                    .assertWarningsMatch(
                        diagnosticMessage(
                            containsString(
                                "Dumping main dex list resources may have side effects due to I/O"
                                    + " on Paths."))))
        .run(parameters.getRuntime(), TestClass.class)
        .assertSuccessWithOutputLines("Hello, world");
    verifyDumpDir(dumpDir, true);
  }

  @Test
  public void testD8MainDexRules() throws Exception {
    Assume.assumeTrue(
        "pre-native-multidex only",
        parameters.getApiLevel().isLessThanOrEqualTo(AndroidApiLevel.K));
    Path dumpDir = temp.newFolder().toPath();
    testForD8()
        .setMinApi(parameters.getApiLevel())
        .addInnerClasses(DumpMainDexInputsTest.class)
        .addMainDexRulesFiles(newMainDexRulesPath1(), newMainDexRulesPath2())
        .addMainDexKeepClassRules(MainDexClass1.class, MainDexClass2.class, TestClass.class)
        .addOptionsModification(options -> options.dumpInputToDirectory = dumpDir.toString())
        .compile()
        .assertAllInfoMessagesMatch(containsString("Dumped compilation inputs to:"))
        .run(parameters.getRuntime(), TestClass.class)
        .assertSuccessWithOutputLines("Hello, world");
    verifyDumpDir(dumpDir, false);
  }

  @Test
  public void testR8MainDexRules() throws Exception {
    Assume.assumeTrue(
        "pre-native-multidex only",
        parameters.getApiLevel().isLessThanOrEqualTo(AndroidApiLevel.K));
    Path dumpDir = temp.newFolder().toPath();
    testForR8(parameters.getBackend())
        .setMinApi(parameters.getApiLevel())
        .addInnerClasses(DumpMainDexInputsTest.class)
        .addMainDexRuleFiles(newMainDexRulesPath1(), newMainDexRulesPath2())
        .addMainDexKeepClassRules(MainDexClass1.class, MainDexClass2.class, TestClass.class)
        .addOptionsModification(options -> options.dumpInputToDirectory = dumpDir.toString())
        .addKeepAllClassesRule()
        .allowDiagnosticMessages()
        .compile()
        .assertAllInfoMessagesMatch(containsString("Dumped compilation inputs to:"))
        .run(parameters.getRuntime(), TestClass.class)
        .assertSuccessWithOutputLines("Hello, world");
    verifyDumpDir(dumpDir, false);
  }

  private void verifyDumpDir(Path dumpDir, boolean checkMainDexList) throws IOException {
    assertTrue(Files.isDirectory(dumpDir));
    List<Path> paths = Files.walk(dumpDir, 1).collect(toList());
    boolean hasVerified = false;
    for (Path path : paths) {
      if (!path.equals(dumpDir)) {
        // The non-external run here results in assert code calling application read.
        verifyDump(path, checkMainDexList);
        hasVerified = true;
      }
    }
    assertTrue(hasVerified);
  }

  private void verifyDump(Path dumpFile, boolean checkMainDexList) throws IOException {
    assertTrue(Files.exists(dumpFile));
    Path unzipped = temp.newFolder().toPath();
    ZipUtils.unzip(dumpFile.toString(), unzipped.toFile());
    assertTrue(Files.exists(unzipped.resolve("r8-version")));
    assertTrue(Files.exists(unzipped.resolve("program.jar")));
    assertTrue(Files.exists(unzipped.resolve("library.jar")));
    if (checkMainDexList) {
      Path mainDexListFile = unzipped.resolve("main-dex-list.txt");
      assertTrue(Files.exists(mainDexListFile));
      String mainDex = new String(Files.readAllBytes(mainDexListFile));
      List<String> mainDexLines =
          Arrays.stream(mainDex.split("\n")).filter(s -> !s.isEmpty()).collect(toList());
      assertEquals(6, mainDexLines.size());
      List<String> expected =
          Stream.of(
                  MainDexFile1.class,
                  MainDexFile2.class,
                  MainDexFile3.class,
                  MainDexClass1.class,
                  MainDexClass2.class,
                  TestClass.class)
              .map(DumpMainDexInputsTest::toMainDexFormat)
              .collect(toList());
      assertEquals(expected, mainDexLines);
    } else {
      Path mainDexRulesFile = unzipped.resolve("main-dex-rules.txt");
      assertTrue(Files.exists(mainDexRulesFile));
      String mainDexRules = new String(Files.readAllBytes(mainDexRulesFile));
      assertThat(mainDexRules, containsString(mainDexRulesForMainDexFile1AndMainDexFile2));
      assertThat(mainDexRules, containsString(mainDexRulesForMainDexFile3));
    }
  }

  static class TestClass {
    public static void main(String[] args) {
      System.out.println("Hello, world");
    }
  }

  static class MainDexClass1 {}

  static class MainDexClass2 {}

  static class MainDexFile1 {}

  static class MainDexFile2 {}

  static class MainDexFile3 {}

  static class NonMainDex1 {}

  static class NonMainDex2 {}
}
