// 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.nio.file.Paths
import java.security.MessageDigest
import java.util.UUID
import kotlin.reflect.full.declaredMemberProperties
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.artifacts.Dependency
import org.gradle.api.artifacts.dsl.DependencyHandler
import org.gradle.api.attributes.Attribute
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.Directory
import org.gradle.api.file.FileCollection
import org.gradle.api.file.RegularFile
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.testing.Test
import org.gradle.jvm.toolchain.JavaInstallationMetadata
import org.gradle.jvm.toolchain.JavaLanguageVersion
import org.gradle.jvm.toolchain.JavaLauncher
import org.gradle.jvm.toolchain.internal.DefaultJavaLanguageVersion
import org.gradle.nativeplatform.platform.OperatingSystem
import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform
import org.gradle.process.CommandLineArgumentProvider

public val TEST_DEP_PROP: Attribute<String> =
  Attribute.of("com.android.tools.r8.testdep.prop", String::class.java)

public fun DependencyHandler.runtimeOnlyData(dependencyNotation: Any): Dependency? {
  return add("runtimeOnlyDataScope", dependencyNotation)
}

public fun DependencyHandler.runtimeOnlyDataScope(dependencyNotation: Any): Dependency? {
  return add("runtimeOnlyDataScope", dependencyNotation)
}

public class TestDepsCommandLineArgumentProvider(
  @get:InputFiles @get:PathSensitive(PathSensitivity.NONE) public val files: FileCollection,
  @get:Input public val arguments: Provider<List<String>>,
) : CommandLineArgumentProvider {
  override fun asArguments(): Iterable<String> {
    return arguments.get()
  }
}

public class DependenciesPlugin : Plugin<Project> {

  override fun apply(target: Project) {
    // Setup all test tasks to listen after system properties passed in by test.py.
    val testTask = target.tasks.findByName("test") as Test?
    testTask?.configure(isR8Lib = false, r8Jar = null, r8LibPartitionMapFile = null)

    // runtimeOnlyData is similar to runtimeOnly where -DTest_DEP_<x> is set to point to the
    // location.
    // com.android.tools.r8.TestDeps handles the runtime reading of these properties.
    val runtimeOnlyDataScope = target.configurations.dependencyScope("runtimeOnlyDataScope")
    target.configurations.consumable("runtimeOnlyDataElements") {
      extendsFrom(runtimeOnlyDataScope.get())
    }
    val runtimeOnlyDataConfig =
      target.configurations.resolvable("runtimeOnlyDataConfig") {
        extendsFrom(runtimeOnlyDataScope.get())
      }

    val testDepsArguments: Provider<List<String>> =
      runtimeOnlyDataConfig.flatMap { config ->
        config.incoming.artifacts.resolvedArtifacts.map { artifacts ->
          artifacts
            .mapNotNull { artifact ->
              val prop = artifact.variant.attributes.getAttribute(TEST_DEP_PROP)
              if (prop != null) {
                "-DTEST_DEP_${prop}=${artifact.file.absolutePath}"
              } else {
                null
              }
            }
            .distinct()
        }
      }
    val testDepsFiles = target.files(runtimeOnlyDataConfig)

    target.tasks.withType(Test::class.java).configureEach {
      outputs.doNotCacheIf("Test runs should not and cannot not be cached") { true }
      jvmArgumentProviders.add(
        TestDepsCommandLineArgumentProvider(files = testDepsFiles, arguments = testDepsArguments)
      )
    }
  }

  public companion object {
    public fun computeRoot(file: File): File {
      // The root folder name is setup dependent.
      // It is instead identified by being a folder with a child folder called 'd8_r8'.
      var current: File? = file
      while (current != null) {
        if (current.resolve("d8_r8").isDirectory) {
          return current
        } else {
          current = current.getParentFile()
        }
      }
      throw RuntimeException("Could not find root dir from $file")
    }
  }
}

public enum class Jdk(public val folder: String, public val version: Int) {
  // Only include LTS and latest non-LTS GA.
  JDK_8("jdk8", 8),
  JDK_9("openjdk-9.0.4", 9), // JDK-9 not LTS, but still used.
  JDK_11("jdk-11", 11),
  JDK_17("jdk-17", 17),
  JDK_21("jdk-21", 21),
  JDK_25("jdk-25", 25),
  JDK_27("jdk-27", 27);

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

