import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import com.google.devtools.ksp.RelativizingPathProvider
import java.io.ByteArrayOutputStream

description = "Kotlin Symbol Processing implementation using Kotlin Analysis API"

val signingKey: String? by project
val signingPassword: String? by project

val kotlinBaseVersion: String by project

val junitVersion: String by project
val junit5Version: String by project
val junitPlatformVersion: String by project
val libsForTesting: Configuration by configurations.creating
val libsForTestingCommon: Configuration by configurations.creating

val aaKotlinBaseVersion: String by project
val aaIntellijVersion: String by project
val aaGuavaVersion: String by project
val aaAsmVersion: String by project
val aaFastutilVersion: String by project
val aaStax2Version: String by project
val aaAaltoXmlVersion: String by project
val aaStreamexVersion: String by project
val aaCoroutinesVersion: String by project

plugins {
    kotlin("jvm")
    id("org.jetbrains.dokka")
    id("com.gradleup.shadow")
    `maven-publish`
    signing
}

val depSourceJars: Configuration by configurations.creating
val depJarsForCheck: Configuration by configurations.creating
val compilerJar: Configuration by configurations.creating

dependencies {
    listOf(
        "com.jetbrains.intellij.platform:util-rt",
        "com.jetbrains.intellij.platform:util-class-loader",
        "com.jetbrains.intellij.platform:util-text-matching",
        "com.jetbrains.intellij.platform:util",
        "com.jetbrains.intellij.platform:util-base",
        "com.jetbrains.intellij.platform:util-xml-dom",
        "com.jetbrains.intellij.platform:core",
        "com.jetbrains.intellij.platform:core-impl",
        "com.jetbrains.intellij.platform:extensions",
        "com.jetbrains.intellij.platform:diagnostic",
        "com.jetbrains.intellij.platform:diagnostic-telemetry",
        "com.jetbrains.intellij.java:java-frontback-psi",
        "com.jetbrains.intellij.java:java-frontback-psi-impl",
        "com.jetbrains.intellij.java:java-psi",
        "com.jetbrains.intellij.java:java-psi-impl",
    ).forEach {
        implementation("$it:$aaIntellijVersion") { isTransitive = false }
        depSourceJars("$it:$aaIntellijVersion:sources") { isTransitive = false }
    }

    listOf(
        "org.jetbrains.kotlin:analysis-api-k2-for-ide",
        "org.jetbrains.kotlin:analysis-api-for-ide",
        "org.jetbrains.kotlin:low-level-api-fir-for-ide",
        "org.jetbrains.kotlin:analysis-api-platform-interface-for-ide",
        "org.jetbrains.kotlin:symbol-light-classes-for-ide",
        "org.jetbrains.kotlin:analysis-api-standalone-for-ide",
        "org.jetbrains.kotlin:analysis-api-impl-base-for-ide",
        "org.jetbrains.kotlin:kotlin-compiler-common-for-ide",
        "org.jetbrains.kotlin:kotlin-compiler-fir-for-ide",
        "org.jetbrains.kotlin:kotlin-compiler-fe10-for-ide",
        "org.jetbrains.kotlin:kotlin-compiler-ir-for-ide",
    ).forEach {
        implementation("$it:$aaKotlinBaseVersion") { isTransitive = false }
        depSourceJars("$it:$aaKotlinBaseVersion:sources") { isTransitive = false }
    }

    implementation("org.jetbrains.kotlinx:kotlinx-collections-immutable-jvm:0.3.4")
    implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3")
    compileOnly(kotlin("stdlib", aaKotlinBaseVersion))

    implementation("com.google.guava:guava:$aaGuavaVersion")
    implementation("one.util:streamex:$aaStreamexVersion")
    implementation("org.jetbrains.intellij.deps:asm-all:$aaAsmVersion")
    implementation("org.codehaus.woodstox:stax2-api:$aaStax2Version") { isTransitive = false }
    implementation("com.fasterxml:aalto-xml:$aaAaltoXmlVersion") { isTransitive = false }
    implementation("com.github.ben-manes.caffeine:caffeine:2.9.3")
    implementation("org.jetbrains.intellij.deps.jna:jna:5.9.0.26") { isTransitive = false }
    implementation("org.jetbrains.intellij.deps.jna:jna-platform:5.9.0.26") { isTransitive = false }
    implementation("org.jetbrains.intellij.deps:trove4j:1.0.20200330") { isTransitive = false }
    implementation("org.jetbrains.intellij.deps:log4j:1.2.17.2") { isTransitive = false }
    implementation("org.jetbrains.intellij.deps:jdom:2.0.6") { isTransitive = false }
    implementation("io.javaslang:javaslang:2.0.6")
    implementation("javax.inject:javax.inject:1")
    implementation("org.jetbrains.kotlin:kotlin-reflect:1.6.10")
    implementation("org.lz4:lz4-java:1.7.1") { isTransitive = false }
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:$aaCoroutinesVersion") { isTransitive = false }
    implementation(
        "org.jetbrains.intellij.deps.fastutil:intellij-deps-fastutil:$aaFastutilVersion"
    ) {
        isTransitive = false
    }
    implementation("org.jetbrains:annotations:24.1.0")

    implementation("io.opentelemetry:opentelemetry-api:1.34.1") { isTransitive = false }

    compileOnly(project(":common-deps"))

    implementation(project(":api"))
    implementation(project(":common-util"))

    testImplementation(kotlin("stdlib", aaKotlinBaseVersion))
    testImplementation("junit:junit:$junitVersion")
    testImplementation("org.junit.jupiter:junit-jupiter-api:$junit5Version")
    testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:$junit5Version")
    testRuntimeOnly("org.junit.jupiter:junit-jupiter-params:$junit5Version")
    testRuntimeOnly("org.junit.platform:junit-platform-suite:$junitPlatformVersion")
    testImplementation("org.jetbrains.kotlin:kotlin-compiler:$aaKotlinBaseVersion")
    testImplementation("org.jetbrains.kotlin:kotlin-compiler-internal-test-framework:$aaKotlinBaseVersion")
    testImplementation(project(":common-deps"))
    testImplementation(project(":test-utils"))
    testImplementation("org.jetbrains.kotlin:analysis-api-test-framework:$aaKotlinBaseVersion")

    libsForTesting(kotlin("stdlib", aaKotlinBaseVersion))
    libsForTesting(kotlin("test", aaKotlinBaseVersion))
    libsForTesting(kotlin("script-runtime", aaKotlinBaseVersion))
    libsForTestingCommon(kotlin("stdlib-common", aaKotlinBaseVersion))

    depJarsForCheck("org.jetbrains.kotlin", "kotlin-stdlib", kotlinBaseVersion)
    depJarsForCheck(project(":api"))
    depJarsForCheck(project(":common-deps"))

    compilerJar("org.jetbrains.kotlin:kotlin-compiler-common-for-ide:$aaKotlinBaseVersion")
}

