// Copyright (c) 2021, 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 static com.android.tools.r8.LibraryDesugaringTestConfiguration.Configuration.DEFAULT;
import static junit.framework.TestCase.assertNotNull;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.MatcherAssert.assertThat;

import com.android.tools.r8.TestBase.Backend;
import com.android.tools.r8.desugar.desugaredlibrary.DesugaredLibraryTestBase.KeepRuleConsumer;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.google.common.collect.ImmutableList;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;

public class LibraryDesugaringTestConfiguration {

  private static final String RELEASES_DIR = "third_party/openjdk/desugar_jdk_libs_releases/";

  public enum Configuration {
    DEFAULT(
        ToolHelper.getDesugarJDKLibs(),
        ToolHelper.DESUGAR_LIB_CONVERSIONS,
        ToolHelper.getDesugarLibJsonForTesting()),
    DEFAULT_JDK11(
        Paths.get("third_party/openjdk/desugar_jdk_libs_11/desugar_jdk_libs.jar"),
        ToolHelper.DESUGAR_LIB_CONVERSIONS,
        Paths.get("src/library_desugar/jdk11/desugar_jdk_libs.json")),
    RELEASED_1_0_9("1.0.9"),
    RELEASED_1_0_10("1.0.10"),
    RELEASED_1_1_0("1.1.0"),
    RELEASED_1_1_1("1.1.1"),
    RELEASED_1_1_5("1.1.5");

    private final Path desugarJdkLibs;
    private final Path customConversions;
    private final Path configuration;

    Configuration(Path desugarJdkLibs, Path customConversions, Path configuration) {
      this.desugarJdkLibs = desugarJdkLibs;
      this.customConversions = customConversions;
      this.configuration = configuration;
    }

    Configuration(String version) {
      this(
          Paths.get(RELEASES_DIR, version, "desugar_jdk_libs.jar"),
          Paths.get(RELEASES_DIR, version, "desugar_jdk_libs_configuration.jar"),
          Paths.get(RELEASES_DIR, version, "desugar.json"));
    }

    public static List<Configuration> getReleased() {
      return ImmutableList.of(
          RELEASED_1_0_9, RELEASED_1_0_10, RELEASED_1_1_0, RELEASED_1_1_1, RELEASED_1_1_5);
    }
  }

  private final AndroidApiLevel minApiLevel;
  private final Path desugarJdkLibs;
  private final Path customConversions;
  private final List<StringResource> desugaredLibrarySpecificationResources;
  private final boolean withKeepRuleConsumer;
  private final KeepRuleConsumer keepRuleConsumer;
  private final CompilationMode mode;
  private final boolean addRunClassPath;

  public static final LibraryDesugaringTestConfiguration DISABLED =
      new LibraryDesugaringTestConfiguration();

  private LibraryDesugaringTestConfiguration() {
    this.minApiLevel = null;
    this.desugarJdkLibs = null;
    this.customConversions = null;
    this.keepRuleConsumer = null;
    this.withKeepRuleConsumer = false;
    this.desugaredLibrarySpecificationResources = null;
    this.mode = null;
    this.addRunClassPath = false;
  }

  private LibraryDesugaringTestConfiguration(
      AndroidApiLevel minApiLevel,
      Path desugarJdkLibs,
      Path customConversions,
      List<StringResource> desugaredLibrarySpecificationResources,
      boolean withKeepRuleConsumer,
      KeepRuleConsumer keepRuleConsumer,
      CompilationMode mode,
      boolean addRunClassPath) {
    this.minApiLevel = minApiLevel;
    this.desugarJdkLibs = desugarJdkLibs;
    this.customConversions = customConversions;
    this.desugaredLibrarySpecificationResources = desugaredLibrarySpecificationResources;
    this.withKeepRuleConsumer = withKeepRuleConsumer;
    this.keepRuleConsumer = keepRuleConsumer;
    this.mode = mode;
    this.addRunClassPath = addRunClassPath;
  }

  public static class Builder {

    AndroidApiLevel minApiLevel;
    private Path desugarJdkLibs;
    private Path customConversions;
    private final List<StringResource> desugaredLibrarySpecificationResources = new ArrayList<>();
    boolean withKeepRuleConsumer = false;
    KeepRuleConsumer keepRuleConsumer;
    private CompilationMode mode = CompilationMode.DEBUG;
    boolean addRunClassPath = true;

    private Builder() {}

    public Builder setMinApi(AndroidApiLevel minApiLevel) {
      this.minApiLevel = minApiLevel;
      return this;
    }

    public Builder setConfiguration(Configuration configuration) {
      desugarJdkLibs = configuration.desugarJdkLibs;
      customConversions = configuration.customConversions;
      desugaredLibrarySpecificationResources.clear();
      desugaredLibrarySpecificationResources.add(
          StringResource.fromFile(configuration.configuration));
      return this;
    }

    public Builder withKeepRuleConsumer() {
      withKeepRuleConsumer = true;
      return this;
    }

    public Builder setKeepRuleConsumer(KeepRuleConsumer keepRuleConsumer) {
      withKeepRuleConsumer = false;
      if (keepRuleConsumer == null) {
        this.keepRuleConsumer = null;
      } else {
        this.keepRuleConsumer = keepRuleConsumer;
      }
      return this;
    }