  public 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(),
    )
  }
}

public fun Test.configure(isR8Lib: Boolean, r8Jar: File?, r8LibPartitionMapFile: File? = null) {
  project.plugins.apply("org.gradle.test-retry")
  TestConfigurationHelper.setupTestTask(this, isR8Lib, r8Jar, r8LibPartitionMapFile)
}

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

// See https://datatracker.ietf.org/doc/html/rfc4122#section-4.3 for the algorithm.
public fun uuid5(namespace: UUID, name: String): UUID {
  val md = MessageDigest.getInstance("SHA-1")
  md.update(uuidToBytes(namespace))
  md.update(name.encodeToByteArray())
  val sha1Bytes = md.digest()
  // Set version 5 (upper 4 bits of octet 6).
  sha1Bytes[6] = (sha1Bytes[6].toInt() and 0x0f).toByte()
  sha1Bytes[6] = (sha1Bytes[6].toInt() or 0x50).toByte()
  // Set two upper bits of octet 8 to 10.
  sha1Bytes[8] = (sha1Bytes[8].toInt() and 0x3f).toByte()
  sha1Bytes[8] = (sha1Bytes[8].toInt() or 0x80).toByte()
  return uuidFromBytes(sha1Bytes)
}

private fun uuidFromBytes(data: ByteArray): UUID {
  assert(data.size >= 16)
  return UUID(toNetworkOrder(data, 0), toNetworkOrder(data, 8))
}

private fun uuidToBytes(uuid: UUID): ByteArray {
  val result = ByteArray(16)
  fromNetworkByteOrder(uuid.mostSignificantBits, result, 0)
  fromNetworkByteOrder(uuid.leastSignificantBits, result, 8)
  return result
}

private fun toNetworkOrder(data: ByteArray, dataIndex: Int): Long {
  var result: Long = 0
  for (i in 0..7) result = result shl 8 or (data[dataIndex + i].toInt() and 0xff).toLong()
  return result
}

private fun fromNetworkByteOrder(value: Long, dest: ByteArray, destIndex: Int) {
  for (i in 0..7) dest[i + destIndex] = (value shr (7 - i) * 8 and 0xffL).toByte()
}

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

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

public fun Project.getJavaHome(jdk: Jdk): File {
  val os: OperatingSystem = DefaultNativePlatform.getCurrentOperatingSystem()
  var osFolder = "linux"
  if (os.isWindows) {
    osFolder = "windows"
  }
  if (os.isMacOsX) {
    osFolder = "osx/Contents/Home"
  }
  return getRoot().resolveAll("third_party", "openjdk", jdk.folder, osFolder)
}

public fun Project.getCompilerPath(jdk: Jdk): String {
  val os: OperatingSystem = DefaultNativePlatform.getCurrentOperatingSystem()
  val binary = if (os.isWindows) "javac.exe" else "javac"
  return getJavaHome(jdk).resolveAll("bin", binary).toString()
}

private fun Project.getJavaPath(jdk: Jdk): String {
  val os: OperatingSystem = DefaultNativePlatform.getCurrentOperatingSystem()
  val binary = if (os.isWindows) "java.exe" else "java"
  return getJavaHome(jdk).resolveAll("bin", binary).toString()
}

public fun Project.getJavaLauncher(jdk: Jdk): JavaLauncher {
  val installationPath = project.layout.projectDirectory.dir(getJavaHome(jdk).toString())
  val executablePath = project.layout.projectDirectory.file(getJavaPath(jdk))
  return object : JavaLauncher {
    override fun getMetadata(): JavaInstallationMetadata {
      return object : JavaInstallationMetadata {
        override fun getLanguageVersion(): JavaLanguageVersion {
          return DefaultJavaLanguageVersion.of(jdk.version)
        }

        override fun getJavaRuntimeVersion(): String {
          return jdk.name
        }

        override fun getJvmVersion(): String {
          return jdk.name
        }

        override fun getVendor(): String {
          return "vendor"
        }

        override fun getInstallationPath(): Directory {
          return installationPath
        }

        override fun isCurrentJvm(): Boolean {
          return false
        }
      }
    }

    override fun getExecutablePath(): RegularFile {
      return executablePath
    }
  }
}

public object JvmCompatibility {
  public const val release: Int = 11
}

