"""YAML-based policy loader."""

from __future__ import annotations

from pathlib import Path
from typing import Any

import yaml

from interceptor.exceptions import PolicyLoadError
from interceptor.types import RiskLevel


class PolicyEngine:
    """Load and query YAML policy files.

    Expected YAML structure::

        tools:
          delete_file:
            risk: HIGH
          write_file:
            risk: MEDIUM

        keywords:
          - drop
          - overwrite
    """

    def __init__(self) -> None:
        self._tool_risks: dict[str, RiskLevel] = {}
        self._extra_keywords: list[str] = []

    # -- loading --------------------------------------------------------------

    def load(self, path: str | Path) -> None:
        """Parse a YAML policy file and populate internal state."""
        path = Path(path)
        if not path.exists():
            raise PolicyLoadError(f"Policy file not found: {path}")

        try:
            with open(path, "r") as fh:
                data: dict[str, Any] = yaml.safe_load(fh) or {}
        except yaml.YAMLError as exc:
            raise PolicyLoadError(f"Invalid YAML in {path}: {exc}") from exc

        # Tools section
        tools: dict[str, Any] = data.get("tools", {})
        for tool_name, cfg in tools.items():
            risk_str = cfg.get("risk", "LOW").upper()
            try:
                self._tool_risks[tool_name] = RiskLevel(risk_str)
            except ValueError:
                raise PolicyLoadError(
                    f"Unknown risk level '{risk_str}' for tool '{tool_name}'"
                )

        # Keywords section
        kw_list = data.get("keywords", [])
        if isinstance(kw_list, list):
            self._extra_keywords.extend(str(k).lower() for k in kw_list)

    # -- queries --------------------------------------------------------------

    @property
    def tool_overrides(self) -> dict[str, RiskLevel]:
        """Per-tool risk overrides from the loaded policy."""
        return dict(self._tool_risks)

    @property
    def extra_keywords(self) -> list[str]:
        """Additional destructive keywords from the loaded policy."""
        return list(self._extra_keywords)

    def get_tool_risk(self, tool_name: str) -> RiskLevel | None:
        """Return the policy-mandated risk for *tool_name*, or ``None``."""
        return self._tool_risks.get(tool_name)
