#!/usr/bin/env python3
"""Produce a bounded, offline record from a licensed TraceMint source checkout.

No product implementation is bundled here. The two fixture Dockerfiles are
scanned by the actual product function, while the authored SARIF and CSV rows
exercise its actual parsers. These are configuration-rule / parser checks,
not a scan service, AI evaluation or certification of a deployment.
"""
from __future__ import annotations

import argparse
import hashlib
import importlib.metadata
import json
import platform
import subprocess
import sys
import time
from datetime import datetime, timezone
from pathlib import Path

BASELINE = "9174a1c9bfbe7147bb59d88ce1d2ea89f1807bc7"
SITE_ROOT = Path(__file__).resolve().parents[1]
EXPECTED_INPUTS = {'dockerfiles/risk.Dockerfile': 'b0c5cf2d893f7621cccb34ae0a0ab329b07578e1ad5a8928f7bd8d47f6ca3d18', 'dockerfiles/control.Dockerfile': '81ae20513dab0e591f6670727d59b0d35d25208e45847cbd600ac354b502183c', 'minimal.sarif': '2e76325485cd47f8e7d74c32a998e255c25823c847ce6b08217d7a7e6e178564', 'minimal.csv': '7ddb85c1ac9a97ca799ed81cd4133a4e9d756d4eafb7e07c158985b3631f0f8a', 'LICENSE.txt': '580b67a3ae4823a27143c5026b49e79ea084686c2c51ed0fb2fa5a5e5ed79d97'}


def digest(data: bytes) -> str:
    return hashlib.sha256(data).hexdigest()


