// 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.net.URI
import java.nio.file.Path
import java.nio.file.Paths
import kotlin.io.path.exists
import java.nio.file.Files.readString
import net.ltgt.gradle.errorprone.errorprone
import org.gradle.api.artifacts.ModuleVersionIdentifier
import org.gradle.api.artifacts.component.ModuleComponentIdentifier
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.spdx.sbom.gradle.SpdxSbomTask
import org.spdx.sbom.gradle.extensions.DefaultSpdxSbomTaskExtension

import com.google.gson.Gson

plugins {
  `kotlin-dsl`
  id("dependencies-plugin")
  id("net.ltgt.errorprone") version "3.0.1"
  id("org.spdx.sbom") version "0.2.0-r8-patch01"
}

java {
  sourceSets.main.configure {
    java.srcDir(getRoot().resolveAll("src", "main", "java"))
    resources.srcDirs(getRoot().resolveAll("third_party", "api_database", "api_database"))
  }
  sourceCompatibility = JvmCompatibility.sourceCompatibility
  targetCompatibility = JvmCompatibility.targetCompatibility
  withSourcesJar()
}

dependencies {
  implementation(":keepanno")
  implementation(":resourceshrinker")
  compileOnly(Deps.asm)
  compileOnly(Deps.asmCommons)
  compileOnly(Deps.asmUtil)
  compileOnly(Deps.fastUtil)
  compileOnly(Deps.gson)
  compileOnly(Deps.guava)
  compileOnly(Deps.kotlinMetadata)
  errorprone(Deps.errorprone)
}

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

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")
        namespace.set("https://r8.googlesource.com/r8/-" + project.version + ".jar")
        creator.set("Organization: Google LLC")
        packageSupplier.set("Organization: Google LLC")
      }
    }
  }
}

val keepAnnoJarTask = projectTask("keepanno", "jar")
val resourceShrinkerJarTask = projectTask("resourceshrinker", "jar")
val resourceShrinkerDepsTask = projectTask("resourceshrinker", "depsJar")

fun mainJarDependencies() : FileCollection {
  return sourceSets
    .main
    .get()
    .compileClasspath
    .filter({ "$it".contains("third_party")
              && "$it".contains("dependencies")
              && !"$it".contains("errorprone")
    })
}

