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'

    // 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")
    outputs.file(targetExec)

    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

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

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

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


configurations {
    runtimeLib.extendsFrom implementation
}
