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

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.FileUtils.withNativeFileSeparators;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.equalTo;

import com.android.tools.r8.GenerateMainDexList;
import com.android.tools.r8.GenerateMainDexListCommand;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.ir.desugar.LambdaRewriter;
import com.android.tools.r8.references.Reference;
import com.android.tools.r8.shaking.WhyAreYouKeepingConsumer;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.Box;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.FileUtils;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.StringUtils;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import org.junit.Assert;
import org.junit.Test;

public class MainDexTracingTest extends TestBase {

  private static final String EXAMPLE_BUILD_DIR = ToolHelper.EXAMPLES_BUILD_DIR;
  private static final String EXAMPLE_O_BUILD_DIR = ToolHelper.EXAMPLES_ANDROID_O_BUILD_DIR;
  private static final String EXAMPLE_SRC_DIR = ToolHelper.EXAMPLES_DIR;
  private static final String EXAMPLE_O_SRC_DIR = ToolHelper.EXAMPLES_ANDROID_O_DIR;

  @Test
  public void traceMainDexList001_whyareyoukeeping() throws Throwable {
    PrintStream stdout = System.out;
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    System.setOut(new PrintStream(baos));
    doTest(
        "traceMainDexList001_1",
        "multidex001",
        EXAMPLE_BUILD_DIR,
        Paths.get(EXAMPLE_SRC_DIR, "multidex", "main-dex-rules-whyareyoukeeping.txt"),
        Paths.get(EXAMPLE_SRC_DIR, "multidex001", "ref-list-1.txt"),
        Paths.get(EXAMPLE_SRC_DIR, "multidex001", "ref-list-1.txt"),
        AndroidApiLevel.I);
    String output = new String(baos.toByteArray(), Charset.defaultCharset());
    Assert.assertThat(output, containsString("is referenced in keep rule:"));
    System.setOut(stdout);
  }

  @Test
  public void traceMainDexList001_whyareyoukeeping_consumer() throws Throwable {
    WhyAreYouKeepingConsumer graphConsumer = new WhyAreYouKeepingConsumer(null);
    doTest(
        "traceMainDexList001_1",
        "multidex001",
        EXAMPLE_BUILD_DIR,
        Paths.get(EXAMPLE_SRC_DIR, "multidex", "main-dex-rules.txt"),
        Paths.get(EXAMPLE_SRC_DIR, "multidex001", "ref-list-1.txt"),
        Paths.get(EXAMPLE_SRC_DIR, "multidex001", "ref-list-1.txt"),
        AndroidApiLevel.I,
        options -> {
          options.enableInlining = false;
          options.mainDexKeptGraphConsumer = graphConsumer;
        });
    {
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      graphConsumer.printWhyAreYouKeeping(
          Reference.classFromTypeName("multidex001.MainActivity"), new PrintStream(baos));
      String output = new String(baos.toByteArray(), Charset.defaultCharset());
      String expected =
          StringUtils.lines(
              "multidex001.MainActivity",
              "|- is referenced in keep rule:",
              withNativeFileSeparators("|  src/test/examples/multidex/main-dex-rules.txt:14:1"));
      Assert.assertEquals(expected, output);
    }
    {
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      graphConsumer.printWhyAreYouKeeping(
          Reference.classFromTypeName("multidex001.ClassForMainDex"), new PrintStream(baos));
      String output = new String(baos.toByteArray(), Charset.defaultCharset());
      // TODO(b/120951570): We should be able to get the reason for ClassForMainDex too.
      String expected =
          true
              ? StringUtils.lines("Nothing is keeping multidex001.ClassForMainDex")
              : StringUtils.lines(
                  "multidex001.ClassForMainDex",
                  "|- is direct reference from:",
                  "|  multidex001.MainActivity",
                  "|- is referenced in keep rule:",
                  withNativeFileSeparators(
                      "|  src/test/examples/multidex/main-dex-rules.txt:14:1"));
      Assert.assertEquals(expected, output);
    }
  }