    public Builder addDesugaredLibraryConfiguration(StringResource desugaredLibrarySpecification) {
      desugaredLibrarySpecificationResources.add(desugaredLibrarySpecification);
      return this;
    }

    public Builder setMode(CompilationMode mode) {
      this.mode = mode;
      return this;
    }

    public Builder dontAddRunClasspath() {
      addRunClassPath = false;
      return this;
    }

    public LibraryDesugaringTestConfiguration build() {
      if (desugaredLibrarySpecificationResources.isEmpty()) {
        desugaredLibrarySpecificationResources.add(
            StringResource.fromFile(ToolHelper.getDesugarLibJsonForTesting()));
      }
      if (withKeepRuleConsumer) {
        this.keepRuleConsumer = createKeepRuleConsumer(minApiLevel);
      }
      return new LibraryDesugaringTestConfiguration(
          minApiLevel,
          desugarJdkLibs != null ? desugarJdkLibs : DEFAULT.desugarJdkLibs,
          customConversions != null ? customConversions : DEFAULT.customConversions,
          desugaredLibrarySpecificationResources,
          withKeepRuleConsumer,
          keepRuleConsumer,
          mode,
          addRunClassPath);
    }
  }

  public static Builder builder() {
    return new Builder();
  }

  public static LibraryDesugaringTestConfiguration forApiLevel(AndroidApiLevel apiLevel) {
    return LibraryDesugaringTestConfiguration.builder().setMinApi(apiLevel).build();
  }

  public boolean isEnabled() {
    return this != DISABLED;
  }

  public boolean isAddRunClassPath() {
    return addRunClassPath;
  }

  public void configure(D8Command.Builder builder) {
    if (!isEnabled()) {
      return;
    }
    if (keepRuleConsumer != null) {
      builder.setDesugaredLibraryKeepRuleConsumer(keepRuleConsumer);
    }
    desugaredLibrarySpecificationResources.forEach(builder::addDesugaredLibraryConfiguration);
  }

  public void configure(R8Command.Builder builder) {
    if (!isEnabled()) {
      return;
    }
    if (keepRuleConsumer != null) {
      builder.setDesugaredLibraryKeepRuleConsumer(keepRuleConsumer);
    }
    desugaredLibrarySpecificationResources.forEach(builder::addDesugaredLibraryConfiguration);
  }

  public Path buildDesugaredLibrary(TestState state) {
    String generatedKeepRules = null;
    if (withKeepRuleConsumer) {
      if (keepRuleConsumer instanceof PresentKeepRuleConsumer) {
        generatedKeepRules = keepRuleConsumer.get();
        assertNotNull(generatedKeepRules);
      } else {
        assertThat(keepRuleConsumer, instanceOf(AbsentKeepRuleConsumer.class));
      }
    }
    String finalGeneratedKeepRules = generatedKeepRules;
    try {
      assert desugaredLibrarySpecificationResources.size() == 1 : "There can be only one";
      return L8TestBuilder.create(minApiLevel, Backend.DEX, state)
          .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P))
          .setDesugarJDKLibs(desugarJdkLibs)
          .setDesugarJDKLibsConfiguration(customConversions)
          .setDesugaredLibraryConfiguration(desugaredLibrarySpecificationResources.get(0))
          .applyIf(
              mode == CompilationMode.RELEASE,
              builder -> {
                if (finalGeneratedKeepRules != null && !finalGeneratedKeepRules.trim().isEmpty()) {
                  builder.addGeneratedKeepRules(finalGeneratedKeepRules);
                }
              },
              L8TestBuilder::setDebug)
          .compile()
          .writeToZip();
    } catch (CompilationFailedException | ExecutionException | IOException e) {
      throw new RuntimeException(e);
    }
  }

  public KeepRuleConsumer getKeepRuleConsumer() {
    return keepRuleConsumer;
  }

  public static KeepRuleConsumer createKeepRuleConsumer(TestParameters parameters) {
    return createKeepRuleConsumer(parameters.getApiLevel());
  }

  private static KeepRuleConsumer createKeepRuleConsumer(AndroidApiLevel apiLevel) {
      return new PresentKeepRuleConsumer();
  }

  public static class PresentKeepRuleConsumer implements KeepRuleConsumer {

    StringBuilder stringBuilder = new StringBuilder();
    String result = null;

    @Override
    public void accept(String string, DiagnosticsHandler handler) {
      assert stringBuilder != null;
      assert result == null;
      stringBuilder.append(string);
    }

    @Override
    public void finished(DiagnosticsHandler handler) {
      assert stringBuilder != null;
      assert result == null;
      result = stringBuilder.toString();
      stringBuilder = null;
    }

    public String get() {
      // TODO(clement): remove that branch once StringConsumer has finished again.
      if (stringBuilder != null) {
        finished(null);
      }

      assert stringBuilder == null;
      assert result != null;
      return result;
    }
  }

  public static class AbsentKeepRuleConsumer implements KeepRuleConsumer {

    public String get() {
      return null;
    }

    @Override
    public void accept(String string, DiagnosticsHandler handler) {
      throw new Unreachable("No desugaring on high API levels");
    }

    @Override
    public void finished(DiagnosticsHandler handler) {
      throw new Unreachable("No desugaring on high API levels");
    }
  }
}
