// Copyright (c) 2022, 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.test;

import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.CompilationMode;
import com.android.tools.r8.D8TestCompileResult;
import com.android.tools.r8.FeatureSplit;
import com.android.tools.r8.L8TestBuilder;
import com.android.tools.r8.L8TestCompileResult;
import com.android.tools.r8.LibraryDesugaringTestConfiguration;
import com.android.tools.r8.R8TestBuilder;
import com.android.tools.r8.SingleTestRunResult;
import com.android.tools.r8.StringResource;
import com.android.tools.r8.TestBase.Backend;
import com.android.tools.r8.TestCompileResult;
import com.android.tools.r8.TestCompilerBuilder;
import com.android.tools.r8.TestCompilerBuilder.DiagnosticsConsumer;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestRuntime;
import com.android.tools.r8.TestShrinkerBuilder;
import com.android.tools.r8.desugar.desugaredlibrary.DesugaredLibraryTestBase;
import com.android.tools.r8.desugar.desugaredlibrary.DesugaredLibraryTestBase.KeepRuleConsumer;
import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibrarySpecificationParser;
import com.android.tools.r8.tracereferences.TraceReferences;
import com.android.tools.r8.utils.ConsumerUtils;
import com.android.tools.r8.utils.FileUtils;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.codeinspector.VerticallyMergedClassesInspector;
import com.google.common.base.Charsets;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.function.Consumer;
import java.util.function.Function;
import org.junit.Assume;

public class DesugaredLibraryTestBuilder<T extends DesugaredLibraryTestBase> {

  private final T test;
  private final TestParameters parameters;
  private final LibraryDesugaringSpecification libraryDesugaringSpecification;
  private final CompilationSpecification compilationSpecification;
  private final TestCompilerBuilder<?, ?, ?, ? extends SingleTestRunResult<?>, ?> builder;
  private String l8ExtraKeepRules = "";
  private Consumer<InternalOptions> l8OptionModifier = ConsumerUtils.emptyConsumer();
  private boolean l8FinalPrefixVerification = true;

  private CustomLibrarySpecification customLibrarySpecification = null;
  private TestingKeepRuleConsumer keepRuleConsumer = null;

  public DesugaredLibraryTestBuilder(
      T test,
      TestParameters parameters,
      LibraryDesugaringSpecification libraryDesugaringSpecification,
      CompilationSpecification runSpecification) {
    this.test = test;
    this.parameters = parameters;
    this.libraryDesugaringSpecification = libraryDesugaringSpecification;
    this.compilationSpecification = runSpecification;
    this.builder = generateBuilder();
    setUp();
  }

  private void setUp() {
    builder
        .addLibraryFiles(libraryDesugaringSpecification.getLibraryFiles())
        .setMinApi(parameters.getApiLevel())
        .setMode(compilationSpecification.getProgramCompilationMode());
    LibraryDesugaringTestConfiguration.Builder libraryConfBuilder =
        LibraryDesugaringTestConfiguration.builder()
            .addDesugaredLibraryConfiguration(
                StringResource.fromFile(libraryDesugaringSpecification.getSpecification()));
    if (compilationSpecification.isL8Shrink() && !compilationSpecification.isCfToCf()) {
      keepRuleConsumer = new TestingKeepRuleConsumer();
      libraryConfBuilder.setKeepRuleConsumer(keepRuleConsumer);
    }
    builder.enableCoreLibraryDesugaring(libraryConfBuilder.build());
  }

  private TestCompilerBuilder<?, ?, ?, ? extends SingleTestRunResult<?>, ?> generateBuilder() {
    if (compilationSpecification.isCfToCf()) {
      assert !compilationSpecification.isProgramShrink();
      if (compilationSpecification.isL8Shrink()) {
        // L8 with Cf backend and shrinking is not a supported pipeline.
        Assume.assumeTrue(parameters.getBackend().isDex());
      }
      return test.testForD8(Backend.CF);
    }
    // Cf back-end is only allowed in Cf to cf compilations.
    Assume.assumeTrue(parameters.getBackend().isDex());
    if (compilationSpecification.isProgramShrink()) {
      return test.testForR8(parameters.getBackend());
    }
    return test.testForD8(Backend.DEX);
  }

  public DesugaredLibraryTestBuilder<T> setCustomLibrarySpecification(
      CustomLibrarySpecification customLibrarySpecification) {
    this.customLibrarySpecification = customLibrarySpecification;
    builder.addLibraryClasses(customLibrarySpecification.getClasses());
    return this;
  }

