package com.correx.testing.contracts.model.orchestration

import com.correx.core.events.types.SessionId
import com.correx.core.events.types.StageId
import com.correx.core.kernel.execution.WorkflowResult
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertFalse
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Test

class WorkflowResultTest {

    @Test
    fun `Completed carries sessionId and terminalStageId`() {
        val result = WorkflowResult.Completed(SessionId("s1"), StageId("stage-z"))
        assertEquals(SessionId("s1"), result.sessionId)
        assertEquals(StageId("stage-z"), result.terminalStageId)
    }

    @Test
    fun `Failed carries sessionId reason and retryExhausted`() {
        val result = WorkflowResult.Failed(SessionId("s2"), "boom", retryExhausted = true)
        assertEquals(SessionId("s2"), result.sessionId)
        assertEquals("boom", result.reason)
        assertTrue(result.retryExhausted)
    }

    @Test
    fun `Failed retryExhausted can be false`() {
        val result = WorkflowResult.Failed(SessionId("s3"), "transient", retryExhausted = false)
        assertFalse(result.retryExhausted)
    }

    @Test
    fun `Cancelled carries sessionId`() {
        val result = WorkflowResult.Cancelled(SessionId("s4"))
        assertEquals(SessionId("s4"), result.sessionId)
    }

    @Test
    fun `sealed exhaustiveness - all variants reachable`() {
        val results: List<WorkflowResult> = listOf(
            WorkflowResult.Completed(SessionId("s1"), StageId("stage-z")),
            WorkflowResult.Failed(SessionId("s2"), "reason", retryExhausted = false),
            WorkflowResult.Cancelled(SessionId("s3")),
        )

        val labels = results.map { result ->
            when (result) {
                is WorkflowResult.Completed -> "completed"
                is WorkflowResult.Failed -> "failed"
                is WorkflowResult.Cancelled -> "cancelled"
            }
        }

        assertEquals(listOf("completed", "failed", "cancelled"), labels)
    }
}
