"""Derivation policy v0 for the Master Capability Registry.

Confidence + status are DERIVED from (relationship_type, evidence_kind) under a
versioned policy — never stored. HARD RULE baked in and structurally guarded: a
CERTIFICATION is a claim, never proof — no certification-backed rule may yield
CONFIRMED. CONFIRMED requires a CONFIRMS relation backed by a concrete ARTIFACT
(or an EXPERT assertion).

Python 3.9 compatible (no `|` unions).
"""

from __future__ import annotations

from .schemas import (
    AssertionStatus,
    Confidence,
    EvidenceKind,
    PolicyRule,
    PolicyVersion,
    RelationType,
)


def _rule(rt: RelationType, ek: EvidenceKind, st: AssertionStatus, cf: Confidence) -> PolicyRule:
    return PolicyRule(relationship_type=rt, evidence_kind=ek, status=st, confidence=cf)


# (relationship_type, evidence_kind) -> (status, confidence)
_V0_RULES = [
    # concrete artifact / expert confirming the capability -> CONFIRMED
    _rule(RelationType.CONFIRMS, EvidenceKind.ARTIFACT, AssertionStatus.CONFIRMED, Confidence.HIGH),
    _rule(RelationType.CONFIRMS, EvidenceKind.EXPERT, AssertionStatus.CONFIRMED, Confidence.MEDIUM),
    # equivalent capability — certificate or artifact behind it -> INFERRED (never confirmed)
    _rule(RelationType.EQUIVALENT, EvidenceKind.CERTIFICATION, AssertionStatus.INFERRED, Confidence.HIGH),
    _rule(RelationType.EQUIVALENT, EvidenceKind.ARTIFACT, AssertionStatus.INFERRED, Confidence.HIGH),
    # supports — weaker
    _rule(RelationType.SUPPORTS, EvidenceKind.CERTIFICATION, AssertionStatus.INFERRED, Confidence.LOW),
    _rule(RelationType.SUPPORTS, EvidenceKind.ARTIFACT, AssertionStatus.INFERRED, Confidence.MEDIUM),
    # requires = an obligation NEEDS the capability (relevance, not possession)
    _rule(RelationType.REQUIRES, EvidenceKind.NONE, AssertionStatus.UNKNOWN, Confidence.LOW),
    # broader/narrower certificate -> weak inference
    _rule(RelationType.BROADER_THAN, EvidenceKind.CERTIFICATION, AssertionStatus.INFERRED, Confidence.LOW),
    _rule(RelationType.NARROWER_THAN, EvidenceKind.CERTIFICATION, AssertionStatus.INFERRED, Confidence.LOW),
    _rule(RelationType.RELATED_TO, EvidenceKind.CERTIFICATION, AssertionStatus.UNKNOWN, Confidence.LOW),
]

DEFAULT_POLICY = PolicyVersion(
    policy_version="capability-policy-v0",
    description="v0: certification never yields CONFIRMED; only CONFIRMS + ARTIFACT/EXPERT does.",
    rules=_V0_RULES,
)


def assert_no_certification_confirms(policy: PolicyVersion) -> None:
    """Structural guard for the hard rule: no CERTIFICATION-backed rule is CONFIRMED."""
    for r in policy.rules:
        if r.evidence_kind == EvidenceKind.CERTIFICATION and r.status == AssertionStatus.CONFIRMED:
            raise ValueError(
                "policy %s violates hard rule: certification -> confirmed (%s)"
                % (policy.policy_version, r.relationship_type.value)
            )


# fail fast at import: the shipped default must satisfy the hard rule
assert_no_certification_confirms(DEFAULT_POLICY)
