"""Trivy result parser — normalizes filesystem vulnerability findings."""

from __future__ import annotations

from typing import Any

from secagent.models import Severity, Vulnerability
from secagent.parsers.base_parser import BaseParser

_SEVERITY_MAP: dict[str, Severity] = {
    "CRITICAL": Severity.CRITICAL,
    "HIGH": Severity.HIGH,
    "MEDIUM": Severity.MEDIUM,
    "LOW": Severity.LOW,
    "UNKNOWN": Severity.UNKNOWN,
}


class TrivyParser(BaseParser):
    """Convert raw Trivy JSON results into ``Vulnerability`` objects.

    Trivy ``Results`` is a list of per-target result objects, each possibly
    containing ``Vulnerabilities`` and ``Secrets`` arrays.
    """

    def parse(self, raw_findings: list[dict[str, Any]]) -> list[Vulnerability]:
        results: list[Vulnerability] = []

        for result_block in raw_findings:
            target_file = result_block.get("Target", "unknown")

            # --- standard CVE vulnerabilities ---
            for vuln_entry in result_block.get("Vulnerabilities", []) or []:
                sev_str = vuln_entry.get("Severity", "UNKNOWN").upper()
                results.append(
                    Vulnerability(
                        scanner="trivy",
                        file=target_file,
                        line=0,  # Trivy does not provide line numbers for CVEs
                        severity=_SEVERITY_MAP.get(sev_str, Severity.UNKNOWN),
                        vuln_type="dependency_vulnerability",
                        description=(
                            f"{vuln_entry.get('VulnerabilityID', 'N/A')}: "
                            f"{vuln_entry.get('Title', vuln_entry.get('Description', 'No description'))}"
                        ),
                        raw=vuln_entry,
                    )
                )

            # --- secret findings (Trivy can also detect secrets) ---
            for secret_entry in result_block.get("Secrets", []) or []:
                results.append(
                    Vulnerability(
                        scanner="trivy",
                        file=target_file,
                        line=secret_entry.get("StartLine", 0),
                        severity=Severity.HIGH,
                        vuln_type="secret",
                        description=secret_entry.get("Title", "Secret detected"),
                        raw=secret_entry,
                    )
                )

        return results
