plugins {
    // Apply the org.jetbrains.kotlin.jvm Plugin to add support for Kotlin.
    id 'org.jetbrains.kotlin.jvm' version '2.2.21'

    // Apply the application plugin to add support for building a CLI application in Java.
    id 'application'
    id 'com.github.johnrengelman.shadow' version '8.1.1'
}

repositories {
    mavenCentral()
    maven { url 'https://jitpack.io' }
}

test {
    minHeapSize = "512m"
    maxHeapSize = "4096m"
    jvmArgs '-XX:MaxMetaspaceSize=1024m'
}

dependencies {
    // Align versions of all Kotlin components
    implementation platform('org.jetbrains.kotlin:kotlin-bom')

    // Use the Kotlin JDK 8 standard library.
    implementation 'org.jetbrains.kotlin:kotlin-stdlib'
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2'

    // This dependency is used by the application.
    implementation 'com.google.guava:guava:33.5.0-jre'


    implementation ("info.picocli:picocli:4.7.7")

    // Use the Kotlin test library.
    testImplementation 'org.jetbrains.kotlin:kotlin-test'

    // Use the Kotlin JUnit integration.
    testImplementation 'org.jetbrains.kotlin:kotlin-test-junit'
    testImplementation "org.jetbrains.kotlin:kotlin-test:2.2.21"

    implementation 'com.github.kupietz:cistern:v1.0.4'
    implementation 'org.maltparser:maltparser:1.9.2'
    implementation 'org.apache.opennlp:opennlp-tools:2.5.6'
    implementation 'edu.stanford.nlp:stanford-corenlp:3.9.2'
    implementation 'org.slf4j:slf4j-simple:2.0.17'
    implementation 'org.apache.ant:ant:1.10.15'
    implementation 'org.apache.commons:commons-compress:1.28.0'
    implementation 'me.tongfei:progressbar:0.10.1'
    implementation 'org.lz4:lz4-java:1.8.0'

    // Fix XML APIs conflict - force resolution to the non-relocated version
    implementation('xml-apis:xml-apis:1.0.b2') {
        because 'Avoid POM relocation warnings from xml-apis 2.0.2 -> 1.0.b2'
    }
}

// Enforce JDK 21 Toolchain and Bytecode-Level 21
java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(21)
    }
}

kotlin {
    jvmToolchain(21)
}

// For any existing Java source code
tasks.withType(JavaCompile).configureEach {
    options.release = 21
}

tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach {
    kotlinOptions {
        jvmTarget = "21"
        // If available, this ensures consistent API targets similar to Java --release
        // freeCompilerArgs += ["-Xjdk-release=21"]
    }
}

// Explicitly inherit version from root project
version = rootProject.version

application {
    // Define the main class for the application.
    mainClass = 'de.ids_mannheim.korapxmltools.KorapXmlToolKt'
}

jar {
    // Mark standard JAR as "plain" to avoid conflicts with ShadowJar
    archiveClassifier.set('plain')
    manifest.attributes(
            'Class-Path': configurations.compileClasspath.collect { it.getName() }.join(' '),
            'Main-Class': "de.ids_mannheim.korapxmltools.KorapXmlToolKt",
            'Implementation-Title': rootProject.name,
            'Implementation-Version': project.version
    )
}

shadowJar {
    archiveBaseName.set('korapxmltool')
    archiveClassifier.set('')
    archiveVersion.set(project.version.toString())
    manifest.attributes(
        'Main-Class': "de.ids_mannheim.korapxmltools.KorapXmlToolKt",
        'Implementation-Title': rootProject.name,
        'Implementation-Version': project.version
    )
}

// Ensure that assemble also creates the ShadowJar
tasks.named('assemble') {
    dependsOn tasks.named('shadowJar')
}

// Additionally create a symlink korapxmltool.jar to the current version for stable script paths
tasks.register('createJarSymlink') {
    dependsOn shadowJar
    doLast {
        def targetJar = shadowJar.archiveFile.get().asFile
        def linkFile = new File(targetJar.parent, 'korapxmltool.jar')

        // Remove existing symlink or file
        if (linkFile.exists()) {
            linkFile.delete()
        }

        // Create symlink (Java 7+ NIO)
        try {
            java.nio.file.Files.createSymbolicLink(
                linkFile.toPath(),
                java.nio.file.Paths.get(targetJar.name)
            )
            println "Created symlink: ${linkFile.name} -> ${targetJar.name}"
        } catch (Exception e) {
            // Fallback to copy on systems where symlinks aren't supported
            println "Warning: Could not create symlink (${e.message}), copying instead"
            java.nio.file.Files.copy(targetJar.toPath(), linkFile.toPath())
        }
    }
}

// Concatenate shebang + shaded jar into an executable launcher
tasks.register('assembleShebangExecutable') {
    dependsOn shadowJar
    inputs.file(rootProject.file("korapxmltool.shebang"))
    inputs.file(shadowJar.archiveFile)
    
    def binDir = rootProject.file("build/bin")
    def targetExec = new File(binDir, "korapxmltool")
    def krillExec = new File(binDir, "korapxml2krill")
    def conlluExec = new File(binDir, "korapxml2conllu")
    outputs.file(targetExec)
    outputs.file(krillExec)
    outputs.file(conlluExec)

    doLast {
        def shebang = rootProject.file("korapxmltool.shebang")
        if (!shebang.exists()) {
            throw new GradleException("Missing shebang stub: ${shebang}")
        }

        // Ensure bin directory exists
        binDir.mkdirs()

        def targetJar = shadowJar.archiveFile.get().asFile

        // Create main korapxmltool executable
        targetExec.withOutputStream { os ->
            os << shebang.bytes
            os << targetJar.bytes
        }
        targetExec.setExecutable(true, false)
        println "Created executable launcher: ${targetExec}"

        // Create korapxml2krill symlink for backward compatibility
        if (krillExec.exists()) {
            krillExec.delete()
        }
        try {
            java.nio.file.Files.createSymbolicLink(
                krillExec.toPath(),
                java.nio.file.Paths.get("korapxmltool")
            )
            println "Created symlink: korapxml2krill -> korapxmltool"
        } catch (Exception e) {
            println "Warning: Could not create korapxml2krill symlink (${e.message}), copying instead"
            java.nio.file.Files.copy(targetExec.toPath(), krillExec.toPath())
            krillExec.setExecutable(true, false)
        }
        
        // Create korapxml2conllu symlink for backward compatibility
        if (conlluExec.exists()) {
            conlluExec.delete()
        }
        try {
            java.nio.file.Files.createSymbolicLink(
                conlluExec.toPath(),
                java.nio.file.Paths.get("korapxmltool")
            )
            println "Created symlink: korapxml2conllu -> korapxmltool"
        } catch (Exception e) {
            println "Warning: Could not create korapxml2conllu symlink (${e.message}), copying instead"
            java.nio.file.Files.copy(targetExec.toPath(), conlluExec.toPath())
            conlluExec.setExecutable(true, false)
        }
    }
}

tasks.named('assemble') {
    dependsOn createJarSymlink
    dependsOn assembleShebangExecutable
}

tasks.named('build') {
    dependsOn createJarSymlink
    dependsOn assembleShebangExecutable
}


configurations {
    runtimeLib.extendsFrom implementation
}