  public DesugaredLibraryTestBuilder<T> addL8OptionsModification(
      Consumer<InternalOptions> optionModifier) {
    l8OptionModifier = l8OptionModifier.andThen(optionModifier);
    return this;
  }

  public DesugaredLibraryTestBuilder<T> addOptionsModification(
      Consumer<InternalOptions> optionModifier) {
    builder.addOptionsModification(optionModifier);
    return this;
  }

  public DesugaredLibraryTestBuilder<T> addProgramClassesAndInnerClasses(Class<?>... clazz)
      throws IOException {
    builder.addProgramClassesAndInnerClasses(clazz);
    return this;
  }

  public DesugaredLibraryTestBuilder<T> addInnerClasses(Class<?>... clazz) throws IOException {
    builder.addInnerClasses(clazz);
    return this;
  }

  public DesugaredLibraryTestBuilder<T> addClasspathClasses(Class<?>... clazz) throws IOException {
    builder.addClasspathClasses(clazz);
    return this;
  }

  public DesugaredLibraryTestBuilder<T> addProgramClasses(Class<?>... clazz) throws IOException {
    builder.addProgramClasses(clazz);
    return this;
  }

  public DesugaredLibraryTestBuilder<T> addProgramClasses(Collection<Class<?>> clazz)
      throws IOException {
    builder.addProgramClasses(clazz);
    return this;
  }

  public DesugaredLibraryTestBuilder<T> addProgramFiles(Path... files) {
    builder.addProgramFiles(files);
    return this;
  }

  public DesugaredLibraryTestBuilder<T> addProgramFiles(Collection<Path> files) {
    builder.addProgramFiles(files);
    return this;
  }

  public DesugaredLibraryTestBuilder<T> ignoreL8FinalPrefixVerification() {
    l8FinalPrefixVerification = false;
    return this;
  }

  public DesugaredLibraryTestBuilder<T> addProgramClassFileData(
      Collection<byte[]> programClassFileData) {
    builder.addProgramClassFileData(programClassFileData);
    return this;
  }

  public DesugaredLibraryTestBuilder<T> setMode(CompilationMode mode) {
    builder.setMode(mode);
    return this;
  }

  private void withR8TestBuilder(Consumer<R8TestBuilder<?>> consumer) {
    if (!builder.isTestShrinkerBuilder()) {
      return;
    }
    consumer.accept((R8TestBuilder<?>) builder);
  }

  public DesugaredLibraryTestBuilder<T> allowUnusedDontWarnPatterns() {
    withR8TestBuilder(R8TestBuilder::allowUnusedDontWarnPatterns);
    return this;
  }

  public DesugaredLibraryTestBuilder<T> allowUnusedProguardConfigurationRules() {
    withR8TestBuilder(R8TestBuilder::allowUnusedProguardConfigurationRules);
    return this;
  }

  public DesugaredLibraryTestBuilder<T> allowDiagnosticMessages() {
    withR8TestBuilder(R8TestBuilder::allowDiagnosticMessages);
    return this;
  }

  public DesugaredLibraryTestBuilder<T> allowUnusedDontWarnKotlinReflectJvmInternal(boolean allow) {
    withR8TestBuilder(b -> b.allowUnusedDontWarnKotlinReflectJvmInternal(allow));
    return this;
  }

  public DesugaredLibraryTestBuilder<T> allowDiagnosticInfoMessages() {
    withR8TestBuilder(R8TestBuilder::allowDiagnosticInfoMessages);
    return this;
  }

  public DesugaredLibraryTestBuilder<T> allowDiagnosticWarningMessages() {
    withR8TestBuilder(R8TestBuilder::allowDiagnosticWarningMessages);
    return this;
  }

  public DesugaredLibraryTestBuilder<T> addKeepRules(String keepRules) {
    withR8TestBuilder(b -> b.addKeepRules(keepRules));
    return this;
  }

  public DesugaredLibraryTestBuilder<T> addL8KeepRules(String keepRules) {
    if (compilationSpecification.isL8Shrink()) {
      l8ExtraKeepRules += keepRules + "\n";
    }
    return this;
  }

  public DesugaredLibraryTestBuilder<T> addKeepClassAndMembersRules(Class<?>... clazz) {
    withR8TestBuilder(b -> b.addKeepClassAndMembersRules(clazz));
    return this;
  }

  public DesugaredLibraryTestBuilder<T> addKeepAttributes(String... attributes) {
    withR8TestBuilder(b -> b.addKeepAttributes(attributes));
    return this;
  }