tasks {
  withType<Exec> {
    doFirst {
      println("Executing command: ${commandLine.joinToString(" ")}")
    }
  }

  withType<ProcessResources> {
    dependsOn(gradle.includedBuild("shared").task(":downloadDeps"))
  }

  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 by registering {
    dependsOn(gradle.includedBuild("shared").task(":downloadDeps"))
    val root = getRoot()
    val r8License = root.resolve("LICENSE")
    val libraryLicense = root.resolve("LIBRARY-LICENSE")
    val libraryLicenseFiles = fileTree(root.resolve("library-licensing"))
    inputs.files(
      listOf(r8License, libraryLicense),
      libraryLicenseFiles,
      mainJarDependencies().map(::zipTree))

    val license = getRoot().resolveAll("build", "generatedLicense", "LICENSE")
    outputs.files(license)
    val dependencies = mutableListOf<String>()
    configurations
      .findByName("runtimeClasspath")!!
      .resolvedConfiguration
      .resolvedArtifacts
      .forEach {
        val identifier = it.id.componentIdentifier
        if (identifier is ModuleComponentIdentifier) {
          dependencies.add("${identifier.group}:${identifier.module}")
        }
      }

    doLast {
      val libraryLicenses = libraryLicense.readText()
      dependencies.forEach {
        if (!libraryLicenses.contains("- artifact: $it")) {
          throw GradleException("No license for $it in LIBRARY_LICENSE")
        }
      }
      license.getParentFile().mkdirs()
      license.createNewFile()
      license.writeText(buildString {
        append("This file lists all licenses for code distributed.\n")
        .append("All non-library code has the following 3-Clause BSD license.\n")
        .append("\n")
        .append("\n")
        .append(r8License.readText())
        .append("\n")
        .append("\n")
        .append("Summary of distributed libraries:\n")
        .append("\n")
        .append(libraryLicenses)
        .append("\n")
        .append("\n")
        .append("Licenses details:\n")
        libraryLicenseFiles.sorted().forEach { file ->
          append("\n").append("\n").append(file.readText())
        }
      })
    }
  }

  val swissArmyKnife by registering(Jar::class) {
    dependsOn(keepAnnoJarTask)
    dependsOn(resourceShrinkerJarTask)
    dependsOn(gradle.includedBuild("shared").task(":downloadDeps"))
    from(sourceSets.main.get().output)
    exclude("com/android/tools/r8/threading/providers/**")
    from(keepAnnoJarTask.outputs.files.map(::zipTree))
    from(resourceShrinkerJarTask.outputs.files.map(::zipTree))
    from(getRoot().resolve("LICENSE"))
    entryCompression = ZipEntryCompression.STORED
    manifest {
      attributes["Main-Class"] = "com.android.tools.r8.SwissArmyKnife"
    }
    exclude("META-INF/*.kotlin_module")
    exclude("**/*.kotlin_metadata")
    destinationDirectory.set(getRoot().resolveAll("build", "libs"))
    archiveFileName.set("r8-full-exclude-deps.jar")
  }

  val threadingModuleBlockingJar by registering(Zip::class) {
    from(sourceSets.main.get().output)
    include("com/android/tools/r8/threading/providers/blocking/**")
    destinationDirectory.set(getRoot().resolveAll("build", "libs"))
    archiveFileName.set("threading-module-blocking.jar")
  }

  val threadingModuleSingleThreadedJar by registering(Zip::class) {
    from(sourceSets.main.get().output)
    include("com/android/tools/r8/threading/providers/singlethreaded/**")
    destinationDirectory.set(getRoot().resolveAll("build", "libs"))
    archiveFileName.set("threading-module-single-threaded.jar")
  }

  val depsJar by registering(Zip::class) {
    dependsOn(gradle.includedBuild("shared").task(":downloadDeps"))
    dependsOn(resourceShrinkerDepsTask)
    dependsOn(threadingModuleBlockingJar)
    dependsOn(threadingModuleSingleThreadedJar)
    from(threadingModuleBlockingJar.get().outputs.getFiles().map(::zipTree))
    from(threadingModuleSingleThreadedJar.get().outputs.getFiles().map(::zipTree))
    from(mainJarDependencies().map(::zipTree))
    from(resourceShrinkerDepsTask.outputs.files.map(::zipTree))
    from(consolidatedLicense)
    exclude("**/module-info.class")
    exclude("**/*.kotlin_metadata")
    exclude("META-INF/*.kotlin_module")
    exclude("META-INF/com.android.tools/**")
    exclude("META-INF/LICENSE*")
    exclude("META-INF/MANIFEST.MF")
    exclude("META-INF/maven/**")
    exclude("META-INF/proguard/**")
    exclude("META-INF/versions/**")
    exclude("META-INF/services/kotlin.reflect.**")
    exclude("**/*.xml")
    exclude("com/android/version.properties")
    exclude("NOTICE")
    exclude("README.md")
    exclude("javax/annotation/**")
    exclude("wireless/**")
    duplicatesStrategy = DuplicatesStrategy.EXCLUDE
    archiveFileName.set("deps.jar")
  }


val swissArmyKnifeWithoutLicense by registering(Zip::class) {
    dependsOn(swissArmyKnife)
    from(swissArmyKnife.get().outputs.files.map(::zipTree))
    exclude("LICENSE")
    archiveFileName.set("swiss-army-no-license.jar")
}

val r8WithRelocatedDeps by registering(Exec::class) {
    dependsOn(depsJar)
    dependsOn(swissArmyKnifeWithoutLicense)
    val swissArmy = swissArmyKnifeWithoutLicense.get().outputs.getFiles().getSingleFile()
    val deps = depsJar.get().outputs.files.getSingleFile()
    inputs.files(listOf(swissArmy, deps))
    val output = getRoot().resolveAll("build", "libs", "r8.jar")
    outputs.file(output)
    commandLine = baseCompilerCommandLine(
      swissArmy,
      deps,
      "relocator",
      listOf("--input",
             "$swissArmy",
             "--input",
             "$deps",
             "--output",
             "$output",
             // Add identity mapping to enforce no relocation of things already in package
             // com.android.tools.r8.
             "--map",
             "com.android.tools.r8.**->com.android.tools.r8",
             "--map",
             "com.android.**->com.android.tools.r8.com.android",
             "--map",
             "com.android.build.shrinker.**->com.android.tools.r8.resourceshrinker",
             "--map",
             "com.google.common.**->com.android.tools.r8.com.google.common",
             "--map",
             "com.google.gson.**->com.android.tools.r8.com.google.gson",
             "--map",
             "com.google.thirdparty.**->com.android.tools.r8.com.google.thirdparty",
             "--map",
             "org.objectweb.asm.**->com.android.tools.r8.org.objectweb.asm",
             "--map",
             "it.unimi.dsi.fastutil.**->com.android.tools.r8.it.unimi.dsi.fastutil",
             "--map",
             "kotlin.**->com.android.tools.r8.jetbrains.kotlin",
             "--map",
             "kotlinx.**->com.android.tools.r8.jetbrains.kotlinx",
             "--map",
             "org.jetbrains.**->com.android.tools.r8.org.jetbrains",
             "--map",
             "org.intellij.**->com.android.tools.r8.org.intellij",
             "--map",
             "org.checkerframework.**->com.android.tools.r8.org.checkerframework",
             "--map",
             "com.google.j2objc.**->com.android.tools.r8.com.google.j2objc",
             "--map",
             "com.google.protobuf.**->com.android.tools.r8.com.google.protobuf",
             "--map",
             "android.aapt.**->com.android.tools.r8.android.aaapt"
      ))
  }
}