public object ThirdPartyDeps {
  public val aapt2: ThirdPartyDependency =
    ThirdPartyDependency("aapt2", Paths.get("third_party", "aapt2").toFile())
  public val agsa: ThirdPartyDependency =
    ThirdPartyDependency(
      "agsa",
      Paths.get("third_party", "closedsource-apps", "agsa", "20250412-v16.14.47").toFile(),
      testOnly = true,
      type = DependencyType.X20,
    )
  public val androidJars: List<ThirdPartyDependency> = getThirdPartyAndroidJars()
  public val androidVMs: List<ThirdPartyDependency> = getThirdPartyAndroidVms()
  public val dex2Oats: List<ThirdPartyDependency> = getThirdPartyDex2Oats()
  public val apiDatabase: ThirdPartyDependency =
    ThirdPartyDependency(
      "apiDatabase",
      Paths.get("third_party", "api_database", "api_database").toFile(),
    )
  public val artTests: ThirdPartyDependency =
    ThirdPartyDependency("art-tests", Paths.get("tests", "2017-10-04", "art").toFile())
  public val artTestsLegacy: ThirdPartyDependency =
    ThirdPartyDependency("art-tests-legacy", Paths.get("tests", "2016-12-19", "art").toFile())
  public val bundletool: ThirdPartyDependency =
    ThirdPartyDependency(
      "bundletool",
      Paths.get("third_party", "bundletool", "bundletool-1.11.0").toFile(),
    )
  public val clank: ThirdPartyDependency =
    ThirdPartyDependency(
      "clank",
      Paths.get("third_party", "chrome", "clank_google3_prebuilt").toFile(),
      testOnly = true,
      type = DependencyType.X20,
    )
  public val chrome: ThirdPartyDependency =
    ThirdPartyDependency(
      "chrome",
      Paths.get("third_party", "chrome", "chrome_200430").toFile(),
      testOnly = true,
      type = DependencyType.X20,
    )
  public val chromeBenchmark: ThirdPartyDependency =
    ThirdPartyDependency(
      "chrome-benchmark",
      Paths.get("third_party", "opensource-apps", "chrome").toFile(),
    )
  public val chromeHeadless: ThirdPartyDependency = getThirdPartyChromeHeadless()
  public val compilerApi: ThirdPartyDependency =
    ThirdPartyDependency(
      "compiler-api",
      Paths.get("third_party", "binary_compatibility_tests", "compiler_api_tests").toFile(),
    )
  public val composeExamplesChangedBitwiseValuePropagation: ThirdPartyDependency =
    ThirdPartyDependency(
      "compose-examples-changed-bitwise-value-propagation",
      Paths.get(
          "third_party",
          "opensource-apps",
          "compose-examples",
          "changed-bitwise-value-propagation",
        )
        .toFile(),
    )
  public val composeSamplesCrane: ThirdPartyDependency =
    ThirdPartyDependency(
      "compose-samples-crane",
      Paths.get("third_party", "opensource-apps", "android", "compose-samples", "crane").toFile(),
    )
  public val composeSamplesJetCaster: ThirdPartyDependency =
    ThirdPartyDependency(
      "compose-samples-jetcaster",
      Paths.get("third_party", "opensource-apps", "android", "compose-samples", "jetcaster")
        .toFile(),
    )
  public val composeSamplesJetChat: ThirdPartyDependency =
    ThirdPartyDependency(
      "compose-samples-jetchat",
      Paths.get("third_party", "opensource-apps", "android", "compose-samples", "jetchat").toFile(),
    )
  public val composeSamplesJetLagged: ThirdPartyDependency =
    ThirdPartyDependency(
      "compose-samples-jetlagged",
      Paths.get("third_party", "opensource-apps", "android", "compose-samples", "jetlagged")
        .toFile(),
    )
  public val composeSamplesJetNews: ThirdPartyDependency =
    ThirdPartyDependency(
      "compose-samples-jetnews",
      Paths.get("third_party", "opensource-apps", "android", "compose-samples", "jetnews").toFile(),
    )
  public val composeSamplesJetSnack: ThirdPartyDependency =
    ThirdPartyDependency(
      "compose-samples-jetsnack",
      Paths.get("third_party", "opensource-apps", "android", "compose-samples", "jetsnack").toFile(),
    )
  public val composeSamplesOwl: ThirdPartyDependency =
    ThirdPartyDependency(
      "compose-samples-owl",
      Paths.get("third_party", "opensource-apps", "android", "compose-samples", "owl").toFile(),
    )
  public val composeSamplesReply: ThirdPartyDependency =
    ThirdPartyDependency(
      "compose-samples-reply",
      Paths.get("third_party", "opensource-apps", "android", "compose-samples", "reply").toFile(),
    )
  public val coreLambdaStubs: ThirdPartyDependency =
    ThirdPartyDependency("coreLambdaStubs", Paths.get("third_party", "core-lambda-stubs").toFile())
  public val desugarLibraryConversions: ThirdPartyDependency =
    ThirdPartyDependency(
      "customConversion",
      Paths.get("third_party", "openjdk", "custom_conversion").toFile(),
    )
  public val dagger: ThirdPartyDependency =
    ThirdPartyDependency("dagger", Paths.get("third_party", "dagger", "2.41").toFile())
  public val dartSdk: ThirdPartyDependency =
    ThirdPartyDependency("dart-sdk", Paths.get("third_party", "dart-sdk").toFile())
  public val examples: ThirdPartyDependency =
    ThirdPartyDependency("examples", Paths.get("third_party", "examples").toFile())
  public val examplesAndroidN: ThirdPartyDependency =
    ThirdPartyDependency("examplesAndroidN", Paths.get("third_party", "examplesAndroidN").toFile())
  public val examplesAndroidO: ThirdPartyDependency =
    ThirdPartyDependency("examplesAndroidO", Paths.get("third_party", "examplesAndroidO").toFile())
  public val examplesAndroidOGenerated: ThirdPartyDependency =
    ThirdPartyDependency(
      "examplesAndroidOGenerated",
      Paths.get("third_party", "examplesAndroidOGenerated").toFile(),
    )
  public val examplesAndroidOLegacy: ThirdPartyDependency =
    ThirdPartyDependency(
      "examplesAndroidOLegacy",
      Paths.get("third_party", "examplesAndroidOLegacy").toFile(),
    )
  public val examplesAndroidP: ThirdPartyDependency =
    ThirdPartyDependency("examplesAndroidP", Paths.get("third_party", "examplesAndroidP").toFile())
  public val examplesAndroidPGenerated: ThirdPartyDependency =
    ThirdPartyDependency(
      "examplesAndroidPGenerated",
      Paths.get("third_party", "examplesAndroidPGenerated").toFile(),
    )
  public val desugarJdkLibs: ThirdPartyDependency =
    ThirdPartyDependency(
      "desugar-jdk-libs",
      Paths.get("third_party", "openjdk", "desugar_jdk_libs").toFile(),
    )
  public val desugarJdkLibsLegacy: ThirdPartyDependency =
    ThirdPartyDependency(
      "desugar-jdk-libs-legacy",
      Paths.get("third_party", "openjdk", "desugar_jdk_libs_legacy").toFile(),
    )
  public val desugarLibraryReleases: List<ThirdPartyDependency> =
    getThirdPartyDesugarLibraryReleases()
  // TODO(b/289363570): This could probably be removed.
  public val framework: ThirdPartyDependency =
    ThirdPartyDependency(
      "framework",
      Paths.get("third_party", "framework").toFile(),
      testOnly = true,
      type = DependencyType.X20,
    )
  public val googleJavaFormat: ThirdPartyDependency =
    ThirdPartyDependency(
      "google-java-format-1.24",
      Paths.get("third_party", "google", "google-java-format", "1.24.0").toFile(),
    )
  public val googleKotlinFormat: ThirdPartyDependency =
    ThirdPartyDependency(
      "google-kotlin-format-0.54",
      Paths.get("third_party", "google", "google-kotlin-format", "0.54").toFile(),
    )
  public val googleYapf_20231013: ThirdPartyDependency =
    ThirdPartyDependency(
      "google-yapf-20231013",
      Paths.get("third_party", "google", "yapf", "20231013").toFile(),
    )
  public val gson: ThirdPartyDependency =
    ThirdPartyDependency("gson", Paths.get("third_party", "gson", "gson-2.10.1").toFile())
  public val guavaJre: ThirdPartyDependency =
    ThirdPartyDependency(
      "guava-jre",
      Paths.get("third_party", "guava", "guava-32.1.2-jre").toFile(),
    )
  public val desugarJdkLibs11: ThirdPartyDependency =
    ThirdPartyDependency(
      "desugar-jdk-libs-11",
      Paths.get("third_party", "openjdk", "desugar_jdk_libs_11").toFile(),
    )
  public val gmscoreVersions: List<ThirdPartyDependency> = getGmsCoreVersions()
  public val internalIssues: List<ThirdPartyDependency> = getInternalIssues()
  public val jacoco: ThirdPartyDependency =
    ThirdPartyDependency("jacoco", Paths.get("third_party", "jacoco", "0.8.6").toFile())
  public val jasmin: ThirdPartyDependency =
    ThirdPartyDependency("jasmin", Paths.get("third_party", "jasmin").toFile())
  public val jsr223: ThirdPartyDependency =
    ThirdPartyDependency("jsr223", Paths.get("third_party", "jsr223-api-1.0").toFile())
  public val java8Runtime: ThirdPartyDependency =
    ThirdPartyDependency(
      "openjdk-rt-1.8",
      Paths.get("third_party", "openjdk", "openjdk-rt-1.8").toFile(),
    )
  public val jdks: List<ThirdPartyDependency> = getJdks()
  public val jdk11Test: ThirdPartyDependency =
    ThirdPartyDependency("jdk-11-test", Paths.get("third_party", "openjdk", "jdk-11-test").toFile())
  public val jdk21Float16Test: ThirdPartyDependency =
    ThirdPartyDependency(
      "float16-test",
      Paths.get("third_party", "openjdk", "float16-test").toFile(),
    )
  public val junit: ThirdPartyDependency =
    ThirdPartyDependency("junit", Paths.get("third_party", "junit").toFile())
  public val jdwpTests: ThirdPartyDependency =
    ThirdPartyDependency("jdwp-tests", Paths.get("third_party", "jdwp-tests").toFile())
  public val kotlinCompilers: List<ThirdPartyDependency> = getThirdPartyKotlinCompilers()
  public val kotlinR8TestResources: ThirdPartyDependency =
    ThirdPartyDependency(
      "kotlinR8TestResources",
      Paths.get("third_party", "kotlinR8TestResources").toFile(),
    )
  public val kotlinxCoroutines: ThirdPartyDependency =
    ThirdPartyDependency(
      "kotlinx-coroutines-1.3.6",
      Paths.get("third_party", "kotlinx-coroutines-1.3.6").toFile(),
    )
  public val multidex: ThirdPartyDependency =
    ThirdPartyDependency("multidex", Paths.get("third_party", "multidex").toFile())
  public val nest: ThirdPartyDependency =
    ThirdPartyDependency(
      "nest",
      Paths.get("third_party", "nest", "nest_20180926_7c6cfb").toFile(),
      testOnly = true,
      type = DependencyType.X20,
    )
  public val node: ThirdPartyDependency =
    ThirdPartyDependency("node", Paths.get("third_party", "node", "24.16.0", "linux").toFile())
  public val nowinandroid: ThirdPartyDependency =
    ThirdPartyDependency(
      "nowinandroid",
      Paths.get("third_party", "opensource-apps", "android", "nowinandroid").toFile(),
    )
  public val prettier: ThirdPartyDependency =
    ThirdPartyDependency("prettier", Paths.get("third_party", "prettier", "3.8.3").toFile())
  public val processKeepRulesBinaryCompatibility: ThirdPartyDependency =
    ThirdPartyDependency(
      "processkeeprules-binary-compatibility",
      Paths.get("third_party", "processkeeprules", "binary_compatibility").toFile(),
    )
  public val proguards: List<ThirdPartyDependency> = getThirdPartyProguards()
  public val proguardsettings: ThirdPartyDependency =
    ThirdPartyDependency(
      "proguardsettings",
      Paths.get("third_party", "proguardsettings").toFile(),
      testOnly = true,
      type = DependencyType.X20,
    )
  public val protoc: ThirdPartyDependency =
    ThirdPartyDependency("protoc", Paths.get("third_party", "protoc").toFile())
  public val protoRuntimeEdition2023: ThirdPartyDependency =
    ThirdPartyDependency(
      "protoRuntimeEdition2023",
      Paths.get("third_party", "proto", "runtime", "edition2023").toFile(),
      testOnly = true,
      type = DependencyType.X20,
    )
  public val protoRuntimeLegacy: ThirdPartyDependency =
    ThirdPartyDependency(
      "protoRuntimeLegacy",
      Paths.get("third_party", "proto", "runtime", "legacy").toFile(),
      testOnly = true,
      type = DependencyType.X20,
    )
  public val protoTestEdition2023: ThirdPartyDependency =
    ThirdPartyDependency(
      "protoTestEdition2023",
      Paths.get("third_party", "proto", "test", "edition2023").toFile(),
      testOnly = true,
      type = DependencyType.X20,
    )
  public val protoTestProto2: ThirdPartyDependency =
    ThirdPartyDependency(
      "protoTestProto2",
      Paths.get("third_party", "proto", "test", "proto2").toFile(),
      testOnly = true,
      type = DependencyType.X20,
    )
  public val protoTestProto3: ThirdPartyDependency =
    ThirdPartyDependency(
      "protoTestProto3",
      Paths.get("third_party", "proto", "test", "proto3").toFile(),
      testOnly = true,
      type = DependencyType.X20,
    )
  public val r8: ThirdPartyDependency =
    ThirdPartyDependency("r8", Paths.get("third_party", "r8").toFile())
  public val r8Mappings: ThirdPartyDependency =
    ThirdPartyDependency("r8-mappings", Paths.get("third_party", "r8mappings").toFile())
  public val r8v2_0_74: ThirdPartyDependency =
    ThirdPartyDependency("r8-v2-0-74", Paths.get("third_party", "r8-releases", "2.0.74").toFile())
  public val r8v3_2_54: ThirdPartyDependency =
    ThirdPartyDependency("r8-v3-2-54", Paths.get("third_party", "r8-releases", "3.2.54").toFile())
  public val r8v8_0_46: ThirdPartyDependency =
    ThirdPartyDependency("r8-v8-0-46", Paths.get("third_party", "r8-releases", "8.0.46").toFile())
  public val retraceBenchmark: ThirdPartyDependency =
    ThirdPartyDependency(
      "retrace-benchmark",
      Paths.get("third_party", "retrace_benchmark").toFile(),
    )
  public val retraceBinaryCompatibility: ThirdPartyDependency =
    ThirdPartyDependency(
      "retrace-binary-compatibility",
      Paths.get("third_party", "retrace", "binary_compatibility").toFile(),
    )
  public val retracePartitionFormats: ThirdPartyDependency =
    ThirdPartyDependency(
      "retrace-partition-formats",
      Paths.get("third_party", "retrace", "partition_formats").toFile(),
    )
  public val retraceInternal: ThirdPartyDependency =
    ThirdPartyDependency(
      "retrace-internal",
      Paths.get("third_party", "retrace_internal").toFile(),
      testOnly = true,
      type = DependencyType.X20,
    )
  public val rhino: ThirdPartyDependency =
    ThirdPartyDependency("rhino", Paths.get("third_party", "rhino-1.7.10").toFile())
  public val rhinoAndroid: ThirdPartyDependency =
    ThirdPartyDependency("rhino-android", Paths.get("third_party", "rhino-android-1.1.1").toFile())
  public val smali: ThirdPartyDependency =
    ThirdPartyDependency("smali", Paths.get("third_party", "smali").toFile())
  public val systemUI: ThirdPartyDependency =
    ThirdPartyDependency(
      "systemUI",
      Paths.get("third_party", "closedsource-apps", "systemui").toFile(),
      testOnly = true,
      type = DependencyType.X20,
    )
  public val tivi: ThirdPartyDependency =
    ThirdPartyDependency("tivi", Paths.get("third_party", "opensource-apps", "tivi").toFile())
  public val youtube1719: ThirdPartyDependency =
    ThirdPartyDependency(
      "youtube-17.19",
      Paths.get("third_party", "youtube", "youtube.android_17.19").toFile(),
      testOnly = true,
      type = DependencyType.X20,
    )
}

