// Copyright (c) 2026, 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 com.google.gson.Gson
import java.net.URI
import java.nio.file.Files.readString
import java.nio.file.Paths
import java.util.UUID
import java.util.concurrent.Callable
import org.gradle.api.tasks.bundling.Jar
import org.gradle.kotlin.dsl.provideDelegate
import org.spdx.sbom.gradle.SpdxSbomTask
import org.spdx.sbom.gradle.extensions.DefaultSpdxSbomTaskExtension

plugins {
  id("org.jetbrains.kotlin.jvm")
  id("r8-conventions")
  id("dependencies-plugin")
  id("org.spdx.sbom")
}

if (project.hasProperty("spdxVersion")) {
  project.version = project.property("spdxVersion")!!
}

// We need all the runtime deps for SPDX generation.
val r8Deps by
  configurations.creating {
    isCanBeConsumed = false
    isCanBeResolved = true
  }

dependencies {
  compileOnly(libs.bundles.compilerDeps)
  r8Deps(libs.bundles.compilerDeps)
}

spdxSbom {
  targets {
    create("r8") {
      // Use of both compileClasspath and runtimeClasspath due to how the
      // dependencies jar is built and dependencies above therefore use
      // compileOnly for actual runtime dependencies.
      configurations.set(listOf("compileClasspath", "runtimeClasspath"))
      scm {
        uri.set("https://r8.googlesource.com/r8/")
        if (project.hasProperty("spdxRevision")) {
          revision.set(project.property("spdxRevision").toString())
        }
      }
      document {
        name.set("R8 Compiler Suite")
        // Generate version 5 UUID from fixed namespace UUID and name generated from revision
        // (git hash) and artifact name.
        if (project.hasProperty("spdxRevision")) {
          namespace.set(
            "https://spdx.google/" +
              uuid5(
                UUID.fromString("df17ea25-709b-4edc-8dc1-d3ca82c74e8e"),
                project.property("spdxRevision").toString() + "-r8",
              )
          )
        }
        creator.set("Organization: Google LLC")
        packageSupplier.set("Organization: Google LLC")
      }
    }
  }
}

val keepRadiusProtoJarScope by configurations.dependencyScope("keepRadiusProtoJarScope")
val keepRadiusProtoJarConfig by
  configurations.resolvable("keepRadiusProtoJarConfig") { extendsFrom(keepRadiusProtoJarScope) }
val keepAnnoDepsJarExceptAsmScope by configurations.dependencyScope("keepAnnoDepsJarExceptAsmScope")
val keepAnnoDepsJarExceptAsmConfig by
  configurations.resolvable("keepAnnoDepsJarExceptAsmConfig") {
    extendsFrom(keepAnnoDepsJarExceptAsmScope)
  }
val keepAnnoToolsJarScope by configurations.dependencyScope("keepAnnoToolsJarScope")
val keepAnnoToolsJarConfig by
  configurations.resolvable("keepAnnoToolsJarConfig") { extendsFrom(keepAnnoToolsJarScope) }

val libanalyzerProtoJarScope by configurations.dependencyScope("libanalyzerProtoJarScope")
val libanalyzerProtoJarConfig by
  configurations.resolvable("libanalyzerProtoJarConfig") { extendsFrom(libanalyzerProtoJarScope) }

val mainJarScope by configurations.dependencyScope("mainJarScope")
val mainJarConfig by configurations.resolvable("mainJarConfig") { extendsFrom(mainJarScope) }
val mainResourcesScope by configurations.dependencyScope("mainResourcesScope")
val mainResourcesConfig by
  configurations.resolvable("mainResourcesConfig") { extendsFrom(mainResourcesScope) }
val swissArmyKnifeScope by configurations.dependencyScope("swissArmyKnifeScope")
val swissArmyKnifeConfig by
  configurations.resolvable("swissArmyKnifeConfig") {
    extendsFrom(swissArmyKnifeScope)
    isTransitive = false
  }

