// Copyright (c) 2023, 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.

import java.io.File
import java.net.URI
import java.nio.file.Paths
import org.gradle.api.JavaVersion
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.plugins.JavaPluginExtension
import org.gradle.api.tasks.JavaExec
import org.gradle.api.tasks.SourceSet
import org.gradle.jvm.tasks.Jar
import org.gradle.kotlin.dsl.register
import org.gradle.nativeplatform.platform.OperatingSystem
import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform

class DependenciesPlugin: Plugin<Project> {

  override fun apply(target: Project) {
    val dependenciesPath = "file:" +
      target.getRoot().resolve("third_party").resolve("dependencies").getAbsolutePath()
    val dependenciesNewPath = "file:" +
      target.getRoot().resolve("third_party").resolve("dependencies_new").getAbsolutePath()
    val repositories = target.getRepositories()
    repositories.maven { name = "LOCAL_MAVEN_REPO";  url = URI(dependenciesPath) }
    repositories.maven { name = "LOCAL_MAVEN_REPO_NEW";  url = URI(dependenciesNewPath) }
  }
}

enum class Jdk(val folder : String) {
  JDK_8("jdk8"),
  JDK_9("openjdk-9.0.4"),
  JDK_11("jdk-11"),
  JDK_17("jdk-17"),
  JDK_20("jdk-20");

  fun isJdk8() : Boolean {
    return this == JDK_8
  }

  fun getThirdPartyDependency() : ThirdPartyDependency {
    val os: OperatingSystem = DefaultNativePlatform.getCurrentOperatingSystem()
    val subFolder : String
    val fileName : String
    if (os.isLinux) {
      subFolder = if(isJdk8()) "linux-x86" else "linux"
      fileName = "java"
    } else if (os.isMacOsX) {
      subFolder = if(isJdk8()) "darwin-x86" else "osx"
      fileName = "java"
    } else {
      assert(os.isWindows())
      if (isJdk8()) {
        throw RuntimeException("No Jdk8 on Windows")
      }
      subFolder = "windows"
      fileName = "java.bat"
    }
    return ThirdPartyDependency(
      name,
      Paths.get("third_party", "openjdk", folder, subFolder, "bin", fileName).toFile(),
      Paths.get("third_party", "openjdk", folder, "$subFolder.tar.gz.sha1").toFile())
  }
}

fun Project.getRoot() : File {
  var parent = this.projectDir
  while (!parent.getName().equals("d8_r8")) {
    parent = parent.getParentFile()
  }
  return parent.getParentFile()
}

fun Project.header(title : String) : String {
  return "****** ${title} ******"
}

fun Project.ensureThirdPartyDependencies(name : String, deps : List<ThirdPartyDependency>) : Task {
  val outputFiles : MutableList<File> = mutableListOf()
  val depsTasks = deps.map({
      tasks.register<DownloadDependencyTask>("download-third-party-${it.packageName}") {
        setDependency(
          it.packageName,
          getRoot().resolve(it.sha1File),
          getRoot().resolve(it.path).parentFile,
          it.type)
        outputFiles.add(it.path)
      }})
  return tasks.register("ensure-third-party-$name") {
    dependsOn(depsTasks)
    outputs.files(outputFiles)
  }.get()
}

/**
 * Builds a jar for each subfolder in an test source set.
 *
 * <p> As an example, src/test/examplesJava9 contains subfolders: backport, collectionof, ..., .
 * These are compiled to individual jars and placed in <repo-root>/build/test/examplesJava9/ as:
 * backport.jar, collectionof.jar, ..., .
 *
 * Calling this from a project will amend the task graph with the task named
 * getExamplesJarsTaskName(examplesName) such that it can be referenced from the test runners.
 */