private fun getThirdPartyAndroidJars(): List<ThirdPartyDependency> {
  return listOf(
      "libcore_latest",
      "lib-main",
      "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",
      "lib-v35",
      "lib-v36",
      "lib-v36.1",
      "lib-v37",
    )
    .map(::getThirdPartyAndroidJar)
}

private fun getThirdPartyAndroidJar(version: String): ThirdPartyDependency {
  return ThirdPartyDependency(version, Paths.get("third_party", "android_jar", version).toFile())
}

private fun getThirdPartyDex2Oats(): List<ThirdPartyDependency> {
  return listOf("head", "36.0", "35.14", "33.10").map(::getThirdPartyDex2Oat)
}

private fun getThirdPartyDex2Oat(version: String): ThirdPartyDependency {
  return ThirdPartyDependency(version, Paths.get("third_party", "dex2oat", version).toFile())
}

private fun getThirdPartyAndroidVms(): List<ThirdPartyDependency> {
  return listOf(
      listOf("host", "art-master"),
      listOf("host", "art-17.0.0-beta4"),
      listOf("host", "art-16.0.0"),
      listOf("host", "art-15.0.0-beta2"),
      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)
}

private fun getThirdPartyAndroidVm(version: List<String>): ThirdPartyDependency {
  return ThirdPartyDependency(
    version.last(),
    Paths.get("tools", "linux", *version.slice(0..version.size - 2).toTypedArray(), version.last())
      .toFile(),
  )
}

