package com.correx.core.toolintent

import com.correx.core.events.events.ToolRequest
import com.correx.core.events.risk.RiskAction
import com.correx.core.events.types.SessionId
import com.correx.core.events.types.StageId
import com.correx.core.events.types.ToolInvocationId
import com.correx.core.tools.contract.ToolCapability
import java.nio.file.Path
import kotlin.test.Test
import kotlin.test.assertEquals

class ToolCallAssessorTest {

    private fun ruleReturning(action: RiskAction, applies: Boolean) = object : ToolCallRule {
        override fun appliesTo(capabilities: Set<ToolCapability>) = applies
        override fun assess(input: ToolCallAssessmentInput) = ToolCallAssessment(disposition = action)
    }

    private val input = ToolCallAssessmentInput(
        request = ToolRequest(ToolInvocationId("i"), SessionId("s"), StageId("st"), "t", emptyMap()),
        capabilities = setOf(ToolCapability.FILE_WRITE),
        workspace = WorkspacePolicy(Path.of("/work")),
        probe = FileSystemWorldProbe(),
    )

    @Test
    fun `folds to the strictest disposition across applicable rules`() {
        val assessor = ToolCallAssessor(
            listOf(
                ruleReturning(RiskAction.PROCEED, applies = true),
                ruleReturning(RiskAction.BLOCK, applies = true),
                ruleReturning(RiskAction.PROMPT_USER, applies = true),
            ),
        )
        assertEquals(RiskAction.BLOCK, assessor.assess(input).disposition)
    }

    @Test
    fun `non-applicable rules are skipped`() {
        val assessor = ToolCallAssessor(listOf(ruleReturning(RiskAction.BLOCK, applies = false)))
        assertEquals(RiskAction.PROCEED, assessor.assess(input).disposition)
    }
}
