import com.google.devtools.ksp.configureKtfmt
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension
import org.jetbrains.kotlin.gradle.dsl.KotlinVersion

val sonatypeUserName: String? by project
val sonatypePassword: String? by project

// kspOnlyVersion is still used by CI to build 2.0.x releases.
if (extra.has("kspOnlyVersion") && !extra.has("kspVersion")) {
    val kspOnlyVersion = extra.get("kspOnlyVersion") as String
    extra.set("kspVersion", kspOnlyVersion)
}

if (!extra.has("kspVersion")) {
    extra.set("kspVersion", "255.255.255-SNAPSHOT")
}

repositories {
    maven("https://redirector.kotlinlang.org/maven/bootstrap/")
    mavenCentral()
}

plugins {
    kotlin("jvm")
    alias(libs.plugins.nexus.publish)
    // Adding plugins used in multiple places to the classpath for centralized version control
    alias(libs.plugins.shadow) apply false
    alias(libs.plugins.dokka) apply false
    alias(libs.plugins.android.lint) apply false
}

nexusPublishing {
    packageGroup.set("com.google.devtools.ksp")
    repositories {
        sonatype {
            username.set(sonatypeUserName)
            password.set(sonatypePassword)
            nexusUrl.set(uri("https://ossrh-staging-api.central.sonatype.com/service/local/"))
            snapshotRepositoryUrl.set(uri("https://central.sonatype.com/repository/maven-snapshots/"))
        }
    }
}

version = rootProject.extra.get("kspVersion") as String

subprojects {
    group = "com.google.devtools.ksp"
    version = rootProject.extra.get("kspVersion") as String
    configureKtfmt()
    repositories {
        google()
        maven("https://redirector.kotlinlang.org/maven/bootstrap/")
        maven("https://www.jetbrains.com/intellij-repository/releases")
        mavenCentral()
    }
    pluginManager.withPlugin("maven-publish") {
        val publishExtension = extensions.getByType<PublishingExtension>()
        publishExtension.repositories {
            if (extra.has("outRepo")) {
                val outRepo = extra.get("outRepo") as String
                maven {
                    url = File(outRepo).toURI()
                }
            } else {
                mavenLocal()
            }
            maven {
                name = "test"
                url = uri("${rootProject.layout.buildDirectory.get().asFile}/repos/test")
            }
        }
        publishExtension.publications.whenObjectAdded {
            check(this is MavenPublication) {
                "unexpected publication $this"
            }
            val publication = this
            publication.pom {
                url.set("https://goo.gle/ksp")
                licenses {
                    license {
                        name.set("The Apache License, Version 2.0")
                        url.set("http://www.apache.org/licenses/LICENSE-2.0.txt")
                    }
                }
                developers {
                    developer {
                        name.set("KSP Team")
                    }
                }
                scm {
                    connection.set("scm:git:https://github.com/google/ksp.git")
                    developerConnection.set("scm:git:https://github.com/google/ksp.git")
                    url.set("https://github.com/google/ksp")
                }
            }
        }
    }

    val compileJavaVersion = JavaLanguageVersion.of(17)

    pluginManager.withPlugin("org.jetbrains.kotlin.jvm") {
        configure<JavaPluginExtension> {
            toolchain.languageVersion.set(compileJavaVersion)
            sourceCompatibility = JavaVersion.VERSION_1_8
            targetCompatibility = JavaVersion.VERSION_1_8
        }
        configure<KotlinJvmProjectExtension> {
            compilerOptions {
                jvmTarget = JvmTarget.JVM_1_8
                languageVersion.set(KotlinVersion.KOTLIN_2_3)
                apiVersion.set(languageVersion)
            }
            jvmToolchain {
                languageVersion = compileJavaVersion
            }
        }
    }

    tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().configureEach {
        compilerOptions.freeCompilerArgs.add("-Xskip-prerelease-check")
    }

    tasks.withType<Jar>().configureEach {
        isPreserveFileTimestamps = false
        isReproducibleFileOrder = true
    }
}