dependencies {
  keepRadiusProtoJarScope(project(":keepradius", "keepradiusProtoJar"))
  keepAnnoDepsJarExceptAsmScope(project(":keepanno", "keepannoDepsJarExceptAsm"))
  keepAnnoToolsJarScope(project(":keepanno", "keepannoToolsJar"))
  libanalyzerProtoJarScope(project(":libanalyzer", "libanalyzer-proto-jar"))
  mainJarScope(project(":main", "mainJar"))
  mainResourcesScope(project(":main", "mainResources"))
  swissArmyKnifeScope(project(":swissarmyknife"))
}

val sharedDepsScope by configurations.dependencyScope("sharedDepsScope")
val sharedDepsConfig by
  configurations.resolvable("sharedDepsConfig") { extendsFrom(sharedDepsScope) }

val sharedTestDepsScope by configurations.dependencyScope("sharedTestDepsScope")
val sharedTestDepsConfig by
  configurations.resolvable("sharedTestDepsConfig") { extendsFrom(sharedTestDepsScope) }

dependencies {
  sharedDepsScope(project(":third_party", "sharedDepsFiles"))
  sharedTestDepsScope(project(":third_party", "sharedTestDepsFiles"))
}

val depsJarFilesScope by configurations.dependencyScope("depsJarFilesScope")

val depsJarFiles by configurations.consumable("depsJarFiles") { extendsFrom(depsJarFilesScope) }

val depsFiles by configurations.consumable("depsFiles") { extendsFrom(depsJarFilesScope) }

fun relocateDepsExceptAsm(pkg: String): List<String> {
  return listOf(
    "--map",
    "android.aapt.**->${pkg}.android.aapt",
    "--map",
    "androidx.annotation.**->${pkg}.androidx.annotation",
    "--map",
    "androidx.collection.**->${pkg}.androidx.collection",
    "--map",
    "androidx.tracing.**->${pkg}.androidx.tracing",
    "--map",
    "com.android.**->${pkg}.com.android",
    "--map",
    "com.android.zipflinger.**->${pkg}.com.android.zipflinger",
    "--map",
    "com.google.common.**->${pkg}.com.google.common",
    "--map",
    "com.google.gson.**->${pkg}.com.google.gson",
    "--map",
    "com.google.thirdparty.**->${pkg}.com.google.thirdparty",
    "--map",
    "com.squareup.wire.**->${pkg}.com.squareup.wire",
    "--map",
    "it.unimi.dsi.fastutil.**->${pkg}.it.unimi.dsi.fastutil",
    "--map",
    "kotlin.**->${pkg}.jetbrains.kotlin",
    "--map",
    "kotlinx.**->${pkg}.jetbrains.kotlinx",
    "--map",
    "okio.**->${pkg}.okio",
    "--map",
    "org.jetbrains.**->${pkg}.org.jetbrains",
    "--map",
    "org.intellij.**->${pkg}.org.intellij",
    "--map",
    "org.checkerframework.**->${pkg}.org.checkerframework",
    "--map",
    "com.google.j2objc.**->${pkg}.com.google.j2objc",
    "--map",
    "com.google.protobuf.**->${pkg}.com.google.protobuf",
    "--map",
    "perfetto.protos.**->${pkg}.perfetto.protos",
    "--map",
    "org.jspecify.annotations.**->${pkg}.org.jspecify.annotations",
    "--map",
    "_COROUTINE.**->${pkg}._COROUTINE",
  )
}

interface InjectedArcOps {
  @get:Inject val arcOps: ArchiveOperations
}

