import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

apply plugin: "kotlin"
apply from: "../kotlin-dsl-dependency.gradle"

buildscript {
    project.ext.supportRootFolder = project.projectDir.getParentFile().getParentFile()
    apply from: "../repos.gradle"
    repos.addMavenRepositories(repositories)
    dependencies {
        classpath(libs.kotlinGradlePluginz)
    }
}

configurations {
    // Dependencies added to these configurations get copied into the corresponding configuration
    // (cacheableApi gets copied into api, etc).
    // Because we cache the resolutions of these configurations, performance is faster when
    // artifacts are put into these configurations than when those artifacts are put into their
    // corresponding configuration.
    cacheableApi
    cacheableImplementation {
        extendsFrom(project.configurations.cacheableApi)
    }
    cacheableRuntimeOnly
}

dependencies {
    cacheableApi(libs.toml)
    cacheableImplementation(libs.gson)
    cacheableImplementation(libs.dom4j) {
        // Optional dependency where Ivy fails to parse the POM file.
        exclude(group:"net.java.dev.msv", module:"xsdlib")
    }
    cacheableApi(libs.androidGradlePluginz)
    cacheableImplementation(libs.dexMemberList)
    cacheableApi(libs.kotlinGradlePluginz)
    cacheableImplementation(gradleApi())
    cacheableApi(libs.dokkaGradlePluginz)
    // needed by inspection plugin
    cacheableImplementation(libs.protobufGradlePluginz)
    cacheableImplementation(libs.wireGradlePluginz)
    cacheableImplementation(libs.shadow)
    // dependencies that aren't used by buildSrc directly but that we resolve here so that the
    // root project doesn't need to re-resolve them and their dependencies on every build
    cacheableRuntimeOnly(libs.hiltAndroidGradlePluginz)
    // room kotlintestapp uses the ksp plugin but it does not publish a plugin marker yet
    cacheableApi(libs.kspGradlePluginz)
    cacheableApi(libs.japicmpPluginz)
    // dependencies whose resolutions we don't need to cache
    compileOnly(findGradleKotlinDsl()) // Only one file in this configuration, no need to cache it
    implementation(project(":jetpad-integration")) // Doesn't have a .pom, so not slow to load
}

// Exclude dokka coming from AGP. We don't need it and it conflicts with dackka: b/195305339
configurations.configureEach { conf ->
  conf.exclude(group:"org.jetbrains.dokka", module:"dokka-core")
}

// Saves configuration into destFile
// Each line of destFile will be the absolute filepath of one of the files in configuration
def saveConfigurationResolution(configuration, destFile) {
    def resolvedConfiguration = configuration.resolvedConfiguration
    def files = resolvedConfiguration.files
    def paths = files.collect { f -> f.toString() }
    def serialized = paths.join("\n")
    destFile.text = serialized
}

// Parses a file into a list of Dependency objects representing a ResolvedConfiguration
def parseConfigurationResolution(savedFile, throwOnError) {
    def savedText = savedFile.text
    def filenames = savedText.split("\n")
    def valid = true
    def dependencies = filenames.collect { filename ->
        if (!project.file(filename).exists()) {
            if (throwOnError) {
                throw new GradleException("\nFile " + filename + " listed as a resolved dependency in " + savedFile + " does not exist!\n\nFor more information, see b/187075069")
            } else {
                valid = false
            }
        }
        project.dependencies.create(project.files(filename))
    }
    if (!valid) {
        return null
    }
    return dependencies
}

// Resolves a Configuration into a list of Dependency objects
def resolveConfiguration(configuration) {
    def resolvedName = configuration.name
    def cacheDir = new File(project.buildDir, "/" + resolvedName)
    def inputsFile = new File(cacheDir, "/deps")
    def outputsFile = new File(cacheDir, "/result")

    def inputText = fingerprintConfiguration(configuration)
    def parsed = null
    if (inputsFile.exists() && inputsFile.text == inputText) {
        // Try to parse the previously resolved configuration, but don't give up if it mentions a
        // nonexistent file. If something has since deleted one of the referenced files, we will
        // try to reresolve that file later
        parsed = parseConfigurationResolution(outputsFile, false)
    }
    // If the configuration has changed or if any of its files have been deleted, reresolve it
    if (parsed == null) {
        cacheDir.mkdirs()
        saveConfigurationResolution(configuration, outputsFile)
        inputsFile.text = inputText
        // confirm that the resolved configuration parses successfully
        parsed = parseConfigurationResolution(outputsFile, true)
    }
    return parsed
}

// Computes a unique string from a Configuration based on its dependencies
// This is used for up-to-date checks
def fingerprintConfiguration(configuration) {
    def dependencies = configuration.allDependencies
    def dependencyTexts = dependencies.collect { dep -> dep.group + ":" + dep.name + ":" + dep.version }
    return dependencyTexts.join("\n")
}

// Imports the contents of fromConf into toConf
// Uses caching to often short-circuit the resolution of fromConf
def loadConfigurationQuicklyInto(fromConf, toConf) {
    def resolved = resolveConfiguration(fromConf)
    resolved.each { dep ->
        project.dependencies.add(toConf.name, dep)
    }
}

loadConfigurationQuicklyInto(configurations.cacheableApi, configurations.api)
loadConfigurationQuicklyInto(configurations.cacheableImplementation, configurations.implementation)
loadConfigurationQuicklyInto(configurations.cacheableRuntimeOnly, configurations.runtimeOnly)

project.tasks.withType(Jar) { task ->
    task.reproducibleFileOrder = true
    task.preserveFileTimestamps = false
}