def main() -> None:
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("--product-root", type=Path, required=True)
    parser.add_argument("--product-commit", default=BASELINE)
    parser.add_argument("--fixtures", type=Path, default=SITE_ROOT / "public/downloads/evaluation-fixtures")
    parser.add_argument("--output", type=Path, default=SITE_ROOT / "public/downloads/evaluation-example-results.json")
    args = parser.parse_args()
    product = args.product_root.resolve(strict=True)
    fixtures = args.fixtures.resolve(strict=True)
    commit = args.product_commit
    # Do not accept a ref expression or call a shell with operator input.
    if len(commit) != 40 or any(c not in "0123456789abcdef" for c in commit):
        raise SystemExit("--product-commit must be a complete lowercase Git SHA")

    for relative, expected in EXPECTED_INPUTS.items():
        if digest((fixtures / relative).read_bytes()) != expected:
            raise SystemExit(f"Fixture bytes differ from this recorded example: {relative}")

    network_attempts: list[str] = []

    def deny_network(event: str, _args: tuple) -> None:
        if event in {"socket.connect", "socket.connect_ex", "socket.getaddrinfo", "socket.sendto"}:
            network_attempts.append(event)
            raise RuntimeError("Network access is disabled for this local example")

    sys.addaudithook(deny_network)
    sys.dont_write_bytecode = True
    sys.path[:0] = [str(product / "api"), str(product)]
    from services.supply_chain_posture import _scan_local_container_iac
    from tracemint_lib.vendor_triage.importers import _import_generic_csv, _import_sarif

    started = datetime.now(timezone.utc).isoformat()
    tick = time.perf_counter()
    findings, inventory = _scan_local_container_iac(fixtures / "dockerfiles")
    scan_seconds = time.perf_counter() - tick
    tick = time.perf_counter()
    sarif = [item.to_dict() for item in _import_sarif(str(fixtures / "minimal.sarif"))]
    generic_csv = [item.to_dict() for item in _import_generic_csv(str(fixtures / "minimal.csv"))]
    import_seconds = time.perf_counter() - tick

    # Prove source identity from bytes, never infer it from checkout HEAD.
    # Retain product-relative paths only; do not publish local filesystem paths.
    source_files = {}
    for module in list(sys.modules.values()):
        module_path = getattr(module, "__file__", None)
        if not module_path:
            continue
        path = Path(module_path).resolve()
        if path.suffix != ".py" or not path.is_relative_to(product):
            continue
        relative = path.relative_to(product).as_posix()
        if not relative.startswith(("api/services/", "tracemint_lib/")):
            continue
        raw = path.read_bytes()
        original = subprocess.run(
            ["git", "-C", str(product), "show", f"{commit}:{relative}"],
            check=True, capture_output=True, timeout=15,
        ).stdout
        if raw != original:
            raise SystemExit(f"Source differs from the requested product commit: {relative}")
        source_files[relative] = {"sha256": digest(raw), "matches_commit": True}

    inputs = {}
    for relative in ["dockerfiles/risk.Dockerfile", "dockerfiles/control.Dockerfile", "minimal.sarif", "minimal.csv", "LICENSE.txt"]:
        raw = (fixtures / relative).read_bytes()
        inputs[relative] = {"sha256": digest(raw), "bytes": len(raw)}
    if inventory["scanned_file_count"] != 2 or len(findings) != 1:
        raise SystemExit("Unexpected fixture result; inspect the product output before publishing")
    if findings[0]["rule_id"] != "dockerfile_root_user" or findings[0]["target"] != "risk.Dockerfile":
        raise SystemExit("Unexpected finding identity")
    if len(sarif) != 1 or len(generic_csv) != 1:
        raise SystemExit("Expected one normalized row per import fixture")
    for records in (sarif, generic_csv):
        if records[0]["file_path"] != "src/fixture.py" or records[0]["line_start"] != 4:
            raise SystemExit("Importer location mapping changed")
    if network_attempts:
        raise SystemExit("A network call was attempted")
    payload = {
        "schema_version": "tracemint.website-evaluation-example.v1",
        "recorded_at": started,
        "scope": "One local deterministic configuration-rule run and two parser-only imports on authored CC0 fixtures.",
        "product_source": {"commit": commit, "identity_method": "Every imported product Python module compared byte-for-byte with git show COMMIT:PATH", "files": dict(sorted(source_files.items()))},
        "runner": {"path": "scripts/run-evaluation-example.py", "sha256": digest(Path(__file__).read_bytes())},
        "environment": {"python": platform.python_version(), "os": platform.system(), "os_release": platform.release(), "architecture": platform.machine(), "dependencies": {name: importlib.metadata.version(name) for name in ("PyYAML", "defusedxml")}},
        "inputs": inputs,
        "configuration": {"scan_entrypoint": "services.supply_chain_posture._scan_local_container_iac", "parser_entrypoints": ["tracemint_lib.vendor_triage.importers._import_sarif", "tracemint_lib.vendor_triage.importers._import_generic_csv"], "network_guard": "Python audit hook denies socket connect, DNS resolution and sendto", "network_attempts": 0, "model_inference": False, "application_service_started": False},
        "observation": {"scan_elapsed_seconds": scan_seconds, "parser_elapsed_seconds": import_seconds, "timing_scope": "One invocation per check; excludes Python startup, imports, provenance checks and file writing. Not a throughput benchmark.", "configuration_scan": {"inventory": inventory, "findings": findings}, "parser_imports": {"sarif": sarif, "generic_csv": generic_csv}},
        "limits": ["No AI model was invoked; no model accuracy, precision, recall or runtime claim follows.", "The Dockerfiles were read as text. No image was built and no running container or cluster was inspected.", "Zero findings for the control fixture means no matching rule in this tiny input, not a generally secure image.", "The authored SARIF and CSV records only exercise field mapping. Source enrichment, AI triage, upload limits and the API worker boundary were not tested.", "The product checkout must be separately licensed. No product implementation or model is redistributed."]
    }
    encoded = json.dumps(payload, indent=2, ensure_ascii=False) + "\n"
    if str(product) in encoded or str(SITE_ROOT) in encoded or str(fixtures) in encoded:
        raise SystemExit("Refusing to publish an absolute local source path")
    args.output.parent.mkdir(parents=True, exist_ok=True)
    args.output.write_text(encoded, encoding="utf-8")
    print(json.dumps({"findings": len(findings), "scanned_files": inventory["scanned_file_count"], "sarif_rows": len(sarif), "csv_rows": len(generic_csv), "source_files_verified": len(source_files), "network_attempts": 0, "output_sha256": digest(encoded.encode())}))


if __name__ == "__main__":
    main()