tasks.withType<KotlinCompile> {
  enabled = false
}

tasks.withType<JavaCompile> {
  dependsOn(gradle.includedBuild("shared").task(":downloadDeps"))
  println("NOTE: Running with JDK: " + org.gradle.internal.jvm.Jvm.current().javaHome)

  // Enable error prone for D8/R8 main sources.
  options.errorprone.isEnabled.set(!project.hasProperty("disable_errorprone"))

  // Make all warnings errors. Warnings that we have chosen not to fix (or suppress) are disabled
  // outright below.
  options.compilerArgs.add("-Werror")

  // Increase number of reported errors to 1000 (default is 100).
  options.compilerArgs.add("-Xmaxerrs")
  options.compilerArgs.add("1000")

  // Non-default / Experimental checks - explicitly enforced.
  options.errorprone.error("RemoveUnusedImports")
  options.errorprone.error("InconsistentOverloads")
  options.errorprone.error("MissingDefault")
  options.errorprone.error("MultipleTopLevelClasses")
  options.errorprone.error("NarrowingCompoundAssignment")

  // Warnings that cause unwanted edits (e.g., inability to write informative asserts).
  options.errorprone.disable("AlreadyChecked")

  // JavaDoc related warnings. Would be nice to resolve but of no real consequence.
  options.errorprone.disable("InvalidLink")
  options.errorprone.disable("InvalidBlockTag")
  options.errorprone.disable("InvalidInlineTag")
  options.errorprone.disable("EmptyBlockTag")
  options.errorprone.disable("MissingSummary")
  options.errorprone.disable("UnrecognisedJavadocTag")
  options.errorprone.disable("AlmostJavadoc")

  // Moving away from identity and canonical items is not planned.
  options.errorprone.disable("IdentityHashMapUsage")
}
