"""Lazy loader for framework → cloud mapping YAML files.

Mappings are loaded on first access and cached per (framework_id, cloud).
"""

from __future__ import annotations

from pathlib import Path

import yaml

from complyform.core.errors import ProfileBundleError
from complyform.core.profiles.models import MappingFile, ResourceMapping

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

_cache: dict[tuple[str, str], MappingFile] = {}


def load_mappings(framework_id: str, cloud: str) -> MappingFile:
    """Load mappings YAML for framework + cloud. Cached per process."""
    key = (framework_id, cloud)
    if key in _cache:
        return _cache[key]

    path = _PROFILES_DIR / "mappings" / cloud / f"{framework_id}.yaml"
    if not path.exists():
        raise ProfileBundleError(f"Mappings not found for {framework_id}/{cloud}")

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

    _cache[key] = mappings_file
    return mappings_file


def get_mappings_for_check(
    framework_id: str, cloud: str, check_id: str
) -> list[ResourceMapping]:
    """Find all mapping entries for a given check ID."""
    mf = load_mappings(framework_id, cloud)
    return [m for m in mf.mappings if m.check_id == check_id]


def get_mappings_for_control(
    framework_id: str, cloud: str, control_id: str
) -> list[ResourceMapping]:
    """Find all mapping entries for a given control ID."""
    mf = load_mappings(framework_id, cloud)
    return [m for m in mf.mappings if m.control_id == control_id]


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