  public DesugaredLibraryTestBuilder<T> addKeepAllClassesRuleWithAllowObfuscation() {
    withR8TestBuilder(TestShrinkerBuilder::addKeepAllClassesRuleWithAllowObfuscation);
    return this;
  }

  public DesugaredLibraryTestBuilder<T> addKeepAllClassesRule() {
    withR8TestBuilder(TestShrinkerBuilder::addKeepAllClassesRule);
    return this;
  }

  public DesugaredLibraryTestBuilder<T> addKeepMainRule(Class<?> clazz) {
    withR8TestBuilder(b -> b.addKeepMainRule(clazz));
    return this;
  }

  public DesugaredLibraryTestBuilder<T> addKeepMainRule(String mainClass) {
    withR8TestBuilder(b -> b.addKeepMainRule(mainClass));
    return this;
  }

  public DesugaredLibraryTestBuilder<T> addKeepRuleFiles(Path... files) {
    withR8TestBuilder(b -> b.addKeepRuleFiles(files));
    return this;
  }

  public DesugaredLibraryTestBuilder<T> addFeatureSplit(
      Function<FeatureSplit.Builder, FeatureSplit> featureSplitBuilder) {
    withR8TestBuilder(b -> b.addFeatureSplit(featureSplitBuilder));
    return this;
  }

  public DesugaredLibraryTestBuilder<T> enableNeverClassInliningAnnotations() {
    withR8TestBuilder(R8TestBuilder::enableNeverClassInliningAnnotations);
    return this;
  }

  public DesugaredLibraryTestBuilder<T> enableInliningAnnotations() {
    withR8TestBuilder(R8TestBuilder::enableInliningAnnotations);
    return this;
  }

  public DesugaredLibraryTestBuilder<T> enableNoVerticalClassMergingAnnotations() {
    withR8TestBuilder(R8TestBuilder::enableNoVerticalClassMergingAnnotations);
    return this;
  }

  public DesugaredLibraryTestBuilder<T> addVerticallyMergedClassesInspector(
      Consumer<VerticallyMergedClassesInspector> inspector) {
    withR8TestBuilder(b -> b.addVerticallyMergedClassesInspector(inspector));
    return this;
  }

  public DesugaredLibraryTestBuilder<T> noMinification() {
    withR8TestBuilder(R8TestBuilder::noMinification);
    return this;
  }

  public DesugaredLibraryTestBuilder<T> enableConstantArgumentAnnotations() {
    withR8TestBuilder(R8TestBuilder::enableConstantArgumentAnnotations);
    return this;
  }

  public DesugaredLibraryTestBuilder<T> applyOnBuilder(
      Consumer<TestCompilerBuilder<?, ?, ?, ?, ?>> consumer) {
    consumer.accept(builder);
    return this;
  }

  public DesugaredLibraryTestBuilder<T> applyIf(
      boolean apply, Consumer<DesugaredLibraryTestBuilder<T>> consumer) {
    if (apply) {
      consumer.accept(this);
    }
    return this;
  }

  public DesugaredLibraryTestBuilder<T> disableL8AnnotationRemoval() {
    l8OptionModifier =
        l8OptionModifier.andThen(options -> options.disableL8AnnotationRemoval = true);
    return this;
  }

  public DesugaredLibraryTestCompileResult<T> compile() throws Exception {
    TestCompileResult<?, ? extends SingleTestRunResult<?>> compile = builder.compile();
    return internalCompile(compile);
  }

  public DesugaredLibraryTestCompileResult<T> compileWithExpectedDiagnostics(
      DiagnosticsConsumer consumer) throws Exception {
    TestCompileResult<?, ? extends SingleTestRunResult<?>> compile =
        builder.compileWithExpectedDiagnostics(consumer);
    return internalCompile(compile);
  }

  private DesugaredLibraryTestCompileResult<T> internalCompile(
      TestCompileResult<?, ? extends SingleTestRunResult<?>> compile) throws Exception {
    L8TestCompileResult l8Compile = compileDesugaredLibrary(compile, keepRuleConsumer);
    D8TestCompileResult customLibCompile = compileCustomLib();
    return new DesugaredLibraryTestCompileResult<>(
        test,
        compile,
        parameters,
        libraryDesugaringSpecification,
        compilationSpecification,
        customLibCompile,
        l8Compile);
  }

  private D8TestCompileResult compileCustomLib() throws CompilationFailedException {
    if (customLibrarySpecification == null) {
      return null;
    }
    return test.testForD8(parameters.getBackend())
        .addProgramClasses(customLibrarySpecification.getClasses())
        .setMinApi(customLibrarySpecification.getMinApi())
        .compile();
  }

