package space.nstart.pcp_tgu_service.service

import org.junit.jupiter.api.Assertions.assertFalse
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Test
import space.nstart.pcp_tgu_service.domain.CalculatedPlan
import java.time.LocalDateTime

class ZrvWindowMatcherTest {

    private val sc = "25544"
    private val t0 = LocalDateTime.now().withNano(0)
    private fun at(min: Long) = t0.plusMinutes(min)

    private val zrvA = CalculatedPlan(sc, at(0), at(10), "KPP-1")
    private val zrvB = CalculatedPlan(sc, at(100), at(110), "KPP-2")
    private val windows = listOf(zrvA, zrvB)

    @Test
    fun `window spanning two different ZRV (start of A, end of B) matches`() {
        assertTrue(ZrvWindowMatcher.matches(windows, at(0), at(110), "KPP-1"))
    }

    @Test
    fun `single-ZRV window (start and end of the same zone) matches`() {
        assertTrue(ZrvWindowMatcher.matches(windows, at(0), at(10), "KPP-1"))
    }

    @Test
    fun `start not aligned to any ZRV start does not match`() {
        assertFalse(ZrvWindowMatcher.matches(windows, at(3), at(110), "KPP-1"))
    }

    @Test
    fun `start kpp mismatch does not match even if time aligns`() {
        assertFalse(ZrvWindowMatcher.matches(windows, at(0), at(110), "KPP-2"))
    }

    @Test
    fun `end not aligned to any ZRV end does not match`() {
        assertFalse(ZrvWindowMatcher.matches(windows, at(0), at(105), "KPP-1"))
    }

    @Test
    fun `stop not after start does not match`() {
        assertFalse(ZrvWindowMatcher.matches(windows, at(0), at(0), "KPP-1"))
    }

    @Test
    fun `empty windows never match`() {
        assertFalse(ZrvWindowMatcher.matches(emptyList(), at(0), at(110), "KPP-1"))
    }

    @Test
    fun `sub-second ZRV matches a window truncated to whole seconds`() {
        // Фронт усекает ISO до целых секунд (.slice(0,19)); реальная ЗРВ имеет доли секунды.
        // Расхождение строго меньше секунды должно совпадать (регрессия на Duration.toSeconds()).
        val fractional = CalculatedPlan(
            sc,
            at(0).withNano(180_078_000),
            at(10).withNano(19_687_000),
            "KPP-1"
        )
        assertTrue(ZrvWindowMatcher.matches(listOf(fractional), at(0), at(10), "KPP-1"))
    }
}
