package space.nstart.pcp.tle_monitoring_service.service

import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertFalse
import org.junit.jupiter.api.Assertions.assertThrows
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Test
import space.nstart.pcp.tle_monitoring_service.configuration.CustomValidationException
import space.nstart.pcp.tle_monitoring_service.configuration.TlePollingProperties
import java.time.Instant

class TlePollingSettingsServiceTest {

    @Test
    fun `initializes settings from properties`() {
        val service = TlePollingSettingsService(
            TlePollingProperties(enabled = false, timeoutSeconds = 45),
        )

        val settings = service.current()

        assertFalse(settings.enabled)
        assertEquals(45, settings.timeoutSeconds)
    }

    @Test
    fun `polling is disabled by default`() {
        val service = TlePollingSettingsService(TlePollingProperties())

        val settings = service.current()

        assertFalse(settings.enabled)
        assertFalse(service.shouldStartPolling())
    }

    @Test
    fun `updates polling settings`() {
        val service = TlePollingSettingsService(TlePollingProperties())

        val settings = service.update(
            UpdateTlePollingSettingsRequest(enabled = false, timeoutSeconds = 60),
        )

        assertFalse(settings.enabled)
        assertEquals(60, settings.timeoutSeconds)
        assertFalse(service.shouldStartPolling())
    }

    @Test
    fun `uses timeout between polling cycles`() {
        val service = TlePollingSettingsService(
            TlePollingProperties(enabled = true, timeoutSeconds = 30),
        )
        val startedAt = Instant.parse("2026-05-13T10:00:00Z")

        assertTrue(service.shouldStartPolling(startedAt))

        service.markPollingStarted(startedAt)

        assertFalse(service.shouldStartPolling(startedAt.plusSeconds(29)))
        assertTrue(service.shouldStartPolling(startedAt.plusSeconds(30)))
    }

    @Test
    fun `rejects invalid timeout`() {
        val service = TlePollingSettingsService(TlePollingProperties())

        assertThrows(CustomValidationException::class.java) {
            service.update(UpdateTlePollingSettingsRequest(enabled = true, timeoutSeconds = 0))
        }
    }

    @Test
    fun `starts immediately after polling is enabled`() {
        val service = TlePollingSettingsService(
            TlePollingProperties(enabled = true, timeoutSeconds = 30),
        )
        val startedAt = Instant.parse("2026-05-13T10:00:00Z")

        service.markPollingStarted(startedAt)
        service.update(UpdateTlePollingSettingsRequest(enabled = false, timeoutSeconds = 30))
        service.update(UpdateTlePollingSettingsRequest(enabled = true, timeoutSeconds = 30))

        assertTrue(service.shouldStartPolling(startedAt.plusSeconds(1)))
    }
}
