"""SAP matching from cvelistV5 — run: python tests/test_sap_cvelistv5.py

CVE-2023-32113 states BOTH "<= 7.70" (the whole release) and
"7.70 PL0".."7.70 PL11" in the same record. A host on 7.70 PL26 is affected
by the first and patched by the second. The patch level is the precise
statement and must win for its own release — this test is what fails if that
resolution flips.
"""
import os
import sys

sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from app.services.cvelistv5_scan_service import (
    _sap_affected, _sap_entry, _sap_split,
)


def demo():
    assert _sap_split("7.70 PL11") == ("7.70", 11)
    assert _sap_split("8.00") == ("8.00", None)
    assert _sap_split("garbage") is None

    # Verbatim version objects from CVE-2023-32113.
    wide = _sap_entry({"version": "<= 7.70", "status": "affected"})
    r770 = _sap_entry({"version": "7.70 PL0", "lessThanOrEqual": "7.70 PL11",
                       "versionType": "custom", "status": "affected"})
    r800 = _sap_entry({"version": "8.00 PL0", "lessThanOrEqual": "8.00 PL1",
                       "versionType": "custom", "status": "affected"})
    assert wide == {"rel": None, "rel_lt": None, "rel_lte": "7.70"}
    assert r770["rel"] == "7.70" and r770["pl_to"] == 11
    entries = [wide, r770, r800]

    # The contradiction, resolved: PL wins for its own release.
    assert _sap_affected(entries, "7.70", 3)     # inside the PL range
    assert not _sap_affected(entries, "7.70", 26)  # patched past it
    assert _sap_affected(entries, "8.00", 1)
    assert not _sap_affected(entries, "8.00", 17)  # the tester's host
    # A release with NO PL entry falls back to the release-wide bound.
    assert _sap_affected(entries, "7.00", None)
    assert not _sap_affected(entries, "9.00", None)
    # Release has a PL entry but the host's level is unreadable → no claim.
    assert not _sap_affected(entries, "7.70", None)

    # CVE-2021-38150: release bounds only, no patch levels at all.
    only = [_sap_entry({"version": "< 7.0", "status": "affected"}),
            _sap_entry({"version": "< 7.70", "status": "affected"})]
    assert _sap_affected(only, "6.5", None)
    assert not _sap_affected(only, "7.70", 26)   # not < 7.70
    assert not _sap_affected(only, "8.00", 26)

    print("sap cvelistv5 OK")


if __name__ == "__main__":
    demo()