fun Project.buildExampleJars(name : String) : Task {
  val outputFiles : MutableList<File> = mutableListOf()
  val jarTasks : MutableList<Task> = mutableListOf()
  val testSourceSet = extensions
    .getByType(JavaPluginExtension::class.java)
    .sourceSets
    // The TEST_SOURCE_SET_NAME is the source set defined by writing java { sourcesets.test { ... }}
    .getByName(SourceSet.TEST_SOURCE_SET_NAME)
  val destinationDir = getRoot().resolveAll("build", "test", name)
  val classesOutput = destinationDir.resolve("classes")
  testSourceSet.java.destinationDirectory.set(classesOutput)
  testSourceSet.resources.destinationDirectory.set(destinationDir)
  testSourceSet
    .java
    .sourceDirectories
    .files
    .forEach { srcDir ->
      srcDir.listFiles(File::isDirectory)?.forEach { exampleDir ->
        var generationTask : Task? = null
        if (exampleDir.resolve("TestGenerator.java").isFile) {
          generationTask = tasks.register<JavaExec>(
            "generate-$name-${exampleDir.name}") {
            dependsOn("compileTestJava")
            mainClass.set("${exampleDir.name}.TestGenerator")
            classpath = files(
              classesOutput,
              testSourceSet.compileClasspath)
            args(classesOutput.toString())
          }.get()
        }
        jarTasks.add(tasks.register<Jar>(
          "jar-$name-${exampleDir.name}") {
          dependsOn("compileTestJava")
          if (generationTask != null) {
            dependsOn(generationTask)
          }
          archiveFileName.set("${exampleDir.name}.jar")
          destinationDirectory.set(destinationDir)
          from(classesOutput) {
            include("${exampleDir.name}/**/*.class")
            exclude("**/TestGenerator*")
          }
        }.get())
      }
    }
  return tasks.register(getExampleJarsTaskName(name)) {
    dependsOn(jarTasks.toTypedArray())
    outputs.files(outputFiles)
  }.get()
}

fun Project.getExampleJarsTaskName(name: String) : String {
  return "build-example-jars-$name"
}

fun Project.resolve(thirdPartyDependency: ThirdPartyDependency) : ConfigurableFileCollection {
  return files(project.getRoot().resolve(thirdPartyDependency.path))
}

/**
 * When using composite builds, referecing tasks in other projects do not give a Task but a
 * TaskReference. To get outputs from other tasks we need to have a proper task and gradle do not
 * provide a way of getting a Task from a TaskReference. We use a trick where create a synthetic
 * task that depends on the task of interest, allowing us to look at the graph and obtain the
 * actual reference. Remove this code if gradle starts supporting this natively.
 */
fun Project.projectTask(project : String, taskName : String) : Task {
  val name = "$project-reference-$taskName";
  val task = tasks.register(name) {
    dependsOn(gradle.includedBuild(project).task(":$taskName"))
  }.get();
  return task.taskDependencies
    .getDependencies(tasks.getByName(name)).iterator().next();
}

fun File.resolveAll(vararg xs: String) : File {
  var that = this;
  for (x in xs) {
    that = that.resolve(x)
  }
  return that
}

fun Project.getJavaHome(jdk : Jdk) : File {
  // TODO(b/270105162): Make sure this works on other platforms.
  return getRoot().resolveAll("third_party", "openjdk", jdk.folder, "linux")
}

fun Project.getCompilerPath(jdk : Jdk) : String {
  // TODO(b/270105162): Make sure this works on other platforms.
  return getJavaHome(jdk).resolveAll("bin", "javac").toString()
}

fun Project.getJavaPath(jdk : Jdk) : String {
  // TODO(b/270105162): Make sure this works on other platforms.
  return getJavaHome(jdk).resolveAll("bin", "java").toString()
}

fun Project.baseCompilerCommandLine(
  jar: File, deps: File, compiler: String, args: List<String> = listOf(),
) : List<String> {
  // Execute r8 commands against a stable r8 with dependencies.
  // TODO(b/139725780): See if we can remove or lower the heap size (-Xmx8g).
  return listOf(
    getJavaPath(Jdk.JDK_17),
    "-Xmx8g",
    "-ea",
    "-cp",
    "$jar:$deps",
    "com.android.tools.r8.SwissArmyKnife",
    compiler) + args
}

fun Project.baseCompilerCommandLine(
  jar: File, compiler: String, args: List<String> = listOf(),
) : List<String> {
  // Execute r8 commands against a stable r8 with dependencies.
  // TODO(b/139725780): See if we can remove or lower the heap size (-Xmx8g).
  return listOf(
    getJavaPath(Jdk.JDK_17),
    "-Xmx8g",
    "-ea",
    "-cp",
    "$jar",
    "com.android.tools.r8.SwissArmyKnife",
    compiler) + args
}

fun Project.createR8LibCommandLine(
  r8Compiler: File,
  input: File,
  output: File,
  pgConf: List<File>,
  excludingDepsVariant: Boolean,
  lib: List<File> = listOf(),
  classpath: List<File> = listOf()
) : List<String> {
  val pgList = pgConf.flatMap({ listOf("--pg-conf", "$it") })
  val libList = lib.flatMap({ listOf("--lib", "$it") })
  val cpList = classpath.flatMap({ listOf("--classpath", "$it") })
  val exclList = if (excludingDepsVariant) listOf("--excldeps-variant") else listOf()
  return listOf(
    "python3",
    "${getRoot().resolve("tools").resolve("create_r8lib.py")}",
    "--r8compiler",
    "${r8Compiler}",
    "--r8jar",
    "${input}",
    "--output",
    "${output}",
  ) + exclList + pgList + libList + cpList
}

