// 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.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> desugaredLibraryConfigurationResources;
  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.desugaredLibraryConfigurationResources = null;
    this.mode = null;
    this.addRunClassPath = false;
  }

  private LibraryDesugaringTestConfiguration(
      AndroidApiLevel minApiLevel,
      Path desugarJdkLibs,
      Path customConversions,
      List<StringResource> desugaredLibraryConfigurationResources,
      boolean withKeepRuleConsumer,
      KeepRuleConsumer keepRuleConsumer,
      CompilationMode mode,
      boolean addRunClassPath) {
    this.minApiLevel = minApiLevel;
    this.desugarJdkLibs = desugarJdkLibs;
    this.customConversions = customConversions;
    this.desugaredLibraryConfigurationResources = desugaredLibraryConfigurationResources;
    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> desugaredLibraryConfigurationResources = 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;
      desugaredLibraryConfigurationResources.clear();
      desugaredLibraryConfigurationResources.add(
          StringResource.fromFile(configuration.configuration));
      return this;
    }

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

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

    public Builder addDesugaredLibraryConfiguration(StringResource desugaredLibraryConfiguration) {
      desugaredLibraryConfigurationResources.add(desugaredLibraryConfiguration);
      return this;
    }

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

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

    public LibraryDesugaringTestConfiguration build() {
      if (desugaredLibraryConfigurationResources.isEmpty()) {
        desugaredLibraryConfigurationResources.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,
          desugaredLibraryConfigurationResources,
          withKeepRuleConsumer,
          keepRuleConsumer,
          mode,
          addRunClassPath);
    }
  }

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

  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);
    }
    desugaredLibraryConfigurationResources.forEach(builder::addDesugaredLibraryConfiguration);
  }

  public void configure(R8Command.Builder builder) {
    if (!isEnabled()) {
      return;
    }
    if (keepRuleConsumer != null) {
      builder.setDesugaredLibraryKeepRuleConsumer(keepRuleConsumer);
    }
    desugaredLibraryConfigurationResources.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 {
      return L8TestBuilder.create(minApiLevel, state)
          .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P))
          .setDesugarJDKLibs(desugarJdkLibs)
          .setDesugarJDKLibsConfiguration(customConversions)
          .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) {
    if (requiresAnyCoreLibDesugaring(apiLevel)) {
      return new PresentKeepRuleConsumer();
    }
    return new AbsentKeepRuleConsumer();
  }

  private static boolean requiresAnyCoreLibDesugaring(AndroidApiLevel apiLevel) {
    return apiLevel.isLessThan(AndroidApiLevel.O);
  }

  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");
    }
  }
}