  @Test
  public void traceMainDexList001_1() throws Throwable {
    doTest(
        "traceMainDexList001_1",
        "multidex001",
        EXAMPLE_BUILD_DIR,
        Paths.get(EXAMPLE_SRC_DIR, "multidex", "main-dex-rules.txt"),
        Paths.get(EXAMPLE_SRC_DIR, "multidex001", "ref-list-1.txt"),
        Paths.get(EXAMPLE_SRC_DIR, "multidex001", "ref-list-1.txt"),
        AndroidApiLevel.I);
  }

  @Test
  public void traceMainDexList001_2() throws Throwable {
    doTest(
        "traceMainDexList001_2",
        "multidex001",
        EXAMPLE_BUILD_DIR,
        Paths.get(EXAMPLE_SRC_DIR, "multidex001", "main-dex-rules-2.txt"),
        Paths.get(EXAMPLE_SRC_DIR, "multidex001", "ref-list-2.txt"),
        Paths.get(EXAMPLE_SRC_DIR, "multidex001", "ref-list-2.txt"),
        AndroidApiLevel.I);
  }

  @Test
  public void traceMainDexList002() throws Throwable {
    doTest(
        "traceMainDexList002",
        "multidex002",
        EXAMPLE_BUILD_DIR,
        Paths.get(EXAMPLE_SRC_DIR, "multidex", "main-dex-rules.txt"),
        Paths.get(EXAMPLE_SRC_DIR, "multidex002", "ref-list-1.txt"),
        Paths.get(EXAMPLE_SRC_DIR, "multidex002", "ref-list-1.txt"),
        AndroidApiLevel.I);
  }

  @Test
  public void traceMainDexList003() throws Throwable {
    doTest(
        "traceMainDexList003",
        "multidex003",
        EXAMPLE_BUILD_DIR,
        Paths.get(EXAMPLE_SRC_DIR, "multidex", "main-dex-rules.txt"),
        Paths.get(EXAMPLE_SRC_DIR, "multidex003", "ref-list-1.txt"),
        Paths.get(EXAMPLE_SRC_DIR, "multidex003", "ref-list-1.txt"),
        AndroidApiLevel.I);
  }

  @Test
  public void traceMainDexList004() throws Throwable {
    doTest(
        "traceMainDexList004",
        "multidex004",
        EXAMPLE_O_BUILD_DIR,
        Paths.get(EXAMPLE_SRC_DIR, "multidex", "main-dex-rules.txt"),
        Paths.get(EXAMPLE_O_SRC_DIR, "multidex004", "ref-list-1.txt"),
        Paths.get(EXAMPLE_O_SRC_DIR, "multidex004", "ref-list-1.txt"),
        AndroidApiLevel.I);
  }

  @Test
  public void traceMainDexList005_1() throws Throwable {
    doTest5(1);
  }

  @Test
  public void traceMainDexList005_2() throws Throwable {
    doTest5(2);
  }

  @Test
  public void traceMainDexList005_3() throws Throwable {
    doTest5(3);
  }

  @Test
  public void traceMainDexList005_4() throws Throwable {
    doTest(
        "traceMainDexList005",
        "multidex005",
        EXAMPLE_BUILD_DIR,
        Paths.get(EXAMPLE_SRC_DIR, "multidex005", "main-dex-rules-4.txt"),
        Paths.get(EXAMPLE_SRC_DIR, "multidex005", "ref-list-4-r8.txt"),
        Paths.get(EXAMPLE_SRC_DIR, "multidex005", "ref-list-4.txt"),
        AndroidApiLevel.I);
  }

  @Test
  public void traceMainDexList005_5() throws Throwable {
    doTest5(5);
  }

  @Test
  public void traceMainDexList005_6() throws Throwable {
    doTest5(6);
  }

  @Test
  public void traceMainDexList005_7() throws Throwable {
    doTest5(7);
  }

  @Test
  public void traceMainDexList005_8() throws Throwable {
    doTest5(8);
  }

  @Test
  public void traceMainDexList005_9() throws Throwable {
    doTest5(9);
  }

  @Test
  public void traceMainDexList005_10() throws Throwable {
    doTest5(10);
  }