private fun getThirdPartyChromeHeadless(): ThirdPartyDependency {
  val os: OperatingSystem = DefaultNativePlatform.getCurrentOperatingSystem()
  val subFolder =
    when {
      os.isLinux -> "linux"
      os.isMacOsX -> "mac"
      else -> {
        assert(os.isWindows)
        "windows"
      }
    }
  return ThirdPartyDependency(
    "chrome_headless",
    Paths.get("third_party", "chrome_headless", subFolder).toFile(),
    testOnly = true,
  )
}

private 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() }
  }
}

private fun getThirdPartyProguards(): List<ThirdPartyDependency> {
  return listOf("proguard-7.0.0", "proguard-7.7.0").map {
    ThirdPartyDependency(it, Paths.get("third_party", "proguard", it).toFile())
  }
}

private 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-1.9.21",
      "kotlin-compiler-2.0.20",
      "kotlin-compiler-2.1.10",
      "kotlin-compiler-2.2.0",
      "kotlin-compiler-2.3.10",
      "kotlin-compiler-2.4.20",
      "kotlin-compiler-dev",
    )
    .map { ThirdPartyDependency(it, Paths.get("third_party", "kotlin", it).toFile()) }
}

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

private fun getInternalIssues(): List<ThirdPartyDependency> {
  return listOf("issue-127524985").map {
    ThirdPartyDependency(
      "internal-$it",
      Paths.get("third_party", "internal", it).toFile(),
      testOnly = true,
      type = DependencyType.X20,
    )
  }
}

