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

import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import com.android.tools.r8.GenerateMainDexListCommand;
import com.android.tools.r8.ToolHelper;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.List;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;

public class GenerateMainDexListCommandTest {

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

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

  @Test
  public void emptyCommand() throws Throwable {
    verifyEmptyCommand(GenerateMainDexListCommand.builder().build());
    verifyEmptyCommand(parse());
    verifyEmptyCommand(parse(""));
    verifyEmptyCommand(parse("", ""));
    verifyEmptyCommand(parse(" "));
    verifyEmptyCommand(parse(" ", " "));
    verifyEmptyCommand(parse("\t"));
    verifyEmptyCommand(parse("\t", "\t"));
  }

  private void verifyEmptyCommand(GenerateMainDexListCommand command) throws IOException {
    assertEquals(0, ToolHelper.getApp(command).getDexProgramResourcesForTesting().size());
    assertEquals(0, ToolHelper.getApp(command).getClassProgramResourcesForTesting().size());
    assertFalse(ToolHelper.getApp(command).hasMainDexListResources());
  }

  private void addAndroidJarsToCommandLine(List<String> args) {
    args.add(ToolHelper.getAndroidJar(AndroidApiLevel.K.getLevel()).toAbsolutePath().toString());
  }

  // Add the jars used in the com.android.tools.r8.maindexlist.MainDexTracingTest test.
  private void addInputJarsToCommandLine(List<String> args) {
    args.add(Paths.get(ToolHelper.EXAMPLES_BUILD_DIR, "multidex001" + JAR_EXTENSION)
        .toAbsolutePath().toString());
    args.add(Paths.get(ToolHelper.EXAMPLES_BUILD_DIR, "multidexfakeframeworks" + JAR_EXTENSION)
        .toAbsolutePath().toString());
  }

  // Add main-dex rules used in the com.android.tools.r8.maindexlist.MainDexTracingTest test.
  private void addMainDexRuleToCommandLine(List<String> args) {
    args.add("--main-dex-rules");
    args.add(Paths.get(ToolHelper.EXAMPLES_DIR, "multidex", "main-dex-rules.txt")
        .toAbsolutePath().toString());
  }

  @Test
  public void defaultOutIsCwd() throws Throwable {
    Path working = temp.getRoot().toPath();
    String mainDexListOutput = "main-dex-list.txt";
    Path output = working.resolve(mainDexListOutput);
    assertFalse(Files.exists(output));
    List<String> args = new ArrayList<>();
    addAndroidJarsToCommandLine(args);
    addInputJarsToCommandLine(args);
    addMainDexRuleToCommandLine(args);
    assertEquals(0, ToolHelper.forkGenerateMainDexList(
        working, args, "--main-dex-list-output", mainDexListOutput).exitCode);
    assertTrue(Files.exists(output));
    assertTrue(Files.size(output) > 0);
  }

  @Test
  public void validOutputPath() throws Throwable {
    Path existingFile = temp.getRoot().toPath().resolve("existing_output");
    try (OutputStream existingFileOut = Files.newOutputStream(existingFile,
        StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)) {
      PrintWriter writer = new PrintWriter(existingFileOut);
      writer.println("Hello, world!");
      writer.flush();
    }
    Path nonExistingFile = temp.getRoot().toPath().resolve("non_existing_output");
    assertEquals(
        existingFile,
        GenerateMainDexListCommand.builder().setMainDexListOutputPath(existingFile).build()
            .getMainDexListOutputPath());
    assertEquals(
        nonExistingFile,
        GenerateMainDexListCommand.builder().setMainDexListOutputPath(nonExistingFile).build()
            .getMainDexListOutputPath());
    assertEquals(
        existingFile,
        parse("--main-dex-list-output", existingFile.toString()).getMainDexListOutputPath());
    assertEquals(
        nonExistingFile,
        parse("--main-dex-list-output", nonExistingFile.toString()).getMainDexListOutputPath());
  }

  @Test
  public void nonExistingOutputFileInNonExistingDir() throws Throwable {
    Path nonExistingFileInNonExistingDir =
        temp.getRoot().toPath().resolve("a/path/that/does/not/exist");
    assertEquals(
        nonExistingFileInNonExistingDir,
        GenerateMainDexListCommand.builder()
            .setMainDexListOutputPath(nonExistingFileInNonExistingDir).build()
            .getMainDexListOutputPath());
    assertEquals(
        nonExistingFileInNonExistingDir,
        parse("--main-dex-list-output",
            nonExistingFileInNonExistingDir.toString()).getMainDexListOutputPath());
  }

  @Test
  public void mainDexRules() throws Throwable {
    Path mainDexRules1 = temp.newFile("main-dex-1.rules").toPath();
    Path mainDexRules2 = temp.newFile("main-dex-2.rules").toPath();
    parse("--main-dex-rules", mainDexRules1.toString());
    parse(
        "--main-dex-rules", mainDexRules1.toString(), "--main-dex-rules", mainDexRules2.toString());
  }

  @Test
  public void mainDexList() throws Throwable {
    Path mainDexList1 = temp.newFile("main-dex-list-1.txt").toPath();
    Path mainDexList2 = temp.newFile("main-dex-list-2.txt").toPath();
    parse("--main-dex-list", mainDexList1.toString());
    parse("--main-dex-list", mainDexList1.toString(), "--main-dex-list", mainDexList2.toString());
  }

  private GenerateMainDexListCommand parse(String... args) throws Throwable {
    return GenerateMainDexListCommand.parse(args).build();
  }
}