  @Test
  public void traceMainDexList006() throws Throwable {
    doTest(
        "traceMainDexList006",
        "multidex006",
        EXAMPLE_BUILD_DIR,
        Paths.get(EXAMPLE_SRC_DIR, "multidex006", "main-dex-rules-1.txt"),
        Paths.get(EXAMPLE_SRC_DIR, "multidex006", "ref-list-1.txt"),
        Paths.get(EXAMPLE_SRC_DIR, "multidex006", "ref-list-1.txt"),
        AndroidApiLevel.I);
  }

  private void doTest5(int variant) throws Throwable {
    doTest(
        "traceMainDexList005",
        "multidex005",
        EXAMPLE_BUILD_DIR,
        Paths.get(EXAMPLE_SRC_DIR, "multidex005", "main-dex-rules-" + variant + ".txt"),
        Paths.get(EXAMPLE_SRC_DIR, "multidex005", "ref-list-" + variant + ".txt"),
        Paths.get(EXAMPLE_SRC_DIR, "multidex005", "ref-list-" + variant + ".txt"),
        AndroidApiLevel.I);
  }

  private void doTest(
      String testName,
      String packageName,
      String buildDir,
      Path mainDexRules,
      Path expectedR8MainDexList,
      Path expectedMainDexList,
      AndroidApiLevel minSdk)
      throws Throwable {
    doTest(
        testName,
        packageName,
        buildDir,
        mainDexRules,
        expectedR8MainDexList,
        expectedMainDexList,
        minSdk,
        (options) -> {
          options.enableInlining = false;
        });
  }

