"""Assessment modifier: adjust findings based on landing zone context.

Contract:
- apply_landing_zone_context() sets findings to PASS when covered by
  inherited landing zone policies.
- Loads policy->control mappings from profiles/landing_zone_mappings.yaml.
"""

from __future__ import annotations

import sys
from pathlib import Path
from typing import TYPE_CHECKING

import yaml

if TYPE_CHECKING:
    from complyform.core.assessor.control_matcher import Finding
    from complyform.core.scanner.landing_zone import LandingZoneContext

__all__ = [
    "apply_landing_zone_context",
]

# policy_id -> list[{framework, control_id}]
LANDING_ZONE_CONTROL_MAP: dict[str, dict[str, list[dict[str, str]]]] = {}

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


def _load_landing_zone_mappings() -> None:
    """Load profiles/landing_zone_mappings.yaml into LANDING_ZONE_CONTROL_MAP."""
    global LANDING_ZONE_CONTROL_MAP  # noqa: PLW0603
    yaml_path = _PROFILES_DIR / "landing_zone_mappings.yaml"
    if not yaml_path.exists():
        print(
            f"Warning: {yaml_path} not found, no LZ mappings loaded",
            file=sys.stderr,
        )
        return
    with open(yaml_path) as f:
        data = yaml.safe_load(f)
    if isinstance(data, dict):
        LANDING_ZONE_CONTROL_MAP = data


def apply_landing_zone_context(
    findings: list[Finding],
    lz: LandingZoneContext,
) -> tuple[list[Finding], int]:
    """Modify findings based on landing zone context.

    For each finding: if control_id maps to an inherited_policy via
    LANDING_ZONE_CONTROL_MAP[lz.type][policy_id] -> list[{framework, control_id}],
    set status="PASS", append note "Enforced by {lz.type}: {policy_id}".

    Returns (modified_findings_list, controls_skipped_count).
    """
    if not lz.detected or lz.type is None or not lz.inherited_policies:
        return (findings, 0)

    if not LANDING_ZONE_CONTROL_MAP:
        _load_landing_zone_mappings()

    lz_type_map = LANDING_ZONE_CONTROL_MAP.get(lz.type, {})
    if not lz_type_map:
        return (findings, 0)

    # Build lookup: (framework, control_id) -> policy_id
    covered: dict[tuple[str, str], str] = {}
    for policy_id in lz.inherited_policies:
        mappings = lz_type_map.get(policy_id, [])
        for mapping in mappings:
            key = (mapping["framework"], mapping["control_id"])
            covered[key] = policy_id

    modified: list[Finding] = []
    skipped = 0

    for finding in findings:
        key = (finding.framework, finding.control_id)
        if key in covered:
            policy_id = covered[key]
            note = f"Enforced by {lz.type}: {policy_id}"
            new_finding = finding.model_copy(
                update={
                    "status": "PASS",
                    "finding": f"{finding.finding} [{note}]",
                },
            )
            modified.append(new_finding)
            skipped += 1
        else:
            modified.append(finding)

    return (modified, skipped)
