import re
from urllib.parse import parse_qs, urlparse

AQUA_REFERENCE_HOST = "avd.aquasec.com"
GITHUB_ADVISORY_URL = "https://github.com/advisories/{advisory_id}"
PROWLER_HUB_CHECK_URL = "https://hub.prowler.com/check/{check_id}"
_CVE_ID_PATTERN = re.compile(r"^CVE-\d{4}-\d+$", re.IGNORECASE)
_GHSA_ID_PATTERN = re.compile(r"^GHSA(?:-[a-z0-9]{4}){3}$", re.IGNORECASE)


def _dedupe_preserve_order(urls: list[str]) -> list[str]:
    seen: set[str] = set()
    ordered_urls: list[str] = []

    for url in urls:
        if not url or not url.strip():
            continue

        normalized_url = url.strip()
        if normalized_url in seen:
            continue

        seen.add(normalized_url)
        ordered_urls.append(normalized_url)

    return ordered_urls


def _is_aqua_reference(url: str) -> bool:
    return AQUA_REFERENCE_HOST in urlparse(url).netloc.lower()


def _build_cve_org_url(vulnerability_id: str) -> str:
    return f"https://www.cve.org/CVERecord?id={vulnerability_id.upper()}"


def build_finding_reference_url(finding_id: str) -> str:
    """Map a Trivy finding ID to a stable, real reference URL.

    - CVE-XXXX-NNNN  → cve.org record
    - GHSA-…         → github.com/advisories
    - everything else → hub.prowler.com/check/<id>, stripping a leading
      "AVD-" prefix because Prowler Hub indexes Trivy rules by the
      non-prefixed ID (e.g., "AWS-0001" not "AVD-AWS-0001").
    """
    normalized = finding_id.strip().upper()
    if _CVE_ID_PATTERN.match(normalized):
        return _build_cve_org_url(normalized)
    if _GHSA_ID_PATTERN.match(normalized):
        return GITHUB_ADVISORY_URL.format(advisory_id=normalized)
    hub_id = normalized[4:] if normalized.startswith("AVD-") else normalized
    return PROWLER_HUB_CHECK_URL.format(check_id=hub_id)


def _is_cve_org_url(url: str, vulnerability_id: str) -> bool:
    parsed_url = urlparse(url)
    if parsed_url.netloc.lower() != "www.cve.org":
        return False

    query_value = parse_qs(parsed_url.query).get("id", [""])[0]
    return query_value.upper() == vulnerability_id.upper()


def resolve_vulnerability_reference_urls(
    vulnerability_id: str,
    references: list[str] | None = None,
    primary_url: str = "",
) -> tuple[str, list[str]]:
    """Resolve non-Aqua vulnerability URLs, prioritizing official CVE destinations."""

    candidate_urls = list(references or [])
    if primary_url and primary_url not in candidate_urls:
        candidate_urls.append(primary_url)

    filtered_urls = _dedupe_preserve_order(
        [url for url in candidate_urls if not _is_aqua_reference(url)]
    )

    if not _CVE_ID_PATTERN.match(vulnerability_id):
        return "", filtered_urls

    cve_org_urls = [
        url for url in filtered_urls if _is_cve_org_url(url, vulnerability_id)
    ]

    recommendation_url = (
        cve_org_urls[0] if cve_org_urls else _build_cve_org_url(vulnerability_id)
    )

    return recommendation_url, [recommendation_url]
