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

import com.android.tools.r8.ToolHelper.ProcessResult;
import com.android.tools.r8.utils.CompilationFailedException;
import com.android.tools.r8.utils.FileUtils;
import com.google.common.collect.ImmutableList;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

public class R8EntryPointTests extends TestBase {

  private static final String MAPPING = "mapping.txt";
  private static final String SEEDS = "seeds.txt";
  private static final Path INPUT_JAR =
      Paths.get(ToolHelper.EXAMPLES_BUILD_DIR, "minification" + FileUtils.JAR_EXTENSION);
  private static final Path PROGUARD_FLAGS =
      Paths.get(ToolHelper.EXAMPLES_DIR, "minification",  "keep-rules.txt");

  private Path testFlags;

  @Before
  public void setup() throws IOException {
    testFlags = temp.newFile("local.flags").toPath();
    FileUtils.writeTextFile(testFlags, ImmutableList.of(
        "-printseeds " + SEEDS,
        "-printmapping " + MAPPING));
  }

  @Test
  public void testRun1Dir() throws Exception {
    Path out = temp.newFolder("outdex").toPath();
    R8.run(getCommand(out));
    Assert.assertTrue(Files.isRegularFile(out.resolve(ToolHelper.DEFAULT_DEX_FILENAME)));
    Assert.assertTrue(Files.isRegularFile(testFlags.getParent().resolve(MAPPING)));
    Assert.assertTrue(Files.isRegularFile(testFlags.getParent().resolve(SEEDS)));
  }

  @Test
  public void testRun1Zip() throws Exception {
    Path out = temp.newFolder("outdex").toPath().resolve("dex.zip");
    R8.run(getCommand(out));
    Assert.assertTrue(Files.isRegularFile(out));
    Assert.assertTrue(Files.isRegularFile(testFlags.getParent().resolve(MAPPING)));
    Assert.assertTrue(Files.isRegularFile(testFlags.getParent().resolve(SEEDS)));
  }

  @Test
  public void testRun2Dir() throws Exception {
    Path out = temp.newFolder("outdex").toPath();
    ExecutorService executor = Executors.newWorkStealingPool(2);
    try {
      R8.run(getCommand(out), executor);
    } finally {
      executor.shutdown();
    }
    Assert.assertTrue(Files.isRegularFile(out.resolve(ToolHelper.DEFAULT_DEX_FILENAME)));
    Assert.assertTrue(Files.isRegularFile(testFlags.getParent().resolve(MAPPING)));
    Assert.assertTrue(Files.isRegularFile(testFlags.getParent().resolve(SEEDS)));
  }

  @Test
  public void testRun2Zip() throws Exception {
    Path out = temp.newFolder("outdex").toPath().resolve("dex.zip");
    ExecutorService executor = Executors.newWorkStealingPool(2);
    try {
      R8.run(getCommand(out), executor);
    } finally {
      executor.shutdown();
    }
    Assert.assertTrue(Files.isRegularFile(out));
    Assert.assertTrue(Files.isRegularFile(testFlags.getParent().resolve(MAPPING)));
    Assert.assertTrue(Files.isRegularFile(testFlags.getParent().resolve(SEEDS)));
  }

  @Test
  public void testMainDir() throws IOException, InterruptedException {
    Path out = temp.newFolder("outdex").toPath();
    ProcessResult r8 = ToolHelper.forkR8(Paths.get("."),
        "--lib", ToolHelper.getDefaultAndroidJar(),
        "--output", out.toString(),
        "--pg-conf", PROGUARD_FLAGS.toString(),
        "--pg-conf", testFlags.toString(),
        INPUT_JAR.toString());
    Assert.assertEquals(0, r8.exitCode);
    Assert.assertTrue(Files.isRegularFile(out.resolve(ToolHelper.DEFAULT_DEX_FILENAME)));
    Assert.assertTrue(Files.isRegularFile(testFlags.getParent().resolve(MAPPING)));
    Assert.assertTrue(Files.isRegularFile(testFlags.getParent().resolve(SEEDS)));
  }

  @Test
  public void testMainRelativeDir() throws IOException, InterruptedException {
    temp.newFolder("outdex");
    Path out = Paths.get("outdex");
    Path workingDir = temp.getRoot().toPath();
    ProcessResult r8 = ToolHelper.forkR8(workingDir,
        "--lib", Paths.get(ToolHelper.getDefaultAndroidJar()).toAbsolutePath().toString(),
        "--output", out.toString(),
        "--pg-conf", PROGUARD_FLAGS.toAbsolutePath().toString(),
        "--pg-conf", testFlags.toAbsolutePath().toString(),
        INPUT_JAR.toAbsolutePath().toString());
    Assert.assertEquals(0, r8.exitCode);
    Assert.assertTrue(
        Files.isRegularFile(workingDir.resolve(out).resolve(ToolHelper.DEFAULT_DEX_FILENAME)));
    Assert.assertTrue(Files.isRegularFile(testFlags.getParent().resolve(MAPPING)));
    Assert.assertTrue(Files.isRegularFile(testFlags.getParent().resolve(SEEDS)));
  }


  @Test
  public void testMainZip() throws IOException, InterruptedException {
    Path out = temp.newFolder("outdex").toPath().resolve("dex.zip");
    ProcessResult r8 = ToolHelper.forkR8(Paths.get("."),
        "--lib", ToolHelper.getDefaultAndroidJar(),
        "--output", out.toString(),
        "--pg-conf", PROGUARD_FLAGS.toString(),
        "--pg-conf", testFlags.toString(),
        INPUT_JAR.toString());
    Assert.assertEquals(0, r8.exitCode);
    Assert.assertTrue(Files.isRegularFile(out));
    Assert.assertTrue(Files.isRegularFile(testFlags.getParent().resolve(MAPPING)));
    Assert.assertTrue(Files.isRegularFile(testFlags.getParent().resolve(SEEDS)));
  }

  private R8Command getCommand(Path out)
      throws CompilationException, IOException, CompilationFailedException {
    return R8Command.builder()
      .addLibraryFiles(Paths.get(ToolHelper.getDefaultAndroidJar()))
      .addProgramFiles(INPUT_JAR)
      .setOutputPath(out)
      .addProguardConfigurationFiles(PROGUARD_FLAGS, testFlags)
      .build();
  }
}