object JvmCompatibility {
  val sourceCompatibility = JavaVersion.VERSION_11
  val targetCompatibility = JavaVersion.VERSION_11
}

object Versions {
  const val asmVersion = "9.5"
  const val errorproneVersion = "2.18.0"
  const val fastUtilVersion = "7.2.1"
  const val gsonVersion = "2.7"
  const val guavaVersion = "31.1-jre"
  const val javassist = "3.29.2-GA"
  const val junitVersion = "4.13-beta-2"
  const val kotlinVersion = "1.8.10"
  const val kotlinMetadataVersion = "0.6.2"
  const val mockito = "2.10.0"
  const val smaliVersion = "3.0.3"
}

object Deps {
  val asm by lazy { "org.ow2.asm:asm:${Versions.asmVersion}" }
  val asmUtil by lazy { "org.ow2.asm:asm-util:${Versions.asmVersion}" }
  val asmCommons by lazy { "org.ow2.asm:asm-commons:${Versions.asmVersion}" }
  val fastUtil by lazy { "it.unimi.dsi:fastutil:${Versions.fastUtilVersion}"}
  val gson by lazy { "com.google.code.gson:gson:${Versions.gsonVersion}"}
  val guava by lazy { "com.google.guava:guava:${Versions.guavaVersion}" }
  val javassist by lazy { "org.javassist:javassist:${Versions.javassist}"}
  val junit by lazy { "junit:junit:${Versions.junitVersion}"}
  val kotlinMetadata by lazy {
    "org.jetbrains.kotlinx:kotlinx-metadata-jvm:${Versions.kotlinMetadataVersion}" }
  val kotlinStdLib by lazy { "org.jetbrains.kotlin:kotlin-stdlib:${Versions.kotlinVersion}" }
  val kotlinReflect by lazy { "org.jetbrains.kotlin:kotlin-reflect:${Versions.kotlinVersion}" }
  val mockito by lazy { "org.mockito:mockito-core:${Versions.mockito}" }
  val smali by lazy { "com.android.tools.smali:smali:${Versions.smaliVersion}" }
  val errorprone by lazy { "com.google.errorprone:error_prone_core:${Versions.errorproneVersion}" }
}

object ThirdPartyDeps {
  val androidJars = getThirdPartyAndroidJars()
  val androidVMs = getThirdPartyAndroidVms()
  val apiDatabase = ThirdPartyDependency(
    "apiDatabase",
    Paths.get(
      "third_party",
      "api_database",
      "api_database",
      "resources",
      "new_api_database.ser").toFile(),
    Paths.get("third_party", "api_database", "api_database.tar.gz.sha1").toFile())
  val compilerApi = ThirdPartyDependency(
    "compiler-api",
    Paths.get(
      "third_party",
      "binary_compatibility_tests",
      "compiler_api_tests",
      "tests.jar").toFile(),
    Paths.get(
      "third_party",
      "binary_compatibility_tests",
      "compiler_api_tests.tar.gz.sha1").toFile())
  val dagger = ThirdPartyDependency(
    "dagger",
    Paths.get("third_party", "dagger", "2.41", "dagger-2.41.jar").toFile(),
    Paths.get("third_party", "dagger", "2.41.tar.gz.sha1").toFile())
  val ddmLib = ThirdPartyDependency(
    "ddmlib",
    Paths.get("third_party", "ddmlib", "ddmlib.jar").toFile(),
    Paths.get("third_party", "ddmlib.tar.gz.sha1").toFile())
  val jacoco = ThirdPartyDependency(
    "jacoco",
    Paths.get("third_party", "jacoco", "0.8.6", "lib", "jacocoagent.jar").toFile(),
    Paths.get("third_party", "jacoco", "0.8.6.tar.gz.sha1").toFile()
  )
  val jasmin = ThirdPartyDependency(
    "jasmin",
    Paths.get("third_party", "jasmin", "jasmin-2.4.jar").toFile(),
    Paths.get("third_party", "jasmin.tar.gz.sha1").toFile())
  val java8Runtime = ThirdPartyDependency(
    "openjdk-rt-1.8",
    Paths.get("third_party", "openjdk", "openjdk-rt-1.8", "rt.jar").toFile(),
    Paths.get("third_party", "openjdk", "openjdk-rt-1.8.tar.gz.sha1").toFile()
  )
  val jdks = getJdks()
  val jdk11Test = ThirdPartyDependency(
    "jdk-11-test",
    Paths.get("third_party", "openjdk", "jdk-11-test", "Makefile").toFile(),
    Paths.get("third_party", "openjdk", "jdk-11-test.tar.gz.sha1").toFile()
  )
  val jdwpTests = ThirdPartyDependency(
    "jdwp-tests",
    Paths.get("third_party", "jdwp-tests", "apache-harmony-jdwp-tests-host.jar").toFile(),
    Paths.get("third_party", "jdwp-tests.tar.gz.sha1").toFile())
  val kotlinCompilers = getThirdPartyKotlinCompilers()
  val proguards = getThirdPartyProguards()
}

