"""Result dataclasses returned by the AI Policy Authoring System."""

from dataclasses import dataclass, field
from typing import Any

from rbacx.core.decision import Decision
from rbacx.dsl.lint import Issue


@dataclass(frozen=True)
class PolicyResult:
    """The outcome of a policy generation or refinement operation.

    Attributes:
        dsl: the generated policy dict, ready to pass directly to
             ``Guard(policy_result.dsl)``.
        warnings: lint issues returned by ``analyze_policy``.  An empty list
                  means the policy passed all semantic checks.
        compiled: the compiled policy returned by ``rbacx.core.compiler``
                  when ``compile=True`` was requested, otherwise ``None``.
        explanation: per-rule human-readable explanations keyed by
                     ``rule_id`` when ``explain=True`` was requested,
                     otherwise ``None``.
        raw: the raw LLM output string when ``raw=True`` was requested,
             useful for debugging prompt/response pairs.  ``None`` otherwise.
    """

    dsl: dict[str, Any]
    warnings: list[Issue] = field(default_factory=list)
    compiled: Any | None = None
    explanation: dict[str, str] | None = None
    raw: str | None = None


@dataclass(frozen=True)
class DecisionExplanation:
    """The outcome of an ``explain_decision`` call.

    The access decision is evaluated **deterministically** by a minimal
    ``Guard`` instance — the LLM is never asked to decide allow/deny.
    The LLM only produces the human-readable narrative of *why* the decision
    was reached.

    Attributes:
        decision: the authoritative ``Decision`` from ``rbacx.core``.
        human: a plain-English explanation of why the decision was made,
               generated by the configured LLM.
    """

    decision: Decision
    human: str