  private L8TestCompileResult compileDesugaredLibrary(
      TestCompileResult<?, ? extends SingleTestRunResult<?>> compile,
      KeepRuleConsumer keepRuleConsumer)
      throws Exception {
    if (!compilationSpecification.isL8Shrink()) {
      return compileDesugaredLibrary(null);
    }
    if (!compilationSpecification.isTraceReferences()) {
      // When going to dex we can get the generated keep rule through the keep rule consumer.
      assert keepRuleConsumer != null;
      return compileDesugaredLibrary(keepRuleConsumer.get());
    }
    L8TestCompileResult nonShrunk =
        test.testForL8(parameters.getApiLevel(), Backend.CF)
            .apply(libraryDesugaringSpecification::configureL8TestBuilder)
            .apply(b -> configure(b, Backend.CF))
            .compile();
    String keepRules =
        collectKeepRulesWithTraceReferences(compile.writeToZip(), nonShrunk.writeToZip());
    return compileDesugaredLibrary(keepRules);
  }

  private L8TestCompileResult compileDesugaredLibrary(String keepRule) throws Exception {
    assert !compilationSpecification.isL8Shrink() || keepRule != null;
    return test.testForL8(parameters.getApiLevel(), parameters.getBackend())
        .apply(
            b ->
                libraryDesugaringSpecification.configureL8TestBuilder(
                    b, compilationSpecification.isL8Shrink(), keepRule))
        .apply(b -> configure(b, parameters.getBackend()))
        .compile();
  }

  private void configure(L8TestBuilder l8Builder, Backend backend) {
    l8Builder
        .applyIf(!l8FinalPrefixVerification, L8TestBuilder::ignoreFinalPrefixVerification)
        .applyIf(
            compilationSpecification.isL8Shrink() && !backend.isCf() && !l8ExtraKeepRules.isEmpty(),
            b -> b.addKeepRules(l8ExtraKeepRules))
        .addOptionsModifier(l8OptionModifier);
  }

  public String collectKeepRulesWithTraceReferences(
      Path desugaredProgramClassFile, Path desugaredLibraryClassFile) throws Exception {
    Path generatedKeepRules = test.temp.newFile().toPath();
    ArrayList<String> args = new ArrayList<>();
    args.add("--keep-rules");
    for (Path libraryFile : libraryDesugaringSpecification.getLibraryFiles()) {
      args.add("--lib");
      args.add(libraryFile.toString());
    }
    args.add("--target");
    args.add(desugaredLibraryClassFile.toString());
    args.add("--source");
    args.add(desugaredProgramClassFile.toString());
    args.add("--output");
    args.add(generatedKeepRules.toString());
    args.add("--map-diagnostics");
    args.add("error");
    args.add("info");
    TraceReferences.run(args.toArray(new String[0]));
    return FileUtils.readTextFile(generatedKeepRules, Charsets.UTF_8);
  }

  public SingleTestRunResult<?> run(TestRuntime runtime, Class<?> mainClass, String... args)
      throws Exception {
    return compile().run(runtime, mainClass.getTypeName(), args);
  }

  public SingleTestRunResult<?> run(TestRuntime runtime, String mainClass, String... args)
      throws Exception {
    return compile().run(runtime, mainClass, args);
  }

  public DesugaredLibraryTestBuilder<T> supportAllCallbacksFromLibrary(
      boolean supportAllCallbacksFromLibrary) {
    addL8OptionsModification(supportLibraryCallbackConsumer(supportAllCallbacksFromLibrary, true));
    builder.addOptionsModification(
        supportLibraryCallbackConsumer(supportAllCallbacksFromLibrary, false));
    return this;
  }

  private Consumer<InternalOptions> supportLibraryCallbackConsumer(
      boolean supportAllCallbacksFromLibrary, boolean libraryCompilation) {
    return opt ->
        opt.setDesugaredLibrarySpecification(
            DesugaredLibrarySpecificationParser.parseDesugaredLibrarySpecificationforTesting(
                StringResource.fromFile(libraryDesugaringSpecification.getSpecification()),
                opt.dexItemFactory(),
                opt.reporter,
                libraryCompilation,
                parameters.getApiLevel().getLevel(),
                builder ->
                    builder.setSupportAllCallbacksFromLibrary(supportAllCallbacksFromLibrary)));
  }

  public DesugaredLibraryTestBuilder<T> addAndroidBuildVersion() {
    builder.addAndroidBuildVersion();
    return this;
  }

  public DesugaredLibraryTestBuilder<T> disableDesugaring() {
    builder.disableDesugaring();
    return this;
  }
}
