package de.arxsilex.maptools.converter.worker

import de.arxsilex.maptools.converter.core.PoiSchemaVersion
import de.arxsilex.maptools.converter.core.GeoSelectionRegion
import java.nio.file.Files
import java.nio.file.Path

data class PoiConvertRequest(
    val input: Path,
    val output: Path,
    val sourceSchema: PoiSchemaVersion,
    val targetSchema: PoiSchemaVersion,
    val temporaryDirectory: Path,
    val areas: List<GeoSelectionRegion>? = null,
) {
    init {
        require(Files.isRegularFile(input)) { "POI-Eingabedatei nicht gefunden: $input" }
        require(input != output) { "POI-Eingabe und -Ausgabe müssen verschieden sein." }
    }

    companion object {
        fun parse(arguments: Array<String>): PoiConvertRequest {
            require(arguments.firstOrNull() == "poi-convert") { "Erwarteter Worker-Befehl: poi-convert" }
            val values = arguments.drop(1).chunked(2).associate { pair ->
                require(pair.size == 2 && pair[0].startsWith("--")) { "Ungültige Worker-Argumente." }
                pair[0].removePrefix("--") to pair[1]
            }
            fun required(name: String): String = values[name] ?: error("Worker-Argument --$name fehlt.")
            fun schema(name: String): PoiSchemaVersion = PoiSchemaVersion.entries.single {
                it.metadataVersion == required(name).toInt()
            }
            val input = Path.of(required("input")).toAbsolutePath().normalize()
            return PoiConvertRequest(
                input = input,
                output = Path.of(required("output")).toAbsolutePath().normalize(),
                sourceSchema = schema("source-schema"),
                targetSchema = schema("target-schema"),
                temporaryDirectory = values["temp-dir"]?.let(Path::of)?.toAbsolutePath()?.normalize()
                    ?: input.parent.resolve(".maptools-temp"),
                areas = values["areas"]?.let(SelectionBoundsCodec::decode),
            )
        }
    }
}