sourceSets.main {
    java.srcDirs("src/main/kotlin")
}

fun Project.javaPluginExtension(): JavaPluginExtension = the()
val JavaPluginExtension.testSourceSet: SourceSet
    get() = sourceSets.getByName("test")
val Project.testSourceSet: SourceSet
    get() = javaPluginExtension().testSourceSet

repositories {
    flatDir {
        dirs("${project.rootDir}/third_party/prebuilt/repo/")
    }
    maven("https://redirector.kotlinlang.org/maven/kotlin-ide-plugin-dependencies")
    maven("https://packages.jetbrains.team/maven/p/ij/intellij-dependencies")
}

tasks.withType<org.gradle.jvm.tasks.Jar> {
    archiveClassifier.set("real")
}

tasks.withType<ShadowJar>().configureEach {
    dependencies {
        exclude(project(":api"))
    }
    exclude("kotlin/**")
    exclude("kotlinx/coroutines/**")
    archiveClassifier.set("")
    minimize {
        exclude(dependency("org.lz4:lz4-java:.*"))
        exclude(dependency("com.github.ben-manes.caffeine:caffeine:.*"))
    }
    mergeServiceFiles()
}

abstract class ValidateShadowJar : DefaultTask() {
    @get:Inject abstract val execOperations: ExecOperations

    @get:InputFile abstract val inputFile: RegularFileProperty

    @get:InputFiles abstract val classpath: ConfigurableFileCollection

    @get:InputFile abstract val baselineFile: RegularFileProperty

    @get:OutputFile abstract val outputFile: RegularFileProperty

    @TaskAction
    fun validate() {
        val jarJar = inputFile.get().asFile
        val depJars = classpath.files
        val stdout = ByteArrayOutputStream()
        try {
            execOperations.exec {
                executable = "jdeps"
                args = listOf(
                    "--multi-release", "base",
                    "--missing-deps",
                    "-cp", depJars.joinToString(File.pathSeparator), jarJar.path
                )
                standardOutput = stdout
            }
        } catch (e: org.gradle.process.internal.ExecException) {
            throw Exception("Unable to run jdeps")
        }
        val actualOutput = stdout.toString()
        outputFile.get().asFile.writeText(actualOutput)
        val expectedOutput = baselineFile.get().asFile.readText()
        if (actualOutput != expectedOutput) {
            throw Exception(
                """
                jdeps missing dependencies output has changed.
                Compare expected ${baselineFile.get().asFile.absolutePath} with
                actual ${outputFile.get().asFile.absolutePath}.
                """.trimIndent()
            )
        }
    }
}

