package com.correx.core.kernel.orchestration

import com.correx.core.events.events.ConceptPromotedEvent
import com.correx.core.events.types.SessionId
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Test

class SelectPromotedConceptsTest {

    private fun concept(classKey: String, gate: String, occ: Int) = ConceptPromotedEvent(
        sessionId = SessionId("__concept_compiler__"),
        fingerprint = classKey,
        classKey = classKey,
        gate = gate,
        conceptText = "text for $classKey",
        occurrences = occ,
    )

    @Test
    fun `a file-write-requiring concept is withheld from a stage lacking file_write`() {
        val promoted = listOf(concept("contract:x", "contract", 5))
        assertTrue(selectPromotedConcepts(promoted, allowedTools = setOf("shell")).isEmpty())
        assertEquals(1, selectPromotedConcepts(promoted, allowedTools = setOf("file_write")).size)
    }

    @Test
    fun `gates with no required capability are broadly relevant`() {
        val promoted = listOf(concept("lint:y", "lint", 3))
        assertEquals(1, selectPromotedConcepts(promoted, allowedTools = setOf("shell")).size)
    }

    @Test
    fun `a concept contradicted after promotion is withheld`() {
        val promoted = listOf(concept("lint:y", "lint", 4))
        assertTrue(
            selectPromotedConcepts(promoted, allowedTools = setOf("shell"), contradicted = setOf("lint:y")).isEmpty(),
        )
        assertEquals(1, selectPromotedConcepts(promoted, allowedTools = setOf("shell")).size)
    }

    @Test
    fun `top concepts by occurrence are kept within the cap`() {
        val promoted = (1..5).map { concept("lint:$it", "lint", occ = it) }
        val picked = selectPromotedConcepts(promoted, allowedTools = emptySet(), limit = 3)
        assertEquals(listOf("lint:5", "lint:4", "lint:3"), picked.map { it.classKey })
    }
}
