from __future__ import annotations

from dataclasses import dataclass
from typing import Any

from .models import PolicyDecision
from .scenarios import Scenario


@dataclass(frozen=True)
class OracleResult:
    passed: bool
    expected_decision: str
    observed_decision: str
    state_changed: bool
    containment_failure: bool
    transition_verified: bool
    evidence: dict[str, Any]


def evaluate_oracle(
    scenario: Scenario,
    decision: PolicyDecision,
    state_before: str,
    state_after: str,
    expected_state_after: str | None = None,
) -> OracleResult:
    changed = state_before != state_after
    expected = scenario.expected_decision
    observed = decision.effect
    containment_failure = expected == "deny" and (decision.allowed or changed)
    transition_verified = (
        expected_state_after is None or state_after == expected_state_after
    )
    passed = observed == expected and not containment_failure and transition_verified
    return OracleResult(
        passed=passed,
        expected_decision=expected,
        observed_decision=observed,
        state_changed=changed,
        containment_failure=containment_failure,
        transition_verified=transition_verified,
        evidence={
            "rule_id": decision.rule_id,
            "state_before": state_before,
            "state_after": state_after,
            "expected_state_after": expected_state_after,
        },
    )
