"""Unified compliance mapping — enriches findings with framework control descriptions."""

from __future__ import annotations

from sentinel.models.findings import AggregatedReport, Finding


def enrich_report(report: AggregatedReport) -> None:
    """
    Mutate findings in-place to validate compliance IDs.
    (Findings already carry their own compliance mappings set by analyzers —
    this function is available for any post-processing needed.)
    """
    # No-op currently; findings carry their mappings from analyzers.
    # This is the extension point for future compliance enrichment.
    pass


def soc2_gap_table(report: AggregatedReport) -> list[dict[str, str]]:
    """
    Build a SOC 2 gap analysis table for the reporting layer.
    Returns: list of {control_id, description, status, finding_count, severity}
    """
    from sentinel.models.compliance import SOC2_CONTROLS

    # Collect all affected SOC 2 controls
    affected: dict[str, list[Finding]] = {}
    for finding in report.all_findings:
        for ctrl in finding.compliance.soc2:
            affected.setdefault(ctrl, []).append(finding)

    rows = []
    for ctrl_id, description in SOC2_CONTROLS.items():
        findings_for_ctrl = affected.get(ctrl_id, [])
        if findings_for_ctrl:
            max_sev = max(f.severity.weight for f in findings_for_ctrl)
            sev_label = next(
                f.severity.value for f in findings_for_ctrl
                if f.severity.weight == max_sev
            )
            rows.append({
                "control_id": ctrl_id,
                "description": description,
                "status": "GAP",
                "finding_count": str(len(findings_for_ctrl)),
                "max_severity": sev_label,
            })
        else:
            rows.append({
                "control_id": ctrl_id,
                "description": description,
                "status": "SATISFIED",
                "finding_count": "0",
                "max_severity": "-",
            })
    return rows


def owasp_cicd_table(report: AggregatedReport) -> list[dict[str, str]]:
    """OWASP CI/CD Top 10 coverage table."""
    from sentinel.models.compliance import OWASP_CICD_CONTROLS

    affected: dict[str, list[Finding]] = {}
    for finding in report.all_findings:
        for ctrl in finding.compliance.owasp_cicd:
            affected.setdefault(ctrl, []).append(finding)

    rows = []
    for ctrl_id, description in OWASP_CICD_CONTROLS.items():
        findings_for_ctrl = affected.get(ctrl_id, [])
        rows.append({
            "control_id": ctrl_id,
            "description": description,
            "status": "FAIL" if findings_for_ctrl else "PASS",
            "finding_count": str(len(findings_for_ctrl)),
        })
    return rows


def remediation_roadmap(report: AggregatedReport) -> list[Finding]:
    """
    Return findings sorted by impact (severity weight) descending.
    These become the Phase 2 remediation scope.
    """
    return sorted(
        report.all_findings,
        key=lambda f: f.severity.weight,
        reverse=True,
    )
