"""Lazy loader for framework control definition YAML files.

Controls are loaded on first access and cached per framework ID.
"""

from __future__ import annotations

from pathlib import Path

import yaml

from complyform.core.errors import ProfileBundleError
from complyform.core.profiles.models import Control, ControlsFile

_PROFILES_DIR = Path(__file__).resolve().parent.parent.parent / "profiles"

_cache: dict[str, ControlsFile] = {}


def load_controls(framework_id: str) -> ControlsFile:
    """Load controls YAML for the given framework. Cached per process."""
    if framework_id in _cache:
        return _cache[framework_id]

    path = _PROFILES_DIR / "controls" / f"{framework_id}.yaml"
    if not path.exists():
        raise ProfileBundleError(
            f"Controls file not found for framework '{framework_id}'"
        )

    raw = yaml.safe_load(path.read_text(encoding="utf-8"))
    try:
        controls_file = ControlsFile.model_validate(raw)
    except Exception as exc:
        raise ProfileBundleError(str(exc)) from exc

    _cache[framework_id] = controls_file
    return controls_file


def get_control(framework_id: str, control_id: str) -> Control | None:
    """Lookup a single control by framework and control ID."""
    cf = load_controls(framework_id)
    for c in cf.controls:
        if c.id == control_id:
            return c
    return None


def _reset_cache() -> None:
    """Clear cached controls — for testing only."""
    _cache.clear()
