package de.arxsilex.maptools.converter.core

data class InputFileInfo(
    val path: String,
    val name: String,
    val sizeBytes: Long,
    val format: InputFormat,
    val pbfMetadata: PbfHeaderMetadata? = null,
    val mapsforgeMetadata: MapsforgeMapMetadata? = null,
    val mapsforgePoiMetadata: MapsforgePoiMetadata? = null,
    val elevationMetadata: ElevationMetadata? = null,
) {
    val bounds: GeoBounds?
        get() = pbfMetadata?.bounds
            ?: mapsforgeMetadata?.bounds
            ?: mapsforgePoiMetadata?.bounds
            ?: elevationMetadata?.bounds
}

data class MapsforgeMapMetadata(
    val bounds: GeoBounds,
    val fileVersion: Int,
    val zoomLevelMin: Int,
    val zoomLevelMax: Int,
    val createdBy: String?,
    val languages: String?,
)

data class MapsforgePoiMetadata(
    val bounds: GeoBounds,
    val schemaVersion: Int,
    val poiCount: Long,
    val writer: String?,
)

data class ElevationMetadata(
    val bounds: GeoBounds,
    val width: Int,
    val height: Int,
    val resolutionMeters: Double?,
    val noDataValue: Double?,
    val coordinateReferenceSystem: String?,
) {
    init {
        require(width > 1 && height > 1) { "Das Höhenraster muss mindestens 2 × 2 Werte enthalten." }
        require(resolutionMeters == null || resolutionMeters > 0.0) {
            "Die Rasterauflösung muss positiv sein."
        }
    }
}

object InputFileInspector {
    fun detectFormat(fileName: String): InputFormat? {
        val normalizedName = fileName.lowercase()
        return InputFormat.entries.firstOrNull { format ->
            format.extensions.any(normalizedName::endsWith)
        }
    }

    fun inspect(path: String, name: String, sizeBytes: Long): InputFileInfo? {
        require(sizeBytes >= 0) { "Die Dateigröße darf nicht negativ sein." }
        val format = detectFormat(name) ?: return null
        return InputFileInfo(path, name, sizeBytes, format)
    }
}