fun getThirdPartyAndroidJars() : List<ThirdPartyDependency> {
  return listOf(
    "libcore_latest",
    "lib-master",
    "lib-v14",
    "lib-v15",
    "lib-v19",
    "lib-v21",
    "lib-v22",
    "lib-v23",
    "lib-v24",
    "lib-v25",
    "lib-v26",
    "lib-v27",
    "lib-v28",
    "lib-v29",
    "lib-v30",
    "lib-v31",
    "lib-v32",
    "lib-v33",
    "lib-v34"
  ).map(::getThirdPartyAndroidJar)
}

fun getThirdPartyAndroidJar(version : String) : ThirdPartyDependency {
  return ThirdPartyDependency(
    version,
    Paths.get("third_party", "android_jar", version, "android.jar").toFile(),
    Paths.get("third_party", "android_jar", "$version.tar.gz.sha1").toFile())
}

fun getThirdPartyAndroidVms() : List<ThirdPartyDependency> {
  return listOf(
    listOf("host", "art-master"),
    listOf("host", "art-14.0.0-dp1"),
    listOf("host", "art-13.0.0"),
    listOf("host", "art-12.0.0-beta4"),
    listOf("art-10.0.0"),
    listOf("art-5.1.1"),
    listOf("art-6.0.1"),
    listOf("art-7.0.0"),
    listOf("art-8.1.0"),
    listOf("art-9.0.0"),
    listOf("art"),
    listOf("dalvik-4.0.4"),
    listOf("dalvik")).map(::getThirdPartyAndroidVm)
}

fun getThirdPartyAndroidVm(version : List<String>) : ThirdPartyDependency {
  val output = Paths.get("tools", "linux", *version.toTypedArray(), "bin", "art").toFile()
  return ThirdPartyDependency(
    version.last(),
    output,
    Paths.get(
      "tools",
      "linux",
      *version.slice(0..version.size - 2).toTypedArray(),
      "${version.last()}.tar.gz.sha1").toFile())
}

fun getJdks() : List<ThirdPartyDependency> {
  val os: OperatingSystem = DefaultNativePlatform.getCurrentOperatingSystem()
  if (os.isLinux || os.isMacOsX) {
    return Jdk.values().map{ it.getThirdPartyDependency()}
  } else {
    return Jdk.values().filter{ !it.isJdk8() }.map{ it.getThirdPartyDependency()}
  }
}

fun getThirdPartyProguards() : List<ThirdPartyDependency> {
  val os: OperatingSystem = DefaultNativePlatform.getCurrentOperatingSystem()
  return listOf("proguard5.2.1", "proguard6.0.1", "proguard-7.0.0")
    .map { ThirdPartyDependency(
        it,
        Paths.get(
          "third_party",
          "proguard",
          it,
          "bin",
          if (os.isWindows) "proguard.bat" else "proguard.sh").toFile(),
        Paths.get("third_party", "proguard", "${it}.tar.gz.sha1").toFile())}
}

fun getThirdPartyKotlinCompilers() : List<ThirdPartyDependency> {
  return listOf(
    "kotlin-compiler-1.3.72",
    "kotlin-compiler-1.4.20",
    "kotlin-compiler-1.5.0",
    "kotlin-compiler-1.6.0",
    "kotlin-compiler-1.7.0",
    "kotlin-compiler-1.8.0",
    "kotlin-compiler-dev")
    .map { ThirdPartyDependency(
      it,
      Paths.get(
        "third_party",
        "kotlin",
        it,
        "kotlinc",
        "lib",
        "kotlin-stdlib.jar").toFile(),
      Paths.get("third_party", "kotlin", "${it}.tar.gz.sha1").toFile())}
}