package com.correx.core.events.serialization

import com.correx.core.events.events.EventPayload
import com.correx.core.events.events.StaticAnalysisCompletedEvent
import com.correx.core.events.events.StaticAnalysisFinding
import com.correx.core.events.types.SessionId
import com.correx.core.events.types.StageId
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertTrue

class StaticAnalysisCompletedEventSerializationTest {

    private val sample = StaticAnalysisCompletedEvent(
        sessionId = SessionId("sess-1"),
        stageId = StageId("implementer"),
        findings = listOf(
            StaticAnalysisFinding(command = "./gradlew compileKotlin", exitCode = 0, summary = "BUILD SUCCESSFUL"),
            StaticAnalysisFinding(command = "./gradlew detekt", exitCode = 1, summary = "MagicNumber at Foo.kt:42"),
        ),
    )

    @Test
    fun `round-trips as polymorphic EventPayload`() {
        val encoded = eventJson.encodeToString(EventPayload.serializer(), sample)
        assertTrue(encoded.contains("\"type\":\"StaticAnalysisCompleted\""), "SerialName must be present: $encoded")
        val decoded = eventJson.decodeFromString(EventPayload.serializer(), encoded)
        assertEquals(sample, decoded)
    }

    @Test
    fun `decodes hand-written StaticAnalysisCompleted JSON`() {
        val json = """
            {"type":"StaticAnalysisCompleted","sessionId":"s","stageId":"implementer",
             "findings":[{"command":"./gradlew detekt","exitCode":2,"summary":"3 violations"}]}
        """.trimIndent()
        val decoded = eventJson.decodeFromString(EventPayload.serializer(), json)
        assertTrue(decoded is StaticAnalysisCompletedEvent)
        val finding = (decoded as StaticAnalysisCompletedEvent).findings.single()
        assertEquals("./gradlew detekt", finding.command)
        assertEquals(2, finding.exitCode)
        assertFalse(finding.clean)
    }

    @Test
    fun `clean is derived from exit code zero`() {
        assertTrue(StaticAnalysisFinding("c", 0, "").clean)
        assertFalse(StaticAnalysisFinding("c", 1, "").clean)
    }
}