  private void doTest(
      String testName,
      String packageName,
      String buildDir,
      Path mainDexRules,
      Path expectedR8MainDexList,
      Path expectedMainDexList,
      AndroidApiLevel minSdk,
      Consumer<InternalOptions> optionsConsumer)
      throws Throwable {
    Path out = temp.getRoot().toPath().resolve(testName + ZIP_EXTENSION);

    Path inputJar = Paths.get(buildDir, packageName + JAR_EXTENSION);
    // Build main-dex list using GenerateMainDexList and test the output from run.
    GenerateMainDexListCommand.Builder mdlCommandBuilder = GenerateMainDexListCommand.builder();
    GenerateMainDexListCommand mdlCommand = mdlCommandBuilder
        .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.K))
        .addProgramFiles(inputJar)
        .addProgramFiles(Paths.get(EXAMPLE_BUILD_DIR, "multidexfakeframeworks" + JAR_EXTENSION))
        .addMainDexRulesFiles(mainDexRules)
        .build();
    List<String> mainDexGeneratorMainDexList =
        GenerateMainDexList.run(mdlCommand).stream()
            .map(this::mainDexStringToDescriptor)
            .sorted()
            .collect(Collectors.toList());

    // Build main-dex list using GenerateMainDexList and test the output from a consumer.
    final Box<String> mainDexListOutput = new Box<>();
    mdlCommandBuilder = GenerateMainDexListCommand.builder();
    mdlCommand =
        mdlCommandBuilder
            .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.K))
            .addProgramFiles(inputJar)
            .addProgramFiles(Paths.get(EXAMPLE_BUILD_DIR, "multidexfakeframeworks" + JAR_EXTENSION))
            .addMainDexRulesFiles(mainDexRules)
            .setMainDexListConsumer(ToolHelper.consumeString(mainDexListOutput::set))
            .build();
    GenerateMainDexList.run(mdlCommand);
    List<String> mainDexGeneratorMainDexListFromConsumer =
        StringUtils.splitLines(mainDexListOutput.get()).stream()
            .map(this::mainDexStringToDescriptor)
            .sorted()
            .collect(Collectors.toList());

    // Build main-dex list using R8.
    final Box<String> r8MainDexListOutput = new Box<>();
    testForR8(Backend.DEX)
        .addProgramFiles(inputJar)
        .addProgramFiles(Paths.get(EXAMPLE_BUILD_DIR, "multidexfakeframeworks" + JAR_EXTENSION))
        .addKeepRules("-keepattributes *Annotation*")
        .addMainDexRuleFiles(mainDexRules)
        .addOptionsModification(optionsConsumer)
        .allowDiagnosticWarningMessages()
        .assumeAllMethodsMayHaveSideEffects()
        .setMinApi(minSdk)
        .noMinification()
        .noTreeShaking()
        .setMainDexListConsumer(ToolHelper.consumeString(r8MainDexListOutput::set))
        .compile()
        .assertAllWarningMessagesMatch(equalTo("Resource 'META-INF/MANIFEST.MF' already exists."))
        .writeToZip(out);

    List<String> r8MainDexList =
        StringUtils.splitLines(r8MainDexListOutput.get()).stream()
            .map(this::mainDexStringToDescriptor)
            .sorted()
            .collect(Collectors.toList());
    // Check that generated lists are the same as the reference list, except for lambda
    // classes which are only produced when running R8.
    String[] r8RefList = new String(Files.readAllBytes(
        expectedR8MainDexList), StandardCharsets.UTF_8).split("\n");
    for (int i = 0; i < r8RefList.length; i++) {
      String reference = r8RefList[i].trim();
      if (r8MainDexList.size() <= i) {
        Assert.fail("R8 main dex list is missing '" + reference + "'");
      }
      checkSameMainDexEntry(reference, r8MainDexList.get(i));
    }
    String[] refList = new String(Files.readAllBytes(
        expectedMainDexList), StandardCharsets.UTF_8).split("\n");
    int nonLambdaOffset = 0;
    for (int i = 0; i < refList.length; i++) {
      String reference = refList[i].trim();
      // The main dex list generator does not do any lambda desugaring.
      if (!isLambda(reference)) {
        if (mainDexGeneratorMainDexList.size() <= i - nonLambdaOffset) {
          Assert.fail("Main dex list generator is missing '" + reference + "'");
        }
        checkSameMainDexEntry(reference, mainDexGeneratorMainDexList.get(i - nonLambdaOffset));
        checkSameMainDexEntry(
            reference, mainDexGeneratorMainDexListFromConsumer.get(i - nonLambdaOffset));
      } else {
        nonLambdaOffset++;
      }
    }
    testZipfileOrder(out);
  }

  private void testZipfileOrder(Path out) throws IOException {
    // Sanity check that the classes.dex files are in the correct order
    ZipFile outZip = new ZipFile(out.toFile());
    Enumeration<? extends ZipEntry> entries = outZip.entries();
    int index = 0;
    LinkedList<String> entryNames = new LinkedList<>();
    // We expect classes*.dex files first, in order, then the rest of the files, in order.
    while(entries.hasMoreElements()) {
      ZipEntry entry = entries.nextElement();
      if (!entry.getName().startsWith("classes") || !entry.getName().endsWith(".dex")) {
        entryNames.add(entry.getName());
        continue;
      }
      if (index == 0) {
        Assert.assertEquals("classes.dex", entry.getName());
      } else {
        Assert.assertEquals("classes" + (index + 1) + ".dex", entry.getName());
      }
      index++;
    }
    // Everything else should be sorted according to name.
    String[] entriesUnsorted = entryNames.toArray(StringUtils.EMPTY_ARRAY);
    String[] entriesSorted = entryNames.toArray(StringUtils.EMPTY_ARRAY);
    Arrays.sort(entriesSorted);
    Assert.assertArrayEquals(entriesUnsorted, entriesSorted);
  }

  private boolean isLambda(String mainDexEntry) {
    return mainDexEntry.contains(LambdaRewriter.LAMBDA_CLASS_NAME_PREFIX);
  }

  private String mainDexStringToDescriptor(String mainDexString) {
    Assert.assertTrue(mainDexString.endsWith(FileUtils.CLASS_EXTENSION));
    return DescriptorUtils.getDescriptorFromClassBinaryName(
        mainDexString.substring(0, mainDexString.length() - FileUtils.CLASS_EXTENSION.length()));
  }

  private void checkSameMainDexEntry(String reference, String computed) {
    if (isLambda(reference)) {
      // For lambda classes we check that there is a lambda class for the right containing
      // class. However, we do not check the hash for the generated lambda class. The hash
      // changes for different compiler versions because different compiler versions generate
      // different lambda implementation method names.
      reference = reference.substring(0, reference.lastIndexOf('$'));
      computed = computed.substring(0, computed.lastIndexOf('$'));
    }
    Assert.assertEquals(reference, computed);
  }
}