private fun getGmsCoreVersions(): List<ThirdPartyDependency> {
  return listOf("gmscore_v10", "latest").map {
    ThirdPartyDependency(
      "gmscore-version-$it",
      Paths.get("third_party", "gmscore", it).toFile(),
      testOnly = true,
      type = DependencyType.X20,
    )
  }
}

private fun allDependencies(): List<ThirdPartyDependency> {
  val allDeps = mutableListOf<ThirdPartyDependency>()
  ThirdPartyDeps::class.declaredMemberProperties.forEach {
    val value = it.get(ThirdPartyDeps)
    if (value is List<*>) {
      value.forEach { dep ->
        if (dep is ThirdPartyDependency) {
          allDeps.add(dep)
        } else {
          throw RuntimeException("Cannot handle non ThirdPartyDependency dependency.")
        }
      }
    } else {
      allDeps.add(value as ThirdPartyDependency)
    }
  }
  return allDeps
}

public fun allPublicDependencies(): List<ThirdPartyDependency> {
  return allDependencies().filter { x -> !x.testOnly && x.type == DependencyType.GOOGLE_STORAGE }
}

public fun allPublicTestDependencies(): List<ThirdPartyDependency> {
  return allDependencies().filter { x -> x.testOnly && x.type == DependencyType.GOOGLE_STORAGE }
}

public fun allInternalDependencies(): List<ThirdPartyDependency> {
  return allDependencies().filter { x -> !x.testOnly && x.type == DependencyType.X20 }
}

public fun allInternalTestDependencies(): List<ThirdPartyDependency> {
  return allDependencies().filter { x -> x.testOnly && x.type == DependencyType.X20 }
}

public fun extractClassesPaths(prefix: String, vararg paths: String): String {
  val result: MutableList<String> = ArrayList()
  paths.forEach { it ->
    result.addAll(
      it.split(File.pathSeparator).filter { it.contains("${prefix}build${File.separator}classes") }
    )
  }
  return result.joinToString(File.pathSeparator)
}
