// 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 DependenciesPlugin.Companion.computeRoot
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.api.tasks.testing.Test
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) }

    // Setup all test tasks to listen after system properties passed in by test.py.
    val testTask = target.tasks.findByName("test")
    if (testTask != null) {
      TestConfigurationHelper.setupTestTask(testTask as Test)
    }
  }

  companion object {
    fun computeRoot(file: File) : File {
      var parent = file
      while (!parent.getName().equals("d8_r8")) {
        parent = parent.getParentFile()
      }
      return parent.getParentFile()
    }
  }
}

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
    if (os.isLinux) {
      subFolder = if(isJdk8()) "linux-x86" else "linux"
    } else if (os.isMacOsX) {
      subFolder = if(isJdk8()) "darwin-x86" else "osx"
    } else {
      assert(os.isWindows())
      if (isJdk8()) {
        throw RuntimeException("No Jdk8 on Windows")
      }
      subFolder = "windows"
    }
    return ThirdPartyDependency(
      name,
      Paths.get("third_party", "openjdk", folder, subFolder).toFile(),
      Paths.get("third_party", "openjdk", folder, "$subFolder.tar.gz.sha1").toFile())
  }
}

fun Project.getRoot() : File {
  return computeRoot(this.projectDir)
}

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 { tpd ->
    val projectAndTaskName = "${project.name}-$name"
    val downloadTaskName = "download-third-party-$projectAndTaskName-${tpd.packageName}"
    val downloadTask = tasks.register<DownloadDependencyTask>(downloadTaskName) {
      setDependency(getRoot().resolve(tpd.sha1File), getRoot().resolve(tpd.path), tpd.type)
    }.get()
    outputFiles.add(tpd.path)
    downloadTask
  }
  return tasks.register("ensure-third-party-$name") {
    dependsOn(*depsTasks.toTypedArray())
    outputs.files(outputFiles)
  }.get()
}

/**
 * Builds a jar for each sub folder in a 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 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 ->
        arrayOf("compileTestJava", "debuginfo-all", "debuginfo-none").forEach { taskName ->
          if (!project.getTasksByName(taskName, false).isEmpty()) {
            var generationTask : Task? = null
            val taskSpecificClassesOutput = getOutputName(classesOutput.toString(), taskName)
            if (exampleDir.resolve("TestGenerator.java").isFile) {
              generationTask = tasks.register<JavaExec>(
                "generate-$name-${exampleDir.name}-$taskName") {
                dependsOn(taskName)
                mainClass.set("${exampleDir.name}.TestGenerator")
                classpath = files(taskSpecificClassesOutput, testSourceSet.compileClasspath)
                args(taskSpecificClassesOutput)
              }.get()
            }
            jarTasks.add(tasks.register<Jar>("jar-$name-${exampleDir.name}-$taskName") {
              dependsOn(taskName)
              if (generationTask != null) {
                dependsOn(generationTask)
              }
              archiveFileName.set("${getOutputName(exampleDir.name, taskName)}.jar")
              destinationDirectory.set(destinationDir)
              from(taskSpecificClassesOutput) {
                include("${exampleDir.name}/**/*.class")
                exclude("**/TestGenerator*")
              }
              // Copy additional resources into the jar.
              from(exampleDir) {
                exclude("**/*.java")
                exclude("**/keep-rules*.txt")
                into(exampleDir.name)
              }
            }.get())
          }
        }
      }
    }
  return tasks.register(getExampleJarsTaskName(name)) {
    dependsOn(jarTasks.toTypedArray())
  }.get()
}

fun getOutputName(dest: String, taskName: String) : String {
  if (taskName.equals("compileTestJava")) {
    return dest
  }
  return "${dest}_${taskName.replace('-', '_')}"
}

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

fun Project.resolve(
    thirdPartyDependency: ThirdPartyDependency, vararg paths: String) : ConfigurableFileCollection {
  return files(project.getRoot().resolve(thirdPartyDependency.path).resolveAll(*paths))
}

