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

import static com.android.tools.r8.KotlinCompilerTool.KotlinCompilerVersion.KOTLINC_1_9_21;
import static com.android.tools.r8.KotlinCompilerTool.KotlinCompilerVersion.MAX_SUPPORTED_VERSION;
import static com.android.tools.r8.ToolHelper.isWindows;
import static com.google.common.io.Files.getNameWithoutExtension;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import com.android.tools.r8.TestRuntime.CfRuntime;
import com.android.tools.r8.ToolHelper.CacheLookupKey;
import com.android.tools.r8.ToolHelper.CommandResultCache;
import com.android.tools.r8.ToolHelper.ProcessResult;
import com.android.tools.r8.errors.Unimplemented;
import com.android.tools.r8.utils.ArrayUtils;
import com.android.tools.r8.utils.FileUtils;
import com.android.tools.r8.utils.Pair;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.ThrowingConsumer;
import com.android.tools.r8.utils.structural.Ordered;
import com.google.common.hash.Hasher;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import org.junit.rules.TemporaryFolder;

public class KotlinCompilerTool {

  public enum KotlinTargetVersion {
    NONE(""),
    JAVA_6("JAVA_6"),
    JAVA_8("JAVA_8");

    private final String folderName;

    KotlinTargetVersion(String folderName) {
      this.folderName = folderName;
    }

    public String getFolderName() {
      return folderName;
    }

    public String getJvmTargetString() {
      switch (this) {
        case JAVA_6:
          return "1.6";
        case JAVA_8:
          return "1.8";
        default:
          throw new Unimplemented("JvmTarget not specified for " + this);
      }
    }
  }

  public enum KotlinCompilerVersion implements Ordered<KotlinCompilerVersion> {
    KOTLINC_1_3_72("kotlin-compiler-1.3.72", KotlinLambdaGeneration.CLASS),
    KOTLINC_1_4_20("kotlin-compiler-1.4.20", KotlinLambdaGeneration.CLASS),
    KOTLINC_1_5_0("kotlin-compiler-1.5.0", KotlinLambdaGeneration.CLASS),
    KOTLINC_1_6_0("kotlin-compiler-1.6.0", KotlinLambdaGeneration.CLASS),
    KOTLINC_1_7_0("kotlin-compiler-1.7.0", KotlinLambdaGeneration.CLASS),
    KOTLINC_1_8_0("kotlin-compiler-1.8.0", KotlinLambdaGeneration.CLASS),
    KOTLINC_1_9_21("kotlin-compiler-1.9.21", KotlinLambdaGeneration.CLASS),
    KOTLIN_DEV("kotlin-compiler-dev", KotlinLambdaGeneration.INVOKE_DYNAMIC);

    public static final KotlinCompilerVersion MIN_SUPPORTED_VERSION = KOTLINC_1_7_0;
    public static final KotlinCompilerVersion MAX_SUPPORTED_VERSION = KOTLINC_1_9_21;

    private final String folder;
    private final KotlinLambdaGeneration defaultLambdaGeneration;

    KotlinCompilerVersion(String folder, KotlinLambdaGeneration defaultLambdaGeneration) {
      this.folder = folder;
      this.defaultLambdaGeneration = defaultLambdaGeneration;
    }

    public static KotlinCompilerVersion latest() {
      return ArrayUtils.last(values());
    }

    public KotlinCompiler getCompiler() {
      return new KotlinCompiler(this);
    }

    public static List<KotlinCompilerVersion> getSupported() {
      return Arrays.stream(KotlinCompilerVersion.values())
          .filter(
              compiler ->
                  compiler.isGreaterThanOrEqualTo(MIN_SUPPORTED_VERSION)
                      && compiler.isLessThanOrEqualTo(MAX_SUPPORTED_VERSION))
          .collect(Collectors.toList());
    }
  }

  public enum KotlinLambdaGeneration {
    CLASS,
    INVOKE_DYNAMIC;

    public String getKotlincFlag() {
      if (this == CLASS) {
        return "-Xlambdas=class";
      } else {
        assert this == INVOKE_DYNAMIC;
        return "-Xlambdas=indy";
      }
    }

    public void apply(KotlinCompilerTool compiler) {
      if (this == CLASS) {
        compiler.generateLambdaClasses();
      } else {
        assert this == INVOKE_DYNAMIC;
        compiler.generateInvokeDynamic();
      }
    }