tasks {
  val filteredDepsJar =
    register<Jar>("filteredDepsJar") {
      val injected = project.objects.newInstance<InjectedArcOps>()
      from(
        Callable {
          r8Deps.incoming.files
            .filter {
              val path = it.absolutePath
              path.contains("third_party") &&
                path.contains("dependencies") &&
                !path.contains("errorprone")
            }
            .map { injected.arcOps.zipTree(it) }
        }
      )

      archiveFileName.set("r8-deps-merged.jar")
      destinationDirectory.set(layout.buildDirectory.dir("libs"))
      duplicatesStrategy = DuplicatesStrategy.EXCLUDE
    }

  withType<SpdxSbomTask> {
    taskExtension.set(
      object : DefaultSpdxSbomTaskExtension() {
        override fun mapRepoUri(input: URI?, moduleId: ModuleVersionIdentifier): URI? {

          // Locate the file origin.json with URL for download location.
          fun getOriginJson(): java.nio.file.Path {
            var repositoryDir =
              moduleId.group.replace('.', '/') + "/" + moduleId.name + "/" + moduleId.version
            return Paths.get("third_party", "dependencies", repositoryDir, "origin.json")
          }

          // Simple data model of the content of origin.json generated by the tool to download
          // and create a local repository. E.g.:
          /*
              {
                "artifacts": [
                  {
                    "file": "org/ow2/asm/asm/9.5/asm-9.5.pom",
                    "repo": "https://repo1.maven.org/maven2/",
                    "artifact": "org.ow2.asm:asm:pom:9.5"
                  },
                  {
                    "file": "org/ow2/asm/asm/9.5/asm-9.5.jar",
                    "repo": "https://repo1.maven.org/maven2/",
                    "artifact": "org.ow2.asm:asm:jar:9.5"
                  }
                ]
              }
          */
          data class Artifact(val file: String, val repo: String, val artifact: String)
          data class Artifacts(val artifacts: List<Artifact>)

          // Read origin.json.
          val json = readString(getOriginJson())
          val artifacts = Gson().fromJson(json, Artifacts::class.java)
          return URI.create(artifacts.artifacts.get(0).repo)
        }
      }
    )
  }

  val consolidatedLicense =
    register<ConsolidatedLicenseTask>("consolidatedLicense") {
      r8License = File(getRootDir(), "LICENSE")
      libraryLicenseMap = File(getRootDir(), "LIBRARY-LICENSE")
      libraryLicenses = File(getRootDir(), "library-licensing")
      dependencies =
        configurations.named("runtimeClasspath").map { runtimeClasspath ->
          runtimeClasspath.incoming.resolutionResult.allComponents.mapNotNull {
            val compId = it.id
            if (compId is ModuleComponentIdentifier) {
              "${compId.group}:${compId.module}"
            } else null
          }
        }
      consolidatedOutputFile = File(getRootDir(), "build/generatedLicense/LICENSE")
    }

  val threadingModuleBlockingJar =
    register<Zip>("threadingModuleBlockingJar") {
      val injected = project.objects.newInstance<InjectedArcOps>()
      dependsOn(mainJarConfig)
      from(mainJarConfig.elements.map { it.map { injected.arcOps.zipTree(it) } })
      include("com/android/tools/r8/threading/providers/blocking/**")
      destinationDirectory.set(File(getRootDir(), "build/libs"))
      archiveFileName.set("threading-module-blocking.jar")
    }

  val threadingModuleSingleThreadedJar =
    register<Zip>("threadingModuleSingleThreadedJar") {
      val injected = project.objects.newInstance<InjectedArcOps>()
      dependsOn(mainJarConfig)
      from(mainJarConfig.elements.map { it.map { injected.arcOps.zipTree(it) } })
      include("com/android/tools/r8/threading/providers/singlethreaded/**")
      destinationDirectory.set(File(getRootDir(), "build/libs"))
      archiveFileName.set("threading-module-single-threaded.jar")
    }

  dependencies {
    add(depsJarFilesScope.name, files(filteredDepsJar))
    add(depsJarFilesScope.name, project(":resourceshrinker", "resourceshrinkerDepsJar"))
    add(depsJarFilesScope.name, files(threadingModuleBlockingJar))
    add(depsJarFilesScope.name, files(threadingModuleSingleThreadedJar))
  }

  val filteredDepsJarConfig by configurations.consumable("filteredDepsJarConfig")

  artifacts {
    add(depsFiles.name, consolidatedLicense)
    add(filteredDepsJarConfig.name, filteredDepsJar)
  }

  val depsJarFilesConfig by
    configurations.resolvable("depsJarFilesConfig") { extendsFrom(depsJarFilesScope) }

  // Jar containing all 3p deps, plus R8 threading modules.
  val depsJar =
    register<Zip>("depsJar") {
      dependsOn(depsJarFilesConfig)
      from(Callable { depsJarFilesConfig.files.map(::zipTree) })
      from(consolidatedLicense)
      include("**/*.class")
      include("META-INF/services/kotlin.metadata.internal.extensions.MetadataExtensions")
      include("LICENSE")
      exclude("**/module-info.class")
      exclude("javax/annotation/**")
      exclude("wireless/**")
      exclude("META-INF/versions/**")

      // Disabling compression makes this step go from 4s -> 2s as of Nov 2025,
      // as measured by "gradle --profile".
      entryCompression = ZipEntryCompression.STORED

      duplicatesStrategy = DuplicatesStrategy.EXCLUDE
      archiveFileName.set("deps.jar")
    }

  val protoJar =
    register<Zip>("protoJar") {
      val injected = project.objects.newInstance<InjectedArcOps>()
      dependsOn(keepRadiusProtoJarConfig, libanalyzerProtoJarConfig)
      from(keepRadiusProtoJarConfig.elements.map { it.map { injected.arcOps.zipTree(it) } })
      from(libanalyzerProtoJarConfig.elements.map { it.map { injected.arcOps.zipTree(it) } })
      exclude("META-INF/MANIFEST.MF")
      archiveFileName.set("proto.jar")
      destinationDirectory.set(File(getRootDir(), "build/libs"))
    }

  val r8WithRelocatedDepsManifest =
    register<Jar>("r8WithRelocatedDepsManifest") {
      manifest { attributes["Main-Class"] = "com.android.tools.r8.SwissArmyKnife" }
      archiveFileName.set("r8-manifest.jar")
    }

  val r8WithRelocatedDeps =
    register<SwissArmyKnifeTask>("r8WithRelocatedDeps") {
      outputs.doNotCacheIf("Large standalone artifact (~50MB)") { true }
      swissArmyKnifeClasspath.from(swissArmyKnifeConfig, depsJar)
      compiler = "relocator"
      inputFiles.from(depsJar)
      inputFiles.from(protoJar)
      inputFiles.from(mainResourcesConfig)
      inputFiles.from(r8WithRelocatedDepsManifest)
      inputNoResFiles.from(swissArmyKnifeConfig)
      val pkg = "com.android.tools.r8"
      extraArgs =
        listOf(
          "--map",
          "com.android.tools.r8.**->${pkg}",
          "--map",
          "com.android.tools.r8.keepanno.annotations.**->${pkg}.keepanno.annotations",
          "--map",
          "com.android.tools.r8.keepanno.**->${pkg}.relocated.keepanno",
          "--map",
          "org.objectweb.asm.**->${pkg}.org.objectweb.asm",
        ) + relocateDepsExceptAsm(pkg) + listOf("--map-diagnostics", "warning", "error")
      outputFile = File(getRootDir(), "build/libs/r8.jar")
    }

  register<SwissArmyKnifeTask>("keepAnnoToolsWithRelocatedDeps") {
    outputs.doNotCacheIf("Large standalone artifact (~8MB)") { true }
    swissArmyKnifeClasspath.from(swissArmyKnifeConfig, depsJar)
    compiler = "relocator"
    inputNoResFiles.from(keepAnnoDepsJarExceptAsmConfig)
    inputNoResFiles.from(keepAnnoToolsJarConfig)
    val pkg = "com.android.tools.r8.keepanno"
    extraArgs =
      listOf("--map", "com.android.tools.r8.keepanno.**->${pkg}") +
        relocateDepsExceptAsm(pkg) +
        listOf("--map-diagnostics", "warning", "error")
    outputFile = File(getRootDir(), "build/libs/keepanno-tools.jar")
  }

  register<CreateR8LibraryTask>("processKeepRulesLibWithRelocatedDeps") {
    r8compilerClasspath.from(r8WithRelocatedDeps.flatMap { it.outputFile })
    inputJar = r8WithRelocatedDeps.flatMap { it.outputFile }
    pgConfigs.from(File(rootDir, "src/main/keep_processkeeprules.txt"))
    enableKeepAnnotations = false

    setOutputJarFile(File(rootDir, "build/libs/processkeepruleslib.jar"))
  }
}