/**
 * 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.10.1"
  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 errorprone by lazy { "com.google.errorprone:error_prone_core:${Versions.errorproneVersion}" }
  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}" }
}

object ThirdPartyDeps {
  val aapt2 = ThirdPartyDependency(
    "aapt2",
    Paths.get("third_party", "aapt2").toFile(),
    Paths.get("third_party", "aapt2.tar.gz.sha1").toFile())
  val androidJars = getThirdPartyAndroidJars()
  val androidVMs = getThirdPartyAndroidVms()
  val apiDatabase = ThirdPartyDependency(
    "apiDatabase",
    Paths.get("third_party", "api_database", "api_database").toFile(),
    Paths.get("third_party", "api_database", "api_database.tar.gz.sha1").toFile())
  val artTests = ThirdPartyDependency(
    "art-tests",
    Paths.get("tests", "2017-10-04", "art").toFile(),
    Paths.get("tests", "2017-10-04", "art.tar.gz.sha1").toFile())
  val artTestsLegacy = ThirdPartyDependency(
    "art-tests-legacy",
    Paths.get("tests", "2016-12-19", "art").toFile(),
    Paths.get("tests", "2016-12-19", "art.tar.gz.sha1").toFile())
  val clank = ThirdPartyDependency(
    "clank",
    Paths.get("third_party", "chrome", "clank_google3_prebuilt").toFile(),
    Paths.get("third_party", "chrome", "clank_google3_prebuilt.tar.gz.sha1").toFile(),
    DependencyType.X20)
  val compilerApi = ThirdPartyDependency(
    "compiler-api",
    Paths.get(
      "third_party", "binary_compatibility_tests", "compiler_api_tests").toFile(),
    Paths.get(
      "third_party",
      "binary_compatibility_tests",
      "compiler_api_tests.tar.gz.sha1").toFile())
  val coreLambdaStubs = ThirdPartyDependency(
    "coreLambdaStubs",
    Paths.get("third_party", "core-lambda-stubs").toFile(),
    Paths.get("third_party", "core-lambda-stubs.tar.gz.sha1").toFile())
  val dagger = ThirdPartyDependency(
    "dagger",
    Paths.get("third_party", "dagger", "2.41").toFile(),
    Paths.get("third_party", "dagger", "2.41.tar.gz.sha1").toFile())
  val ddmLib = ThirdPartyDependency(
    "ddmlib",
    Paths.get("third_party", "ddmlib").toFile(),
    Paths.get("third_party", "ddmlib.tar.gz.sha1").toFile())
  val desugarJdkLibs = ThirdPartyDependency(
    "desugar-jdk-libs",
    Paths.get("third_party", "openjdk", "desugar_jdk_libs").toFile(),
    Paths.get("third_party", "openjdk", "desugar_jdk_libs.tar.gz.sha1").toFile())
  val desugarJdkLibsLegacy = ThirdPartyDependency(
    "desugar-jdk-libs-legacy",
    Paths.get("third_party", "openjdk", "desugar_jdk_libs_legacy").toFile(),
    Paths.get("third_party", "openjdk", "desugar_jdk_libs_legacy.tar.gz.sha1").toFile())
  val desugarLibraryReleases = getThirdPartyDesugarLibraryReleases()
  // TODO(b/289363570): This could probably be removed.
  val framework = ThirdPartyDependency(
    "framework",
    Paths.get("third_party", "framework").toFile(),
    Paths.get("third_party", "framework.tar.gz.sha1").toFile(),
    DependencyType.X20)
  val iosched2019 = ThirdPartyDependency(
    "iosched-2019",
    Paths.get("third_party", "iosched_2019").toFile(),
    Paths.get("third_party", "iosched_2019.tar.gz.sha1").toFile())
  val desugarJdkLibs11 = ThirdPartyDependency(
    "desugar-jdk-libs-11",
    Paths.get("third_party", "openjdk", "desugar_jdk_libs_11").toFile(),
    Paths.get("third_party", "openjdk", "desugar_jdk_libs_11.tar.gz.sha1").toFile())
  val gmscoreVersions = getGmsCoreVersions()
  val internalIssues = getInternalIssues()
  val jacoco = ThirdPartyDependency(
    "jacoco",
    Paths.get("third_party", "jacoco", "0.8.6").toFile(),
    Paths.get("third_party", "jacoco", "0.8.6.tar.gz.sha1").toFile())
  val jasmin = ThirdPartyDependency(
    "jasmin",
    Paths.get("third_party", "jasmin").toFile(),
    Paths.get("third_party", "jasmin.tar.gz.sha1").toFile())
  val jsr223 = ThirdPartyDependency(
    "jsr223",
    Paths.get("third_party", "jsr223-api-1.0").toFile(),
    Paths.get("third_party", "jsr223-api-1.0.tar.gz.sha1").toFile())
  val java8Runtime = ThirdPartyDependency(
    "openjdk-rt-1.8",
    Paths.get("third_party", "openjdk", "openjdk-rt-1.8").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").toFile(),
    Paths.get("third_party", "openjdk", "jdk-11-test.tar.gz.sha1").toFile())
  val jdwpTests = ThirdPartyDependency(
    "jdwp-tests",
    Paths.get("third_party", "jdwp-tests").toFile(),
    Paths.get("third_party", "jdwp-tests.tar.gz.sha1").toFile())
  val kotlinCompilers = getThirdPartyKotlinCompilers()
  val multidex = ThirdPartyDependency(
    "multidex",
    Paths.get("third_party", "multidex").toFile(),
    Paths.get("third_party", "multidex.tar.gz.sha1").toFile())
  val nest = ThirdPartyDependency(
    "nest",
    Paths.get("third_party", "nest", "nest_20180926_7c6cfb").toFile(),
    Paths.get("third_party", "nest", "nest_20180926_7c6cfb.tar.gz.sha1").toFile(),
    DependencyType.X20)
  val proguards = getThirdPartyProguards()
  val protobufLite = ThirdPartyDependency(
    "protobuf-lite",
    Paths.get("third_party", "protobuf-lite").toFile(),
    Paths.get("third_party", "protobuf-lite.tar.gz.sha1").toFile(),
    DependencyType.X20)
  val r8 = ThirdPartyDependency(
    "r8",
    Paths.get("third_party", "r8").toFile(),
    Paths.get("third_party", "r8.tar.gz.sha1").toFile())
  val r8Mappings = ThirdPartyDependency(
    "r8-mappings",
    Paths.get("third_party", "r8mappings").toFile(),
    Paths.get("third_party", "r8mappings.tar.gz.sha1").toFile())
  val r8v2_0_74 = ThirdPartyDependency(
    "r8-v2-0-74",
    Paths.get("third_party", "r8-releases","2.0.74").toFile(),
    Paths.get("third_party", "r8-releases", "2.0.74.tar.gz.sha1").toFile())
  val r8v3_2_54 = ThirdPartyDependency(
    "r8-v3-2-54",
    Paths.get("third_party", "r8-releases","3.2.54").toFile(),
    Paths.get("third_party", "r8-releases", "3.2.54.tar.gz.sha1").toFile())
  val retraceBenchmark = ThirdPartyDependency(
    "retrace-benchmark",
    Paths.get("third_party", "retrace_benchmark").toFile(),
    Paths.get("third_party", "retrace_benchmark.tar.gz.sha1").toFile())
  val retraceBinaryCompatibility = ThirdPartyDependency(
    "retrace-binary-compatibility",
    Paths.get("third_party", "retrace", "binary_compatibility").toFile(),
    Paths.get("third_party", "retrace", "binary_compatibility.tar.gz.sha1").toFile())
  val retraceInternal = ThirdPartyDependency(
    "retrace-internal",
    Paths.get("third_party", "retrace_internal").toFile(),
    Paths.get("third_party", "retrace_internal.tar.gz.sha1").toFile(),
    DependencyType.X20)
  val rhino = ThirdPartyDependency(
    "rhino",
    Paths.get("third_party", "rhino-1.7.10").toFile(),
    Paths.get("third_party", "rhino-1.7.10.tar.gz.sha1").toFile())
  val rhinoAndroid = ThirdPartyDependency(
    "rhino-android",
    Paths.get("third_party", "rhino-android-1.1.1").toFile(),
    Paths.get("third_party", "rhino-android-1.1.1.tar.gz.sha1").toFile())
  val smali = ThirdPartyDependency(
    "smali",
    Paths.get("third_party", "smali").toFile(),
    Paths.get("third_party", "smali.tar.gz.sha1").toFile())
  val tivi = ThirdPartyDependency(
    "tivi",
    Paths.get("third_party", "opensource-apps", "tivi").toFile(),
    Paths.get("third_party", "opensource-apps", "tivi.tar.gz.sha1").toFile())
}

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).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-beta3"),
    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 {
  return ThirdPartyDependency(
    version.last(),
    Paths.get(
      "tools",
      "linux",
      *version.slice(0..version.size - 2).toTypedArray(),
      version.last()).toFile(),
    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> {
  return listOf("proguard5.2.1", "proguard6.0.1", "proguard-7.0.0", "proguard-7.3.2")
    .map { ThirdPartyDependency(
      it,
      Paths.get("third_party", "proguard", it).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).toFile(),
      Paths.get("third_party", "kotlin", "${it}.tar.gz.sha1").toFile())}
}

fun getThirdPartyDesugarLibraryReleases() : List<ThirdPartyDependency> {
  return listOf(
    "1.0.9",
    "1.0.10",
    "1.1.0",
    "1.1.1",
    "1.1.5")
    .map { ThirdPartyDependency(
      "desugar-library-release-$it",
      Paths.get("third_party", "openjdk", "desugar_jdk_libs_releases", it).toFile(),
      Paths.get("third_party", "openjdk", "desugar_jdk_libs_releases", "${it}.tar.gz.sha1").toFile())}
}

fun getInternalIssues() : List<ThirdPartyDependency> {
  return listOf("issue-127524985")
    .map { ThirdPartyDependency(
      "internal-$it",
      Paths.get("third_party", "internal", it).toFile(),
      Paths.get("third_party", "internal", "${it}.tar.gz.sha1").toFile(),
      DependencyType.X20)}
}

fun getGmsCoreVersions() : List<ThirdPartyDependency> {
  return listOf(
    "gmscore_v10",
    "latest")
    .map { ThirdPartyDependency(
      "gmscore-version-$it",
      Paths.get("third_party", "gmscore", it).toFile(),
      Paths.get("third_party", "gmscore", "${it}.tar.gz.sha1").toFile(),
      DependencyType.X20)}
}