    public boolean isClass() {
      return this == CLASS;
    }

    public boolean isInvokeDynamic() {
      return this == INVOKE_DYNAMIC;
    }

    public boolean isDefaultForVersion(KotlinCompilerVersion version) {
      return this == version.defaultLambdaGeneration;
    }
  }

  public static final class KotlinCompiler {

    private final String name;
    private final Path lib;
    private final Path compiler;
    private final KotlinCompilerVersion compilerVersion;

    public KotlinCompiler(KotlinCompilerVersion compilerVersion) {
      this.lib =
          Paths.get(ToolHelper.THIRD_PARTY_DIR, "kotlin", compilerVersion.folder, "kotlinc", "lib");
      this.compiler = lib.resolve("kotlin-compiler.jar");
      this.compilerVersion = compilerVersion;
      this.name = compilerVersion.name();
    }

    public KotlinCompiler(String name, Path compiler, KotlinCompilerVersion compilerVersion) {
      this.compiler = compiler;
      this.lib = null;
      this.compilerVersion = compilerVersion;
      this.name = name;
    }

    public static KotlinCompiler latest() {
      return MAX_SUPPORTED_VERSION.getCompiler();
    }

    public Path getCompiler() {
      return compiler;
    }

    public Path getFolder() {
      return lib;
    }

    public boolean is(KotlinCompilerVersion version) {
      return compilerVersion == version;
    }

    public boolean isOneOf(KotlinCompilerVersion... versions) {
      return Arrays.stream(versions).anyMatch(this::is);
    }

    public boolean isNot(KotlinCompilerVersion version) {
      return !is(version);
    }

    public KotlinCompilerVersion getCompilerVersion() {
      return compilerVersion;
    }

    public Path getKotlinStdlibJar() {
      Path stdLib = getFolder().resolve("kotlin-stdlib.jar");
      assert Files.exists(stdLib) : "Expected kotlin stdlib jar";
      return stdLib;
    }

    public Path getKotlinReflectJar() {
      Path reflectJar = getFolder().resolve("kotlin-reflect.jar");
      assert Files.exists(reflectJar) : "Expected kotlin reflect jar";
      return reflectJar;
    }

    public Path getKotlinScriptRuntime() {
      Path reflectJar = getFolder().resolve("kotlin-script-runtime.jar");
      assert Files.exists(reflectJar) : "Expected kotlin script runtime jar";
      return reflectJar;
    }

    public Path getKotlinAnnotationJar() {
      Path annotationJar = getFolder().resolve("annotations-13.0.jar");
      assert Files.exists(annotationJar) : "Expected annotation jar";
      return annotationJar;
    }

    @Override
    public String toString() {
      return name;
    }
  }

  private final CfRuntime jdk;
  private final TestState state;
  private final KotlinCompiler compiler;
  private final KotlinTargetVersion targetVersion;
  private final KotlinLambdaGeneration lambdaGeneration;
  private final List<Path> sources = new ArrayList<>();
  private final List<Path> classpath = new ArrayList<>();
  private final List<String> additionalArguments = new ArrayList<>();
  private boolean useJvmAssertions;
  // TODO(b/211590675): We should enable assertions by default.
  private boolean enableAssertions = true;
  private Path output = null;

  private KotlinCompilerTool(
      CfRuntime jdk,
      TestState state,
      KotlinCompiler kotlinCompiler,
      KotlinTargetVersion kotlinTargetVersion,
      KotlinLambdaGeneration lambdaGeneration) {
    this.jdk = jdk;
    this.state = state;
    this.compiler = kotlinCompiler;
    this.targetVersion = kotlinTargetVersion;
    this.lambdaGeneration = lambdaGeneration;
  }

  public KotlinCompiler getCompiler() {
    return compiler;
  }

  public KotlinTargetVersion getTargetVersion() {
    return targetVersion;
  }

  public KotlinLambdaGeneration getLambdaGeneration() {
    return lambdaGeneration;
  }

  public static KotlinCompilerTool create(
      CfRuntime jdk,
      TemporaryFolder temp,
      KotlinCompiler kotlinCompiler,
      KotlinTargetVersion kotlinTargetVersion,
      KotlinLambdaGeneration lambdaGeneration) {
    return new KotlinCompilerTool(
        jdk, new TestState(temp), kotlinCompiler, kotlinTargetVersion, lambdaGeneration);
  }

