package com.correx.core.kernel.orchestration

import com.correx.core.events.events.BriefEcho
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 BriefEchoComparatorTest {

    @Test
    fun `identical echo has no mismatch`() {
        val brief = BriefEcho(
            referencedFiles = setOf("core/kernel/Foo.kt"),
            symbols = setOf("Foo"),
            acceptanceCriteria = setOf("must compile"),
        )
        val diff = BriefEchoComparator.compare(brief, brief)
        assertFalse(diff.hasMismatch)
        assertTrue(diff.droppedFiles.isEmpty())
        assertTrue(diff.inventedFiles.isEmpty())
    }

    @Test
    fun `dropped acceptance criterion is a mismatch`() {
        val original = BriefEcho(acceptanceCriteria = setOf("must compile", "must pass tests"))
        val echo = BriefEcho(acceptanceCriteria = setOf("must compile"))
        val diff = BriefEchoComparator.compare(original, echo)
        assertTrue(diff.hasMismatch)
        assertEquals(setOf("must pass tests"), diff.droppedAcceptanceCriteria)
    }

    @Test
    fun `invented file is a mismatch`() {
        val original = BriefEcho(referencedFiles = setOf("core/kernel/Foo.kt"))
        val echo = BriefEcho(referencedFiles = setOf("core/kernel/Foo.kt", "core/kernel/Bar.kt"))
        val diff = BriefEchoComparator.compare(original, echo)
        assertTrue(diff.hasMismatch)
        assertEquals(setOf("core/kernel/Bar.kt"), diff.inventedFiles)
    }

    @Test
    fun `dropped file only is not a mismatch`() {
        val original = BriefEcho(referencedFiles = setOf("core/kernel/Foo.kt", "core/kernel/Bar.kt"))
        val echo = BriefEcho(referencedFiles = setOf("core/kernel/Foo.kt"))
        val diff = BriefEchoComparator.compare(original, echo)
        assertFalse(diff.hasMismatch)
        assertEquals(setOf("core/kernel/Bar.kt"), diff.droppedFiles)
    }

    @Test
    fun `acceptance criterion match is case-insensitive and trimmed`() {
        val original = BriefEcho(acceptanceCriteria = setOf("Must Compile"))
        val echo = BriefEcho(acceptanceCriteria = setOf("  must compile  "))
        val diff = BriefEchoComparator.compare(original, echo)
        assertFalse(diff.hasMismatch)
        assertTrue(diff.droppedAcceptanceCriteria.isEmpty())
    }

    @Test
    fun `dropped symbol is not a mismatch but is reported`() {
        val original = BriefEcho(symbols = setOf("Foo", "Bar"))
        val echo = BriefEcho(symbols = setOf("foo"))
        val diff = BriefEchoComparator.compare(original, echo)
        assertFalse(diff.hasMismatch)
        assertEquals(setOf("Bar"), diff.droppedSymbols)
    }
}
