"""Tests for reproducible supply-chain policy decisions."""

from __future__ import annotations

import importlib.util
from datetime import date
from pathlib import Path


ROOT = Path(__file__).parents[1]
SCRIPT = ROOT / "scripts" / "check_supply_chain_policy.py"
SPEC = importlib.util.spec_from_file_location("check_supply_chain_policy", SCRIPT)
assert SPEC is not None and SPEC.loader is not None
MODULE = importlib.util.module_from_spec(SPEC)
SPEC.loader.exec_module(MODULE)


def _policy() -> dict[str, object]:
    return {
        "schema_version": 1,
        "vulnerability": {
            "fail_severities": ["unknown", "low", "medium", "high", "critical"],
            "max_fixed_suppression_days": 7,
            "max_unfixed_suppression_days": 90,
            "suppressions": [],
        },
        "secret": {
            "report_redaction_percent": 100,
            "max_suppression_days": 30,
            "suppressions": [],
        },
        "license": {
            "allowed_expressions": ["MIT"],
            "excluded_packages": ["obliteratus"],
        },
    }


def test_committed_policy_is_valid():
    policy = MODULE._read_json(ROOT / "ci" / "supply-chain-policy.json")
    assert MODULE.validate_policy(policy) == []


def test_policy_rejects_expired_and_overlong_suppressions():
    policy = _policy()
    policy["vulnerability"]["suppressions"] = [
        {
            "id": "GHSA-example",
            "reason": "temporary",
            "approved_on": "2026-01-01",
            "expires": "2026-01-10",
            "fix_available": True,
        },
    ]
    failures = MODULE.validate_policy(policy, today=date(2026, 1, 11))

    assert "suppression[0] expired on 2026-01-10" in failures
    assert "suppression[0] exceeds its 7-day maximum" in failures


def test_audit_blocks_every_unsuppressed_vulnerability():
    evidence = {
        "vulnerabilities": [
            {"id": "GHSA-example", "aliases": ["CVE-example"], "fix_versions": ["2.0"]},
        ],
        "adverse_statuses": [],
    }
    decision = MODULE.evaluate_audit(_policy(), evidence, scanner_status=1)

    assert decision["passed"] is False
    assert decision["failures"] == ["unsuppressed vulnerability: GHSA-example"]


def test_audit_rejects_unexplained_scanner_failure():
    evidence = {"vulnerabilities": [], "adverse_statuses": []}

    decision = MODULE.evaluate_audit(_policy(), evidence, scanner_status=1)

    assert decision["passed"] is False
    assert decision["failures"] == [
        "uv audit returned failure without reviewable findings",
    ]


def test_audit_accepts_bounded_alias_suppression():
    policy = _policy()
    policy["vulnerability"]["suppressions"] = [
        {
            "id": "CVE-example",
            "reason": "upgrade lands this week",
            "approved_on": "2026-01-01",
            "expires": "2026-01-08",
            "fix_available": True,
        },
    ]
    evidence = {
        "vulnerabilities": [
            {"id": "GHSA-example", "aliases": ["CVE-example"], "fix_versions": ["2.0"]},
        ],
        "adverse_statuses": [],
    }
    decision = MODULE.evaluate_audit(
        policy,
        evidence,
        scanner_status=1,
        today=date(2026, 1, 2),
    )

    assert decision["passed"] is True
    assert decision["suppressed"] == ["GHSA-example"]


def test_audit_rejects_stale_fixability_claim():
    policy = _policy()
    policy["vulnerability"]["suppressions"] = [
        {
            "id": "GHSA-example",
            "reason": "waiting for a fix",
            "approved_on": "2026-01-01",
            "expires": "2026-03-01",
            "fix_available": False,
        },
    ]
    evidence = {
        "vulnerabilities": [{"id": "GHSA-example", "fix_versions": ["2.0"]}],
        "adverse_statuses": [],
    }
    decision = MODULE.evaluate_audit(
        policy,
        evidence,
        scanner_status=1,
        today=date(2026, 1, 2),
    )

    assert decision["passed"] is False
    assert any("fixability is stale" in failure for failure in decision["failures"])


def test_license_gate_is_exact_and_excludes_first_party_package():
    inventory = [
        {"Name": "obliteratus", "License": "AGPL-3.0-or-later"},
        {"Name": "safe", "License": "MIT"},
        {"Name": "unknown", "License": "UNKNOWN"},
    ]
    decision = MODULE.evaluate_licenses(_policy(), inventory)

    assert decision["passed"] is False
    assert decision["checked_packages"] == 2
    assert decision["failures"] == ["unapproved license expression for unknown: UNKNOWN"]


def test_secret_gate_requires_redaction_even_for_suppressed_finding():
    policy = _policy()
    policy["secret"]["suppressions"] = [
        {
            "fingerprint": "file:rule:1",
            "reason": "documented fixture",
            "approved_on": "2026-01-01",
            "expires": "2026-01-15",
        },
    ]
    report = [
        {
            "Fingerprint": "file:rule:1",
            "Secret": "not-redacted",
            "Match": "token=not-redacted",
        },
    ]
    decision = MODULE.evaluate_secrets(
        policy,
        report,
        scanner_status=1,
        today=date(2026, 1, 2),
    )

    assert decision["passed"] is False
    assert any("not fully redacted" in failure for failure in decision["failures"])


def test_bind_sbom_adds_exact_release_artifact_hash(tmp_path):
    artifact = tmp_path / "OBLITERATUS-deadbeef.zip"
    artifact.write_bytes(b"source snapshot")
    sbom = {
        "bomFormat": "CycloneDX",
        "specVersion": "1.5",
        "metadata": {"component": {"name": "obliteratus"}},
    }

    bound = MODULE.bind_sbom(sbom, artifact)

    component = bound["metadata"]["component"]
    assert component["hashes"] == [
        {
            "alg": "SHA-256",
            "content": "41637c7875947b50775c0ab2bb30a28b292be748376a5713eb8f527d9953433c",
        },
    ]
    assert component["properties"] == [
        {"name": "obliteratus:release-artifact", "value": artifact.name},
    ]