  public KotlinCompilerTool addArguments(String... arguments) {
    Collections.addAll(additionalArguments, arguments);
    return this;
  }

  public KotlinCompilerTool enableExperimentalContextReceivers() {
    return addArguments("-Xcontext-receivers");
  }

  public KotlinCompilerTool addSourceFiles(Path... files) {
    return addSourceFiles(Arrays.asList(files));
  }

  public KotlinCompilerTool addSourceFiles(Collection<Path> files) {
    sources.addAll(files);
    return this;
  }

  public KotlinCompilerTool addSourceFilesWithNonKtExtension(TemporaryFolder temp, Path... files) {
    return addSourceFilesWithNonKtExtension(temp, Arrays.asList(files));
  }

  public KotlinCompilerTool includeRuntime() {
    assert !additionalArguments.contains("-include-runtime");
    addArguments("-include-runtime");
    return this;
  }

  public KotlinCompilerTool noReflect() {
    assert !additionalArguments.contains("-no-reflect");
    addArguments("-no-reflect");
    return this;
  }

  public KotlinCompilerTool noStdLib() {
    assert !additionalArguments.contains("-no-stdlib");
    addArguments("-no-stdlib");
    return this;
  }

  // This forces using invokedynamic for Kotlin lambdas.
  public KotlinCompilerTool generateLambdaClasses() {
    assert !additionalArguments.contains(KotlinLambdaGeneration.CLASS.getKotlincFlag())
        && !additionalArguments.contains(KotlinLambdaGeneration.INVOKE_DYNAMIC.getKotlincFlag());
    addArguments(KotlinLambdaGeneration.CLASS.getKotlincFlag());
    return this;
  }

  // This forces generation kotlinc of lambda classes for Kotlin lambdas
  public KotlinCompilerTool generateInvokeDynamic() {
    assert !additionalArguments.contains(KotlinLambdaGeneration.CLASS.getKotlincFlag())
        && !additionalArguments.contains(KotlinLambdaGeneration.INVOKE_DYNAMIC.getKotlincFlag());
    addArguments(KotlinLambdaGeneration.INVOKE_DYNAMIC.getKotlincFlag());
    return this;
  }

  public KotlinCompilerTool disableAssertions() {
    this.enableAssertions = false;
    return this;
  }

  public KotlinCompilerTool addSourceFilesWithNonKtExtension(
      TemporaryFolder temp, Collection<Path> files) {
    return addSourceFiles(
        files.stream()
            .map(
                fileNotNamedKt -> {
                  try {
                    // The Kotlin compiler does not require particular naming of files except for
                    // the extension, so just create a file called source.kt in a new directory.
                    String newFileName = getNameWithoutExtension(fileNotNamedKt.toString()) + ".kt";
                    Path fileNamedKt = temp.newFolder().toPath().resolve(newFileName);
                    Files.copy(fileNotNamedKt, fileNamedKt);
                    return fileNamedKt;
                  } catch (IOException e) {
                    throw new RuntimeException(e);
                  }
                })
            .collect(Collectors.toList()));
  }

  public KotlinCompilerTool addClasspathFiles(Path... files) {
    return addClasspathFiles(Arrays.asList(files));
  }

  public KotlinCompilerTool addClasspathFiles(Collection<Path> files) {
    classpath.addAll(files);
    return this;
  }

  public KotlinCompilerTool setOutputPath(Path file) {
    assertTrue("Output path must be an existing directory or a non-existing jar file",
        (!Files.exists(file) && FileUtils.isJarFile(file) && Files.exists(file.getParent()))
            || (Files.exists(file) && Files.isDirectory(file)));
    this.output = file;
    return this;
  }

  public KotlinCompilerTool setUseJvmAssertions(boolean useJvmAssertions) {
    this.useJvmAssertions = useJvmAssertions;
    return this;
  }

  public KotlinCompilerTool apply(Consumer<KotlinCompilerTool> consumer) {
    consumer.accept(this);
    return this;
  }

  private Path getOrCreateOutputPath() throws IOException {
    return output != null ? output : state.getNewTempFolder().resolve("out.jar");
  }

  /** Compile and return the compilations process result object. */
  public ProcessResult compileRaw() throws IOException {
    assertNotNull("An output path must be specified prior to compilation.", output);
    return compileInternal(output);
  }

