package space.nstart.pcp.slots_service.model.satellite

import org.junit.jupiter.api.Test
import space.nstart.pcp.pcp_types_lib.dto.requests.slots.BookedSlotStatus
import space.nstart.pcp.pcp_types_lib.dto.requests.slots.SlotStatus
import space.nstart.pcp.slots_service.entity.BookedSlotEntity
import space.nstart.pcp.slots_service.entity.SlotEntity
import java.time.LocalDateTime
import kotlin.test.assertEquals

class TestSatelliteImplBookedBlockingTest {

    @Test
    fun `non-booked slot inside active booked interval is marked busy and exact booked slot stays booked`() {
        val baseTime = LocalDateTime.of(2026, 5, 21, 0, 0)
        val satellite = TestSatelliteImpl(
            id = 1L,
            tnCalc = baseTime,
            durationCalc = 1,
            maxChainLength = 3,
            maxSurveyDuration = 300,
            mmi = 10
        )
        val bookedRawSlot = slot(slotId = 1L, slotNum = 1L, baseTime = baseTime, startSecond = 0, endSecond = 10)
        val candidateInsideBooked = slot(slotId = 2L, slotNum = 2L, baseTime = baseTime, startSecond = 2, endSecond = 8)
        val booked = BookedSlotEntity(slot = bookedRawSlot, cycle = 0).apply {
            status = BookedSlotStatus.PROCESSED.name
        }

        val result = satellite.prepareCoverageSlots(
            slots = listOf(bookedRawSlot, candidateInsideBooked),
            bookedSlots = listOf(booked),
            timeStart = baseTime,
            timeStop = baseTime.plusSeconds(20),
            sign = null,
            states = null
        ).map { it.slot }.associateBy { it.slotNumber }

        assertEquals(SlotStatus.BOOKED, result.getValue(1L).state)
        assertEquals(SlotStatus.BUSY, result.getValue(2L).state)
    }

    private fun slot(
        slotId: Long,
        slotNum: Long,
        baseTime: LocalDateTime,
        startSecond: Long,
        endSecond: Long
    ) = SlotEntity(
        slotId = slotId,
        slotNum = slotNum,
        cycle = 0,
        satelliteId = 1L,
        coveringType = 0,
        tn = baseTime.plusSeconds(startSecond),
        tk = baseTime.plusSeconds(endSecond),
        roll = 10.0,
        contour = "POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0))",
        revolution = 1L,
        revolutionSign = "ASC"
    )
}