val validateShadowJar = tasks.register<ValidateShadowJar>("validateShadowJar") {
    inputFile.set(tasks.shadowJar.flatMap { it.archiveFile })
    classpath.from(depJarsForCheck.incoming.artifactView { }.files)
    baselineFile.set(layout.projectDirectory.file("shadow-validation-baseline.txt"))
    outputFile.set(layout.buildDirectory.file("validateShadowJar.txt"))
}

tasks.named("check").configure {
    dependsOn(validateShadowJar)
}

val sourcesJar = tasks.register<Jar>("sourcesJar") {
    duplicatesStrategy = DuplicatesStrategy.EXCLUDE
    archiveClassifier.set("sources")
    from(sourceSets.main.map { it.allSource })
    from(project(":common-util").sourceSets.main.get().allSource)
    depSourceJars.resolve().forEach {
        from(zipTree(it))
    }
}
val dokkaJavadocJar = tasks.register<Jar>("dokkaJavadocJar") {
    archiveClassifier.set("javadoc")
    from(tasks.dokkaJavadoc.flatMap { it.outputDirectory })
}

publishing {
    publications {
        create<MavenPublication>("shadow") {
            artifactId = "symbol-processing-aa"
            artifact(tasks.shadowJar)
            artifact(dokkaJavadocJar)
            artifact(sourcesJar)
            pom {
                name.set("com.google.devtools.ksp:symbol-processing-aa")
                description.set("KSP implementation on Kotlin Analysis API")
                withXml {
                    fun groovy.util.Node.addDependency(
                        groupId: String,
                        artifactId: String,
                        version: String,
                        scope: String = "runtime"
                    ) {
                        appendNode("dependency").apply {
                            appendNode("groupId", groupId)
                            appendNode("artifactId", artifactId)
                            appendNode("version", version)
                            appendNode("scope", scope)
                        }
                    }

                    asNode().appendNode("dependencies").apply {
                        addDependency("org.jetbrains.kotlin", "kotlin-stdlib", kotlinBaseVersion)
                        addDependency("org.jetbrains.kotlinx", "kotlinx-coroutines-core-jvm", aaCoroutinesVersion)
                        addDependency("com.google.devtools.ksp", "symbol-processing-api", version)
                        addDependency("com.google.devtools.ksp", "symbol-processing-common-deps", version)
                    }
                }
            }
        }
    }
}

signing {
    isRequired = hasProperty("signingKey")
    useInMemoryPgpKeys(signingKey, signingPassword)
    sign(extensions.getByType<PublishingExtension>().publications)
}

kotlin {
    compilerOptions {
        freeCompilerArgs.add("-Xcontext-receivers")
    }
}

val copyLibsForTesting = tasks.register<Copy>("copyLibsForTesting") {
    from(configurations["libsForTesting"])
    into("dist/kotlinc/lib")
    val escaped = Regex.escape(aaKotlinBaseVersion)
    rename("(.+)-$escaped\\.jar", "$1.jar")
}

val copyLibsForTestingCommon = tasks.register<Copy>("copyLibsForTestingCommon") {
    from(configurations["libsForTestingCommon"])
    into("dist/common")
    val escaped = Regex.escape(aaKotlinBaseVersion)
    rename("(.+)-$escaped\\.jar", "$1.jar")
}

tasks.test {
    dependsOn(copyLibsForTesting)
    dependsOn(copyLibsForTestingCommon)
    maxHeapSize = "2g"

    useJUnitPlatform()

    systemProperty("idea.is.unit.test", "true")
    systemProperty("java.awt.headless", "true")
    environment("NO_FS_ROOTS_ACCESS_CHECK", "true")

    testLogging {
        events("passed", "skipped", "failed")
    }

    val ideaHomeDir = layout.buildDirectory.dir("tmp/ideaHome")
        .get()
        .asFile
        .apply { if (!exists()) mkdirs() }
    jvmArgumentProviders.add(RelativizingPathProvider("idea.home.path", ideaHomeDir))
    jvmArgumentProviders.add(RelativizingPathProvider("java.io.tmpdir", temporaryDir))
}
