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

buildscript {
    project.ext.supportRootFolder = project.projectDir.getParentFile()
    repositories {
        maven {
            url "${supportRootFolder}/../../prebuilts/androidx/external"
        }
    }

    apply from: "build_dependencies.gradle"

    dependencies {
        classpath build_libs.kotlin.gradle_plugin
    }

    configurations.classpath.resolutionStrategy {
        eachDependency { details ->
            if (details.requested.group == 'org.jetbrains.kotlin') {
                details.useVersion build_versions.kotlin
            }
        }
    }
}

apply from: "out.gradle"
init.chooseOutDir()

ext.supportRootFolder = project.projectDir.getParentFile()
apply from: "local_dokka.gradle"
apply from: 'repos.gradle'
apply from: "build_dependencies.gradle"
apply plugin: "kotlin"
apply from: "kotlin-dsl-dependency.gradle"

allprojects {
    repos.addMavenRepositories(repositories)

    tasks.withType(KotlinCompile).configureEach {
        kotlinOptions {
            jvmTarget = "1.8"
            freeCompilerArgs += [
                    "-Werror",
                    "-Xskip-runtime-version-check",
                    "-Xskip-metadata-version-check",
                    // Allow `@OptIn` and `@UseExperimental`
                    "-Xopt-in=kotlin.RequiresOptIn"
            ]
        }
    }
}

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)
    }
    cacheableRuntime {
        extendsFrom(project.configurations.cacheableImplementation)
    }
}

dependencies {
    cacheableApi build_libs.agp
    cacheableImplementation build_libs.dex_member_list
    cacheableApi build_libs.kotlin.gradle_plugin
    cacheableImplementation build_libs.kotlinpoet
    cacheableImplementation gradleApi()
    cacheableApi build_libs.dokka_gradle
    // needed by inspection plugin
    cacheableImplementation "com.google.protobuf:protobuf-gradle-plugin:0.8.12"
    cacheableImplementation "org.anarres.jarjar:jarjar-gradle:1.0.1"
    // 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
    cacheableRuntime "com.google.dagger:hilt-android-gradle-plugin:DEV-SNAPSHOT"
    // 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
}



apply plugin: "java-gradle-plugin"

sourceSets {
    main.java.srcDirs += "${supportRootFolder}/benchmark/gradle-plugin/src/main/kotlin"
    main.resources.srcDirs += "${supportRootFolder}/benchmark/gradle-plugin/src/main/resources"

    main.java.srcDirs += "${supportRootFolder}/inspection/inspection-gradle-plugin/src/main/kotlin"
    main.resources.srcDirs += "${supportRootFolder}/inspection/inspection-gradle-plugin/src/main" +
            "/resources"

    main.java.srcDirs += "${supportRootFolder}/compose/material/material/icons/generator/src/main" +
            "/kotlin"
}

gradlePlugin {
    plugins {
        benchmark {
            id = 'androidx.benchmark'
            implementationClass = 'androidx.benchmark.gradle.BenchmarkPlugin'
        }
        inspection {
            id = 'androidx.inspection'
            implementationClass = 'androidx.inspection.gradle.InspectionPlugin'
        }
    }
}

// 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) {
    def savedText = savedFile.text
    def filenames = savedText.split("\n")
    def dependencies = filenames.collect { filename ->
        project.dependencies.create(project.files(filename))
    }
    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)
    if (!inputsFile.exists() || inputsFile.text != inputText) {
        cacheDir.mkdirs()
        saveConfigurationResolution(configuration, outputsFile)
        inputsFile.text = inputText
    }
    def result = parseConfigurationResolution(outputsFile)
    return result
}

// 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.cacheableRuntime, configurations.runtime)

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