"""Cross-mapping index: lookup equivalent controls across frameworks."""

from __future__ import annotations

from functools import lru_cache
from pathlib import Path

import yaml

from complyform.core.errors import ProfileBundleError
from complyform.core.profiles.models import ControlCrossMapping, CrossMappingIndex

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


@lru_cache(maxsize=1)
def _load_index() -> CrossMappingIndex:
    """Load and validate cross_mappings/index.yaml (cached per process)."""
    path = _PROFILES_DIR / "cross_mappings" / "index.yaml"
    if not path.exists():
        return CrossMappingIndex(schema_version=1, mappings=[])
    raw = yaml.safe_load(path.read_text(encoding="utf-8"))
    try:
        return CrossMappingIndex.model_validate(raw)
    except Exception as exc:
        raise ProfileBundleError(str(exc)) from exc


def lookup(
    source_framework: str,
    source_control: str,
) -> list[ControlCrossMapping]:
    """Find all cross-mappings from a given source control."""
    idx = _load_index()
    return [
        m
        for m in idx.mappings
        if m.source_framework == source_framework and m.source_control == source_control
    ]


def lookup_reverse(
    target_framework: str,
    target_control: str,
) -> list[ControlCrossMapping]:
    """Find all cross-mappings pointing to a given target control."""
    idx = _load_index()
    return [
        m
        for m in idx.mappings
        if m.target_framework == target_framework and m.target_control == target_control
    ]


def get_all() -> list[ControlCrossMapping]:
    """Return all cross-mapping entries."""
    return _load_index().mappings


def _reset_cache() -> None:
    """Clear cached cross-mappings — for testing only."""
    _load_index.cache_clear()
