package com.correx.core.events.serialization

import com.correx.core.events.events.EventPayload
import com.correx.core.events.events.HealthDegradedEvent
import com.correx.core.events.events.HealthRestoredEvent
import com.correx.core.events.events.HealthSubject
import com.correx.core.events.types.SessionId
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertTrue

class HealthEventsSerializationTest {

    @Test
    fun `HealthDegradedEvent round-trips as polymorphic EventPayload`() {
        val sample: EventPayload = HealthDegradedEvent(
            sessionId = SessionId("__system__"),
            subject = HealthSubject.DISK,
            metric = "total_bytes",
            observedValue = 6_000_000_000,
            threshold = 5_000_000_000,
            detail = "event log + CAS at 5.6 GiB (warn ≥ 4.7 GiB)",
        )
        val encoded = eventJson.encodeToString(EventPayload.serializer(), sample)
        assertTrue(encoded.contains("\"type\":\"HealthDegraded\""), "SerialName must be present: $encoded")
        assertEquals(sample, eventJson.decodeFromString(EventPayload.serializer(), encoded))
    }

    @Test
    fun `HealthRestoredEvent round-trips as polymorphic EventPayload`() {
        val sample: EventPayload = HealthRestoredEvent(
            sessionId = SessionId("__system__"),
            subject = HealthSubject.DISK,
            metric = "total_bytes",
            observedValue = 1_000_000_000,
            detail = "event log + CAS at 953.7 MiB",
        )
        val encoded = eventJson.encodeToString(EventPayload.serializer(), sample)
        assertTrue(encoded.contains("\"type\":\"HealthRestored\""), "SerialName must be present: $encoded")
        assertEquals(sample, eventJson.decodeFromString(EventPayload.serializer(), encoded))
    }

    @Test
    fun `every HealthSubject round-trips`() {
        for (subject in HealthSubject.entries) {
            val sample: EventPayload = HealthRestoredEvent(
                sessionId = SessionId("__system__"),
                subject = subject,
                metric = "m",
                observedValue = 0,
                detail = "ok",
            )
            assertEquals(
                sample,
                eventJson.decodeFromString(
                    EventPayload.serializer(),
                    eventJson.encodeToString(EventPayload.serializer(), sample),
                ),
            )
        }
    }
}
