package de.arxsilex.maptools.converter.core.elevation

import de.arxsilex.maptools.converter.core.GeoBounds
import kotlin.io.path.createTempDirectory
import kotlin.io.path.writeText
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertTrue

class ElevationPreviewBuilderTest {
    @Test
    fun `builds a bounded Mercator preview and preserves no-data cells`() {
        val directory = createTempDirectory("elevation-preview-")
        try {
            val source = directory.resolve("terrain.asc").also { path ->
                path.writeText(
                    """
                    ncols 4
                    nrows 3
                    xllcorner 8
                    yllcorner 50
                    cellsize 0.01
                    NODATA_value -9999
                    100 150 200 250
                    50 -9999 175 225
                    0 25 75 125
                    """.trimIndent() + "\n",
                )
            }
            var completedRows = 0

            val preview = ElevationPreviewBuilder.build(
                inputs = listOf(source),
                requestedBounds = GeoBounds(7.0, 49.0, 9.0, 51.0),
                maxWidth = 24,
                maxHeight = 18,
                onProgress = { completed, _ -> completedRows = completed },
            )

            assertTrue(preview.width in 2..24)
            assertTrue(preview.height in 2..18)
            assertEquals(preview.height, completedRows)
            assertEquals(GeoBounds(8.0, 50.0, 8.04, 50.03), preview.bounds)
            assertEquals(0f, preview.minimumElevationMeters)
            assertEquals(250f, preview.maximumElevationMeters)
            assertTrue(preview.elevations.any(Float::isNaN))
            assertTrue(preview.populatedCells < preview.elevations.size)
        } finally {
            directory.toFile().deleteRecursively()
        }
    }

    @Test
    fun `preview dimensions never exceed the configured memory bound`() {
        val dimensions = ElevationPreviewBuilder.previewDimensions(
            GeoBounds(5.0, 47.0, 16.0, 55.0),
            maxWidth = 720,
            maxHeight = 480,
        )

        assertTrue(dimensions.first in 2..720)
        assertTrue(dimensions.second in 2..480)
        assertTrue(dimensions.first * dimensions.second <= 720 * 480)
    }
}
