// 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.ByteArrayOutputStream
import java.nio.charset.Charset
import javax.inject.Inject
import org.gradle.api.provider.Provider
import org.gradle.api.provider.ValueSource
import org.gradle.api.provider.ValueSourceParameters
import org.gradle.process.ExecOperations

plugins {
  `java-library`
  id("dependencies-plugin")
  id("net.ltgt.errorprone")
}

// Properties that you can set in your ~/.gradle/gradle.properties:

// Use a separate sourceSet for files that have been modified when doing incremental builds.
// Speeds up compile times where the list of files isn't changed from 1-2 minutes -> 1-2 seconds.
//
// Modified files are determined using git, and the list of modified files never shrinks (since
// that would cause build errors). However, it is safe to fully reset the list of modified files,
// which you can do by deleting d8_r8/main/build/turbo-paths.txt.
//
// What's the catch?
// Unmodified sources that depend on modified ones will *not be rebuilt* when modified sources
// change. This is where the speed-up comes from, but can lead to runtime crashes if signatures
// change without references to them being updated.
// Be sure to fix problems reported by IntelliJ when using this mode.
val isGeminiCli = "1".equals(System.getenv("GEMINI_CLI"))
var enableTurboBuilds = project.hasProperty("enable_r8_turbo_builds") && !isGeminiCli

val MAIN_JAVA_PATH_PREFIX = "src/main/java/"

interface TurboPathsValueSourceParameters : ValueSourceParameters {
  val pathPrefix: Property<String>
  val turboPathsFile: Property<File>
  val extraGlobs: ListProperty<String>
  val mainOutputDir: Property<File>
}

enum class TurboReason {
  FIRST_BUILD,
  PATHS_CHANGED,
  PATHS_UNCHANGED,
  CORRUPT_FILE,
  TOO_MANY_PATHS,
}

data class TurboState(val paths: List<String>, val reason: TurboReason)

abstract class TurboPathsValueSource : ValueSource<TurboState, TurboPathsValueSourceParameters> {
  @get:Inject abstract val execOperations: ExecOperations

  fun isDirectoryEmpty(path: File): Boolean {
    if (!path.exists()) {
      return true
    }

    val files = path.listFiles()
    return files == null || files.isEmpty()
  }

  override fun obtain(): TurboState? {
    val prefix = parameters.pathPrefix.get()
    val turboPathsFile = parameters.turboPathsFile.get()
    val extraGlobs = parameters.extraGlobs.get()
    val mainOutputDir = parameters.mainOutputDir.get()

    // Check for first build (since the turbo sourceSet requires the main one
    // to have been built already).
    if (isDirectoryEmpty(mainOutputDir)) {
      return TurboState(listOf(), TurboReason.FIRST_BUILD)
    }

    var mergeBase = "origin/main"
    val pathSet: MutableSet<String> = mutableSetOf()

    if (turboPathsFile.exists()) {
      val lines = turboPathsFile.readLines()
      if (!lines.isEmpty() && lines[0].startsWith("mergebase=")) {
        mergeBase = lines[0].removePrefix("mergebase=")
        pathSet.addAll(lines.drop(1))
      } else {
        // Corrupt file.
        turboPathsFile.delete()
        return TurboState(listOf(), TurboReason.CORRUPT_FILE)
      }
    }

    val prevNumSource = pathSet.size
    val output = ByteArrayOutputStream()
    execOperations.exec {
      commandLine = listOf("git", "diff", "--name-only", "--merge-base", mergeBase)
      standardOutput = output
    }
    val result = String(output.toByteArray(), Charset.defaultCharset())
    val gitPaths =
      result
        .lines()
        .filter { it.startsWith(prefix) && it.endsWith(".java") }
        .map { it.trim().removePrefix(prefix) }
    pathSet.addAll(gitPaths)

    val ret = pathSet.toMutableList()
    ret.sort()
    // Allow users to specify extra globs.
    ret += extraGlobs

    if (mergeBase == "origin/main") {
      output.reset()
      execOperations.exec {
        commandLine = listOf("git", "rev-parse", "origin/main")
        standardOutput = output
      }
      mergeBase = String(output.toByteArray(), Charset.defaultCharset()).trim()
    }

    if (pathSet.size > 200 && gitPaths.size < 40) {
      // File has gotten too big. Start fresh.
      turboPathsFile.delete()
      return TurboState(listOf(), TurboReason.TOO_MANY_PATHS)
    }

    turboPathsFile.writeText("mergebase=$mergeBase\n" + ret.joinToString("\n"))
    val changed = prevNumSource != pathSet.size
    val reason =
      if (pathSet.isEmpty()) TurboReason.FIRST_BUILD
      else if (changed) TurboReason.PATHS_CHANGED else TurboReason.PATHS_UNCHANGED
    return TurboState(ret, reason)
  }
}

val turboPathsProvider: Provider<TurboState> =
  providers.of(TurboPathsValueSource::class.java) {
    parameters.pathPrefix.set(MAIN_JAVA_PATH_PREFIX)

    // Wipe this file to remove files from the active set.
    parameters.turboPathsFile.set(layout.buildDirectory.file("turbo-paths.txt").get().asFile)

    parameters.extraGlobs.set(
      project.findProperty("turbo_build_globs")?.toString()?.split(',') ?: emptyList()
    )

    parameters.mainOutputDir.set(sourceSets["main"].java.destinationDirectory.get().getAsFile())
  }

// Add all changed files to the "turbo" source set.
val turboState = if (enableTurboBuilds) turboPathsProvider.get() else null

