"""Unit tests for the CVE detector (mocked OSV API)."""
from __future__ import annotations

from unittest.mock import AsyncMock, patch

import pytest

from pyguard.detectors.cve import find_cves
from pyguard.models import Severity

_MOCK_VULN = {
    "id": "GHSA-xxxx-yyyy-zzzz",
    "aliases": ["CVE-2024-12345"],
    "summary": "Remote code execution via crafted input",
    "details": "An attacker can execute arbitrary code.",
    "affected": [
        {
            "package": {"name": "vulnerable-pkg", "ecosystem": "PyPI"},
            "ecosystem_specific": {"severity": "HIGH"},
            "ranges": [{"type": "ECOSYSTEM", "events": [{"fixed": "2.0.0"}]}],
        }
    ],
    "severity": [],
    "database_specific": {},
}


@pytest.mark.asyncio
async def test_cve_found_returns_finding():
    with patch(
        "pyguard.detectors.cve.query_vulnerabilities",
        new=AsyncMock(return_value=[_MOCK_VULN]),
    ):
        with patch("pyguard.detectors.cve.get_default_cache") as mock_cache:
            mock_cache.return_value.get.return_value = None
            mock_cache.return_value.set.return_value = None
            findings = await find_cves("vulnerable-pkg", "1.9.0")

    assert len(findings) == 1
    assert findings[0].cve_id == "CVE-2024-12345"
    assert findings[0].severity == Severity.HIGH
    assert "2.0.0" in (findings[0].remediation or "")


@pytest.mark.asyncio
async def test_no_cves_returns_empty():
    with patch(
        "pyguard.detectors.cve.query_vulnerabilities",
        new=AsyncMock(return_value=[]),
    ):
        with patch("pyguard.detectors.cve.get_default_cache") as mock_cache:
            mock_cache.return_value.get.return_value = None
            mock_cache.return_value.set.return_value = None
            findings = await find_cves("safe-pkg", "1.0.0")

    assert findings == []


@pytest.mark.asyncio
async def test_latest_version_skipped():
    findings = await find_cves("some-pkg", "latest")
    assert findings == []
