package space.nstart.pcp.pcp_types_lib.dto.satellite.mission

import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.fasterxml.jackson.module.kotlin.readValue
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertInstanceOf
import org.junit.jupiter.api.Test
import kotlin.test.assertTrue

class ModeResponseDTOJacksonTest {

    private val mapper = jacksonObjectMapper().registerModule(JavaTimeModule())

    @Test
    fun `deserializes mixed mission modes by type`() {
        val json = """
            [
              {
                "id": 1,
                "planId": 10,
                "timeStart": "2026-03-17T08:00:00Z",
                "revolution": 100,
                "type": "SURVEY",
                "source": "AUTO",
                "lat": 55.75,
                "longitude": 37.62,
                "duration": 12.5,
                "contourWkt": null,
                "roll": 1.5,
                "bookedSlotIds": [101, 102]
              },
              {
                "id": 2,
                "planId": 10,
                "timeStart": "2026-03-17T09:00:00Z",
                "revolution": 101,
                "type": "DROP",
                "station": "S1",
                "duration": 3.0,
                "surveys": [1]
              }
            ]
        """.trimIndent()

        val result: List<ModeResponseDTO> = mapper.readValue(json)

        assertEquals(2, result.size)
        assertInstanceOf(SurveyModeResponseDTO::class.java, result[0])
        assertInstanceOf(DropModeResponseDTO::class.java, result[1])
        assertEquals("SURVEY", result[0].type)
        assertEquals("DROP", result[1].type)
    }

    @Test
    fun `serializes computed volume and tolerates it on read-back`() {
        // Сервис-источник теперь сериализует volumeMb; потребитель (pcp-ui-service)
        // десериализует тот же JSON обратно — read-only поле не должно ломать чтение.
        val modes: List<ModeResponseDTO> = listOf(
            SurveyModeResponseDTO(id = 1, planId = 10, duration = 100.0),
            DropModeResponseDTO(id = 2, planId = 10, duration = 5.0)
        )

        val json = mapper.writeValueAsString(modes)
        val tree = mapper.readTree(json)

        // Съёмка: 100 с × 120 Мбайт/с = 12000 Мбайт. Сброс: 5 с × 1200 Мбит/с ÷ 8 = 750 Мбайт.
        assertEquals(12000.0, tree[0]["volumeMb"].asDouble())
        assertEquals(750.0, tree[1]["volumeMb"].asDouble())

        val roundTrip: List<ModeResponseDTO> = mapper.readValue(json)
        assertEquals(12000.0, roundTrip[0].volumeMb)
        assertEquals(750.0, roundTrip[1].volumeMb)
        assertTrue(roundTrip[0] is SurveyModeResponseDTO)
    }
}
