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'
    
    // Enable parallel test execution for faster builds
    maxParallelForks = Runtime.runtime.availableProcessors().intdiv(2) ?: 1
}

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.1'
    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")
    def conllu2korapxmlExec = new File(binDir, "conllu2korapxml")
    outputs.file(targetExec)
    outputs.file(krillExec)
    outputs.file(conlluExec)
    outputs.file(conllu2korapxmlExec)

    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)
        }
        
        // Create conllu2korapxml symlink for CoNLL-U to KorAP XML ZIP conversion
        if (conllu2korapxmlExec.exists()) {
            conllu2korapxmlExec.delete()
        }
        try {
            java.nio.file.Files.createSymbolicLink(
                conllu2korapxmlExec.toPath(),
                java.nio.file.Paths.get("korapxmltool")
            )
            println "Created symlink: conllu2korapxml -> korapxmltool"
        } catch (Exception e) {
            println "Warning: Could not create conllu2korapxml symlink (${e.message}), copying instead"
            java.nio.file.Files.copy(targetExec.toPath(), conllu2korapxmlExec.toPath())
            conllu2korapxmlExec.setExecutable(true, false)
        }
    }
}

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

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


configurations {
    runtimeLib.extendsFrom implementation
}
