import java.security.MessageDigest
import org.gradle.api.DefaultTask
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.provider.MapProperty
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.TaskAction

abstract class VerifyMapsforgePluginsTask : DefaultTask() {
    @get:InputFiles
    @get:PathSensitive(PathSensitivity.RELATIVE)
    abstract val artifacts: ConfigurableFileCollection

    @get:Input
    abstract val expectedHashes: MapProperty<String, String>

    @TaskAction
    fun verify() {
        val expected = expectedHashes.get()
        artifacts.files.forEach { artifact ->
            check(artifact.isFile) {
                "Mapsforge-Plugin fehlt: ${artifact.absolutePath}. " +
                    "Bitte zuerst scripts/bootstrap-dependencies.ps1 ausführen."
            }
            val digest = MessageDigest.getInstance("SHA-256")
            val actualHash = artifact.inputStream().use { input ->
                val buffer = ByteArray(DEFAULT_BUFFER_SIZE)
                while (true) {
                    val count = input.read(buffer)
                    if (count < 0) break
                    digest.update(buffer, 0, count)
                }
                digest.digest().joinToString("") { "%02x".format(it) }
            }
            check(actualHash == expected.getValue(artifact.name)) {
                "Falsche SHA-256-Prüfsumme für ${artifact.name}."
            }
        }
    }
}

plugins {
    kotlin("jvm")
    application
}

// The shipped Mapsforge writer files are fat JARs. This resolvable, non-consumable
// configuration exposes their published dependency metadata to SBOM/update tooling
// without adding duplicate classes to the packaged runtime.
val bundledRuntimeMetadata = configurations.create("bundledRuntimeMetadata") {
    isCanBeConsumed = false
    isCanBeResolved = true
}

kotlin {
    jvmToolchain(25)
}

dependencies {
    implementation(project(":core"))
    implementation("org.openstreetmap.osmosis:osmosis-core:0.49.2")
    implementation("org.openstreetmap.osmosis:osmosis-pbf:0.49.2")
    implementation("org.openstreetmap.osmosis:osmosis-areafilter:0.49.2")
    implementation("org.openstreetmap.osmosis:osmosis-set:0.49.2")
    implementation("org.openstreetmap.pbf:osmpbf:1.6.1")
    runtimeOnly(files("libs/mapsforge-map-writer-0.29.0-jar-with-dependencies.jar"))
    runtimeOnly(files("libs/mapsforge-poi-writer-0.29.0-jar-with-dependencies.jar"))
    // Exact coordinates embedded in the official 0.29.0 writer fat JARs.
    bundledRuntimeMetadata("com.google.guava:guava:33.0.0-jre")
    bundledRuntimeMetadata("org.locationtech.jts:jts-core:1.20.0")
    bundledRuntimeMetadata("org.glassfish.jaxb:jaxb-runtime:2.3.2")
    bundledRuntimeMetadata("org.xerial:sqlite-jdbc:3.53.2.0")
    bundledRuntimeMetadata("com.google.guava:failureaccess:1.0.2")
    bundledRuntimeMetadata("com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava")
    bundledRuntimeMetadata("com.google.code.findbugs:jsr305:3.0.2")
    bundledRuntimeMetadata("com.google.errorprone:error_prone_annotations:2.23.0")
    bundledRuntimeMetadata("org.jvnet.staxex:stax-ex:1.8.1")
    bundledRuntimeMetadata("jakarta.xml.bind:jakarta.xml.bind-api:2.3.2")
    bundledRuntimeMetadata("org.glassfish.jaxb:txw2:2.3.2")
    bundledRuntimeMetadata("com.sun.istack:istack-commons-runtime:3.0.8")
    bundledRuntimeMetadata("com.sun.xml.fastinfoset:FastInfoset:1.2.16")
    bundledRuntimeMetadata("jakarta.activation:jakarta.activation-api:1.2.1")
    testImplementation(kotlin("test"))
}

val mapsforgeArtifacts = mapOf(
    "mapsforge-map-writer-0.29.0-jar-with-dependencies.jar" to
        "b507829b5a562be32e4fab14c8a76ffd45cebe99f6999cc955de3fcb4ed22dbf",
    "mapsforge-poi-writer-0.29.0-jar-with-dependencies.jar" to
        "a414872bd994b025bb8402034a80add23ca3cdbde72f716886794e3b8d2ad701",
)

val verifyMapsforgePlugins = tasks.register<VerifyMapsforgePluginsTask>("verifyMapsforgePlugins") {
    group = "verification"
    description = "Prüft die offiziellen Mapsforge-Writer-Plugins."
    artifacts.from(mapsforgeArtifacts.keys.map { layout.projectDirectory.file("libs/$it") })
    expectedHashes.set(mapsforgeArtifacts)
}

tasks.named("test") {
    dependsOn(verifyMapsforgePlugins)
}

application {
    mainClass.set("de.arxsilex.maptools.converter.worker.WorkerMainKt")
}
