package com.correx.core.validation.semantic.rules

import com.correx.core.validation.policy.CycleSignatureFactory
import com.correx.core.validation.model.ValidationContext
import com.correx.core.validation.model.ValidationIssue
import com.correx.core.validation.model.ValidationSeverity
import com.correx.core.validation.semantic.SemanticRule

class CycleExitRule(
    private val requirePolicyForCycles: Boolean
) : SemanticRule {

    override fun validate(context: ValidationContext): List<ValidationIssue> {

        if (!requirePolicyForCycles) return emptyList()

        val knownSignatures = context.detectedCycles
            .map { CycleSignatureFactory.from(it.nodes, it.edges) }
            .toSet()

        val bound = context.cyclePolicies
            .map { it.cycle }
            .toSet()

        val unbound = knownSignatures - bound

        return unbound.map { signature ->
            ValidationIssue(
                code = "CYCLE_POLICY_MISSING",
                message = "Cycle has no policy binding: $signature",
                severity = ValidationSeverity.WARNING,
                location = null
            )
        }
    }
}
