package space.nstart.pcp.pcp_satellites_service.dto

import jakarta.validation.Validation
import org.junit.jupiter.api.Test
import space.nstart.pcp.pcp_types_lib.dto.requests.ComplexPlanProcessRequestDTO
import java.time.LocalDateTime
import kotlin.test.assertEquals
import kotlin.test.assertTrue

class ComplexPlanProcessRequestDTOValidationTest {

    private val validator = Validation.buildDefaultValidatorFactory().validator
    private val intervalStart = LocalDateTime.of(2026, 3, 26, 10, 0)
    private val intervalEnd = LocalDateTime.of(2026, 3, 26, 12, 0)

    @Test
    fun `sun null is valid`() {
        assertTrue(validate(null).isEmpty())
    }

    @Test
    fun `sun minus 90 is valid`() {
        assertTrue(validate(-90.0).isEmpty())
    }

    @Test
    fun `sun 90 is valid`() {
        assertTrue(validate(90.0).isEmpty())
    }

    @Test
    fun `sun below minus 90 is invalid`() {
        val violations = validate(-90.1)

        assertEquals(1, violations.size)
        assertEquals("sun", violations.single().propertyPath.toString())
    }

    @Test
    fun `sun above 90 is invalid`() {
        val violations = validate(90.1)

        assertEquals(1, violations.size)
        assertEquals("sun", violations.single().propertyPath.toString())
    }

    @Test
    fun `aggregation counts null are valid`() {
        assertTrue(validate(sun = null, countLat = null, countLong = null).isEmpty())
    }

    @Test
    fun `aggregation counts one are valid`() {
        assertTrue(validate(sun = null, countLat = 1, countLong = 1).isEmpty())
    }

    @Test
    fun `countLat below one is invalid`() {
        val violations = validate(sun = null, countLat = 0, countLong = 1)

        assertEquals(1, violations.size)
        assertEquals("countLat", violations.single().propertyPath.toString())
    }

    @Test
    fun `countLong below one is invalid`() {
        val violations = validate(sun = null, countLat = 1, countLong = 0)

        assertEquals(1, violations.size)
        assertEquals("countLong", violations.single().propertyPath.toString())
    }

    private fun validate(
        sun: Double?,
        countLat: Int? = null,
        countLong: Int? = null
    ) =
        validator.validate(
            ComplexPlanProcessRequestDTO(
                intervalStart = intervalStart,
                intervalEnd = intervalEnd,
                satelliteIds = listOf(22L),
                sun = sun,
                countLat = countLat,
                countLong = countLong
            )
        )
}
