// 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 junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertTrue;
import static org.junit.Assume.assumeTrue;

import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestRuntime;
import com.android.tools.r8.TestShrinkerBuilder;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.ToolHelper.ArtCommandBuilder;
import com.android.tools.r8.ToolHelper.ProcessResult;
import com.android.tools.r8.dexsplitter.SplitterTestBase;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import dalvik.system.PathClassLoader;
import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
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 FeatureSplitTest extends DesugaredLibraryTestBase {

  private final TestParameters parameters;
  private final boolean shrinkDesugaredLibrary;

  @Parameters(name = "{1}, shrinkDesugaredLibrary: {0}")
  public static List<Object[]> data() {
    return buildParameters(
        BooleanUtils.values(), getTestParameters().withDexRuntimes().withAllApiLevels().build());
  }

  public FeatureSplitTest(boolean shrinkDesugaredLibrary, TestParameters parameters) {
    this.shrinkDesugaredLibrary = shrinkDesugaredLibrary;
    this.parameters = parameters;
  }

  @Test
  public void testTwoFeatures() throws CompilationFailedException, IOException, ExecutionException {
    CompiledWithFeature compiledWithFeature = new CompiledWithFeature().invoke(this);
    Path basePath = compiledWithFeature.getBasePath();
    Path feature1Path = compiledWithFeature.getFeature1Path();
    Path feature2Path = compiledWithFeature.getFeature2Path();
    Path desugaredLibrary = compiledWithFeature.getDesugaredLibrary();

    assertKeepThe3StreamMethods(compiledWithFeature.getKeepRules());

    assertClassPresent(basePath, BaseClass.class);
    assertClassPresent(feature1Path, FeatureClass.class);
    assertClassPresent(feature2Path, FeatureClass2.class);

    verifyRun(BaseClass.class, basePath, desugaredLibrary, null, "42");
    verifyRun(FeatureClass.class, basePath, desugaredLibrary, feature1Path, "1");
    verifyRun(FeatureClass2.class, basePath, desugaredLibrary, feature2Path, "7");
  }

  private void assertKeepThe3StreamMethods(String keepRules) {
    // Stream desugaring is not needed >= N.
    if (parameters.getApiLevel().getLevel() >= AndroidApiLevel.N.getLevel()) {
      return;
    }
    // Ensure count, toArray and forEach are kept.
    assertTrue(
        keepRules.contains(
            "-keep class j$.lang.Iterable$-EL {\n"
                + "    void forEach(java.lang.Iterable, j$.util.function.Consumer);"));
    assertTrue(
        keepRules.contains(
            "-keep class j$.util.stream.Stream {\n"
                + "    long count();\n"
                + "    java.lang.Object[] toArray();"));
  }

  private void assertClassPresent(Path appPath, Class<?> present)
      throws IOException, ExecutionException {
    CodeInspector inspector = new CodeInspector(appPath);
    assertTrue(inspector.clazz(present).isPresent());
  }

  private void verifyRun(
      Class<?> toRun,
      Path basePath,
      Path desugaredLibrary,
      Path splitterFeatureDexFile,
      String expectedResult)
      throws IOException {
    ProcessResult result =
        runFeatureOnArt(
            toRun, desugaredLibrary, basePath, splitterFeatureDexFile, parameters.getRuntime());
    assertEquals(result.exitCode, 0);
    assertEquals(result.stdout, StringUtils.lines(expectedResult));
  }

  protected ProcessResult runFeatureOnArt(
      Class toRun,
      Path desugaredLibrary,
      Path splitterBaseDexFile,
      Path splitterFeatureDexFile,
      TestRuntime runtime)
      throws IOException {
    assumeTrue(runtime.isDex());
    ArtCommandBuilder commandBuilder = new ArtCommandBuilder(runtime.asDex().getVm());
    commandBuilder.appendClasspath(splitterBaseDexFile.toString());
    if (desugaredLibrary != null) {
      commandBuilder.appendClasspath(desugaredLibrary.toString());
    }
    commandBuilder.appendProgramArgument(toRun.getName());
    if (splitterFeatureDexFile != null) {
      commandBuilder.appendProgramArgument(splitterFeatureDexFile.toString());
    }
    commandBuilder.setMainClass(SplitRunner.class.getName());
    return ToolHelper.runArtRaw(commandBuilder);
  }

  public interface RunInterface {

    void run();
  }

  // Base using ForEach.
  public static class BaseClass implements RunInterface {

    @Override
    public void run() {
      ArrayList<Integer> list = new ArrayList<>();
      list.add(42);
      list.forEach(System.out::println);
    }
  }

  // Feature using count.
  public static class FeatureClass implements RunInterface {

    @SuppressWarnings("ReplaceInefficientStreamCount")
    @Override
    public void run() {
      ArrayList<Object> list = new ArrayList<>();
      list.add(new Object());
      System.out.println(list.stream().count());
    }
  }

  // Feature using toArray.
  public static class FeatureClass2 implements RunInterface {

    @SuppressWarnings("SimplifyStreamApiCallChains")
    @Override
    public void run() {
      ArrayList<Integer> list = new ArrayList<>();
      list.add(7);
      System.out.println(list.stream().toArray()[0]);
    }
  }

  static class SplitRunner {

    /* We support two different modes:
     *   - One argument to main:
     *     Pass in the class to be loaded, must implement RunInterface, run will be called.
     *   - Two arguments to main:
     *     Pass in the class to be loaded, must implement RunInterface, run will be called.
     *     Pass in the feature split that we class load.
     */
    public static void main(String[] args) {
      if (args.length < 1 || args.length > 2) {
        throw new RuntimeException("Unsupported number of arguments");
      }
      String classToRun = args[0];
      ClassLoader loader = SplitRunner.class.getClassLoader();
      // In the case where we simulate splits, we pass in the feature as the second argument
      if (args.length == 2) {
        try {
          loader = new PathClassLoader(args[1], SplitRunner.class.getClassLoader());
        } catch (MalformedURLException e) {
          throw new RuntimeException("Failed reading input URL");
        }
      }

      try {
        Class<?> aClass = loader.loadClass(classToRun);
        RunInterface b = (RunInterface) aClass.newInstance();
        b.run();
      } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
        throw new RuntimeException("Failed loading class");
      }
    }
  }

  private class CompiledWithFeature {

    private Path basePath;
    private Path feature1Path;
    private Path feature2Path;
    private Path desugaredLibrary;
    private String keepRules = "";

    public Path getBasePath() {
      return basePath;
    }

    public Path getFeature1Path() {
      return feature1Path;
    }

    public Path getFeature2Path() {
      return feature2Path;
    }

    public Path getDesugaredLibrary() {
      return desugaredLibrary;
    }

    public String getKeepRules() {
      return keepRules;
    }

    public CompiledWithFeature invoke(FeatureSplitTest tester)
        throws IOException, CompilationFailedException {

      basePath = temp.newFile("base.zip").toPath();
      feature1Path = temp.newFile("feature1.zip").toPath();
      feature2Path = temp.newFile("feature2.zip").toPath();

      KeepRuleConsumer keepRuleConsumer = createKeepRuleConsumer(parameters);
      testForR8(parameters.getBackend())
          .addProgramClasses(BaseClass.class, RunInterface.class, SplitRunner.class)
          .setMinApi(parameters.getApiLevel())
          .addFeatureSplit(
              builder ->
                  SplitterTestBase.simpleSplitProvider(
                      builder, feature1Path, temp, FeatureClass.class))
          .addFeatureSplit(
              builder ->
                  SplitterTestBase.simpleSplitProvider(
                      builder, feature2Path, temp, FeatureClass2.class))
          .addKeepAllClassesRule()
          .applyIf(
              parameters.getApiLevel().isLessThan(AndroidApiLevel.N),
              TestShrinkerBuilder::addDontWarnEmulatedLibraryClasses)
          .enableCoreLibraryDesugaring(parameters.getApiLevel(), keepRuleConsumer)
          .compile()
          .writeToZip(basePath);
      // Stream desugaring is not needed >= N.
      if (parameters.getApiLevel().getLevel() >= AndroidApiLevel.N.getLevel()) {
        return this;
      }
      desugaredLibrary =
          tester.buildDesugaredLibrary(
              parameters.getApiLevel(), keepRuleConsumer.get(), shrinkDesugaredLibrary);
      keepRules = keepRuleConsumer.get();
      return this;
    }
  }
}