  /** Compile asserting success and return the output path. */
  public Path compile() throws IOException {
    return compile(false);
  }

  public Path compile(boolean expectingFailure) throws IOException {
    Path output = getOrCreateOutputPath();
    ProcessResult result = compileInternal(output);
    if (expectingFailure) {
      assertNotEquals(result.toString(), result.exitCode, 0);
    } else {
      assertEquals(result.toString(), result.exitCode, 0);
    }
    return output;
  }

  private ProcessResult compileInternal(Path output) throws IOException {
    CommandLineAndHasherConsumers commandLineAndHasherConsumers =
        buildCommandLineAndHasherConsumers(output);
    CacheLookupKey cacheLookupKey = null;
    if (CommandResultCache.isEnabled()) {
      cacheLookupKey =
          new CacheLookupKey(
              hasher ->
                  commandLineAndHasherConsumers.hasherConsumers.forEach(
                      hasherConsumer -> hasherConsumer.acceptWithRuntimeException(hasher)));
      Pair<ProcessResult, Path> lookupResult =
          CommandResultCache.getInstance().lookup(cacheLookupKey);
      if (lookupResult != null
          && lookupResult.getFirst().exitCode == 0
          && lookupResult.getSecond() != null) {
        Files.copy(lookupResult.getSecond(), output);
        return lookupResult.getFirst();
      }
    }
    ProcessBuilder builder = new ProcessBuilder(commandLineAndHasherConsumers.cmdline);
    builder.directory(new File(ToolHelper.getProjectRoot()));
    ProcessResult processResult = ToolHelper.runProcess(builder);
    if (CommandResultCache.isEnabled() && output.toFile().isFile()) {
      CommandResultCache.getInstance().putResult(processResult, cacheLookupKey, output);
    }
    return processResult;
  }

  public static class CommandLineAndHasherConsumers {
    final List<String> cmdline = new ArrayList<>();
    final List<ThrowingConsumer<Hasher, IOException>> hasherConsumers = new ArrayList<>();
  }

  private CommandLineAndHasherConsumers buildCommandLineAndHasherConsumers(Path output)
      throws IOException {
    CommandLineAndHasherConsumers commandLineAndHasherConsumers =
        new CommandLineAndHasherConsumers();
    List<String> cmdline = commandLineAndHasherConsumers.cmdline;
    cmdline.add(jdk.getJavaExecutable().toString());
    if (enableAssertions) {
      cmdline.add("-ea");
    }
    cmdline.add("-cp");
    cmdline.add(compiler.getCompiler().toString());
    cmdline.add(ToolHelper.K2JVMCompiler);
    if (useJvmAssertions) {
      cmdline.add("-Xassertions=jvm");
    }
    cmdline.add("-jdk-home");
    cmdline.add(jdk.getJavaHome().toString());
    cmdline.add("-jvm-target");
    cmdline.add(targetVersion.getJvmTargetString());
    cmdline.add(lambdaGeneration.getKotlincFlag());
    // Until now this is just command line files, no inputs, hash existing command
    String noneFileCommandLineArguments = StringUtils.join("", cmdline);
    commandLineAndHasherConsumers.hasherConsumers.add(
        hasher -> hasher.putString(noneFileCommandLineArguments, StandardCharsets.UTF_8));

    for (Path source : sources) {
      cmdline.add(source.toString());
      commandLineAndHasherConsumers.hasherConsumers.add(
          hasher -> hasher.putBytes(Files.readAllBytes(source)));
    }
    cmdline.add("-d");
    cmdline.add(output.toString());
    if (!classpath.isEmpty()) {
      cmdline.add("-cp");
      cmdline.add(classpath
          .stream()
          .map(Path::toString)
          .collect(Collectors.joining(isWindows() ? ";" : ":")));
      for (Path path : classpath) {
        commandLineAndHasherConsumers.hasherConsumers.add(
            hasher -> {
              hasher.putString("--cp", StandardCharsets.UTF_8);
              hasher.putBytes(Files.readAllBytes(path));
            });
      }
    }
    cmdline.addAll(additionalArguments);
    commandLineAndHasherConsumers.hasherConsumers.add(
        hasher -> additionalArguments.forEach(s -> hasher.putString(s, StandardCharsets.UTF_8)));
    return commandLineAndHasherConsumers;
  }
}