if (turboState != null) {
  val numFiles = turboState.paths.size
  val msg =
    when (turboState.reason) {
      TurboReason.FIRST_BUILD -> "First build detected. Build will be slow."
      TurboReason.PATHS_CHANGED -> "Paths in active set have changed. Build will be slow."
      TurboReason.PATHS_UNCHANGED -> "Paths unchanged. Size=$numFiles. Build should be fast!"
      TurboReason.CORRUPT_FILE -> "turbo-paths.txt was invalid. Build will be slow."
      TurboReason.TOO_MANY_PATHS -> "Paths were compacted. Build will be slow."
    }
  logger.warn("Turbo: $msg")
} else if (isGeminiCli) {
  logger.warn("Turbo: enable_r8_turbo_builds=false (gemini-cli detected)")
} else {
  logger.warn("Turbo: enable_r8_turbo_builds=false")
}

java {
  sourceSets {
    val srcDir = getRoot().resolveAll("src", "main", "java")

    main {
      resources.srcDirs(getRoot().resolveAll("third_party", "api_database", "api_database"))
      java {
        srcDir(srcDir)
        if (turboState != null && !turboState.paths.isEmpty()) {
          exclude(turboState.paths)
        }
      }
    }

    // Must be created unconditionally so that other targets can depend on it.
    create("turbo") {
      java {
        srcDir(srcDir)
        if (turboState != null && !turboState.paths.isEmpty()) {
          include(turboState.paths)
        } else {
          exclude("*")
        }
      }
    }
  }

  sourceCompatibility = JvmCompatibility.sourceCompatibility
  targetCompatibility = JvmCompatibility.targetCompatibility
  toolchain { languageVersion = JavaLanguageVersion.of(JvmCompatibility.release) }
  withSourcesJar()
}

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

dependencies { sharedDepsScope(project(":shared", "sharedDepsFiles")) }

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

val internalJarScope by configurations.dependencyScope("internalJarScope")
val internalJarResolvable by
  configurations.resolvable("internalJarResolvable") { extendsFrom(internalJarScope) }
val internalClassesScope by configurations.dependencyScope("internalClassesScope")
val internalClassesResolvable by
  configurations.resolvable("internalClassesResolvable") { extendsFrom(internalClassesScope) }

dependencies {
  internalJarScope(project(":utils", "isolatedJar"))
  internalClassesScope(project(":utils", "isolatedClasses"))
  implementation(project(":assistant", "assistantJar"))
  implementation(project(":keepradius", "keepradiusJar"))
  implementation(project(":keepanno", "keepannoClasses"))
  implementation(project(":resourceshrinker", "resourceshrinkerJar"))
  implementation(project(":utils"))
  Deps.compilerDeps.forEach { compileOnly(it) }
  errorprone(Deps.errorprone)
}

if (enableTurboBuilds) {
  tasks.named("compileJava") {
    // Makes compileTurboJava run first, but does not cause compileJava to re-run if
    // compileTurboJava changes.
    dependsOn(tasks.named("compileTurboJava"))
  }

  // Does not include main's output directory, which must also be added when compilation avoidance
  // causes only a subset of sources to be recompiled.
  val mainClasspath = sourceSets["main"].compileClasspath.getAsPath()

  tasks.named<JavaCompile>("compileTurboJava") {
    // Add the main's classes to the classpath without letting gradle know about this dependency
    // (as it's a circular one).
    options.compilerArgs.add("-classpath")
    options.compilerArgs.add(
      "" +
        sourceSets["turbo"].java.destinationDirectory.get() +
        File.pathSeparator +
        mainClasspath +
        File.pathSeparator +
        sourceSets["main"].java.destinationDirectory.get()
    )
  }

  tasks.named<JavaCompile>("compileJava") {
    // Add the turbo's classes to the classpath without letting gradle know about this dependency
    // (or else it will cause it to rebuild whenever files in it change).
    options.compilerArgs.add("-classpath")
    options.compilerArgs.add(
      "" +
        sourceSets["main"].java.destinationDirectory.get() +
        File.pathSeparator +
        mainClasspath +
        File.pathSeparator +
        sourceSets["turbo"].java.destinationDirectory.get()
    )
  }
}

tasks {
  jar {
    from(sourceSets["turbo"].output)
    doLast {
      enforceUncompressedEntries(archiveFile.get().asFile, setOf("resources/new_api_database.ser"))
    }
  }

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

tasks.withType<JavaCompile> {
  dependsOn(sharedDepsConfig)
  logger.info("NOTE: Running with JDK: " + org.gradle.internal.jvm.Jvm.current().javaHome)
}

tasks.named("sourcesJar") { dependsOn(sharedDepsConfig) }

tasks.withType<ProcessResources> { dependsOn(sharedDepsConfig) }

// Contains both :main jar and :utils jar but not third party dependencies.
val mainJar by configurations.consumable("mainJar") { extendsFrom(internalJarResolvable) }
// Contains partial class files of :main and all class files of :utils but not third party
// dependencies.
val mainClassesOutput by
  configurations.consumable("mainClassesOutput") { extendsFrom(internalClassesResolvable) }
// Contains partial class files of :main but not :utils nor third party dependencies.
val turboClassesOutput by configurations.consumable("turboClassesOutput")
val mainResources by configurations.consumable("mainResources")
val mainSources by configurations.consumable("mainSources")

artifacts {
  add(mainJar.name, tasks.named("jar"))
  add(
    mainClassesOutput.name,
    tasks.named<JavaCompile>("compileJava").map { it.destinationDirectory },
  )
  add(
    turboClassesOutput.name,
    tasks.named<JavaCompile>("compileTurboJava").map { it.destinationDirectory },
  )
  add(
    mainResources.name,
    tasks.named<ProcessResources>("processResources").map { it.destinationDir },
  )
  add(mainSources.name, tasks.named("sourcesJar"))
}

configureErrorProneForJavaCompile()
