"""Compliance framework mapping for violation enrichment."""

from mergeguide.compliance.mapping import (
    ControlMapping,
    FrameworkControl,
    MappingRegistry,
)

__all__ = [
    "ControlMapping",
    "FrameworkControl",
    "MappingRegistry",
    "enrich_violations",
    "load_control_mappings",
]


def load_control_mappings(json_path: str | None = None) -> MappingRegistry:
    """Load control mappings from JSON file into a MappingRegistry.

    Args:
        json_path: Path to control-mappings.json. If None, uses the
            default bundled mappings shipped with the package.

    Returns:
        MappingRegistry instance ready for violation enrichment.
    """
    import json
    import os

    if json_path is None:
        # Default: look in the mcp-server/data directory relative to the repo root,
        # then fall back to a bundled copy next to this module.
        _here = os.path.dirname(os.path.abspath(__file__))
        candidates = [
            os.path.join(_here, "data", "control-mappings.json"),
            os.path.join(_here, "..", "..", "..", "mcp-server", "data", "control-mappings.json"),
        ]
        for candidate in candidates:
            if os.path.isfile(candidate):
                json_path = candidate
                break
        if json_path is None:
            # No mappings file found — return empty registry (graceful degradation)
            return MappingRegistry(version="0.0", updated="", mappings={})

    with open(json_path) as f:
        raw = json.load(f)

    mappings: dict[str, ControlMapping] = {}
    for rule_id, rule_data in raw.get("mappings", {}).items():
        controls = [
            FrameworkControl(
                framework_id=c["framework_id"],
                framework_name=c.get("framework_name", ""),
                control_id=c["control_id"],
                control_title=c.get("control_title", ""),
                min_tier=c.get("min_tier", "free"),
                framework_url=c.get("framework_url"),
            )
            for c in rule_data.get("controls", [])
        ]
        mappings[rule_id] = ControlMapping(
            rule_id=rule_id,
            cwe_ids=rule_data.get("cwe_ids", []),
            controls=controls,
        )

    return MappingRegistry(
        version=raw.get("version", "1.0"),
        updated=raw.get("updated", ""),
        mappings=mappings,
    )


def enrich_violations(
    violations: list[dict[str, object]],
    registry: MappingRegistry,
    tier: str = "free",
) -> list[dict[str, object]]:
    """Add framework_controls to each violation dict, filtered by tier.

    This is a pure function — it does NOT mutate the input list. Returns a
    new list of violation dicts with the ``framework_controls`` key added.

    Args:
        violations: List of violation dicts (must have ``rule_id``).
        registry: Loaded MappingRegistry.
        tier: Caller's billing tier for control filtering.

    Returns:
        New list of violation dicts with ``framework_controls`` added.
    """
    enriched = []
    for v in violations:
        v_copy = dict(v)
        rule_id = str(v_copy.get("rule_id", ""))
        controls = registry.get_controls(rule_id, tier)
        v_copy["framework_controls"] = [c.to_dict() for c in controls]
        enriched.append(v_copy)
    return enriched
