import com.correx.core.events.events.EventPayload
import com.correx.core.events.events.StageCompletedEvent
import com.correx.core.events.events.StageFailedEvent
import com.correx.core.events.events.TransitionExecutedEvent
import com.correx.core.events.serialization.JsonEventSerializer
import com.correx.core.events.types.SessionId
import com.correx.core.events.types.StageId
import com.correx.core.events.types.TransitionId
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test

class TransitionEventSerializationTest {

    @Test
    fun `TransitionExecutedEvent serializes and deserializes (stage start equivalent)`() {
        val event = TransitionExecutedEvent(
            sessionId = SessionId("session-1"),
            from = StageId("from"),
            to = StageId("stage-a"),
            transitionId = TransitionId("transition-a")
        )

        assertRoundTrip(event)
    }

    @Test
    fun `StageCompletedEvent serializes and deserializes`() {
        val event = StageCompletedEvent(
            sessionId = SessionId("session-1"),
            stageId = StageId("stage-a"),
            transitionId = TransitionId("transition-a")
        )

        assertRoundTrip(event)
    }

    @Test
    fun `StageFailedEvent serializes and deserializes`() {
        val event = StageFailedEvent(
            sessionId = SessionId("session-1"),
            stageId = StageId("stage-a"),
            transitionId = TransitionId("transition-a"),
            reason = "boom"
        )

        assertRoundTrip(event)
    }

    @Test
    fun `TransitionExecutedEvent serializes and deserializes`() {
        val event = TransitionExecutedEvent(
            sessionId = SessionId("session-1"),
            from = StageId("stage-a"),
            to = StageId("stage-b"),
            transitionId = TransitionId("transition-a")
        )

        assertRoundTrip(event)
    }

    private inline fun <reified T : EventPayload> assertRoundTrip(
        event: T
    ) {
        val json = JsonEventSerializer()
        val serialized = json.serialize(event)

        val deserialized =
            json.deserialize(serialized)

        assertEquals(event, deserialized)
    }
}
