"""Invented CRM export audit, executed 2026-10-24. No vendor/API/customer data.

Run with Python 3: python3 replay.py
The complete inputs are below. This checks a tiny static package, not a real
export, API client, permission model, snapshot algorithm, or restoration.
"""
import hashlib
import json
from collections import Counter

expected_ids = {"C01", "C02", "C03", "C04", "C05", "C06"}
pages = [
    {"cursor": None, "next": "p2", "ids": ["C01", "C02", "C03"]},
    {"cursor": "p2", "next": "p3", "ids": ["C03", "C04", "C05"]},
]
required_fields = {"id", "owner_id", "opt_out"}
headers = {"id", "owner_id"}
expected_edges = {("C01", "D01"), ("C02", "D01"), ("C04", "D02")}
exported_edges = {("C01", "D01"), ("C04", "D02"), ("C05", "D99")}
deal_ids = {"D01", "D02"}
source_files = {"F01": b"signed proposal\n", "F02": b"renewal notes\n"}
package_files = {"F01": b"signed proposal"}

ids = [ident for page in pages for ident in page["ids"]]
counts = Counter(ids)
missing_edges = expected_edges - exported_edges
unexpected_edges = exported_edges - expected_edges
result = {
    "method": "synthetic static package audit; not a vendor test",
    "expected_contacts": len(expected_ids),
    "export_rows": len(ids),
    "distinct_contact_ids": len(counts),
    "duplicate_ids": sorted(k for k, v in counts.items() if v > 1),
    "missing_ids": sorted(expected_ids - counts.keys()),
    "unexpected_ids": sorted(counts.keys() - expected_ids),
    "unconsumed_next_cursor": pages[-1]["next"],
    "missing_required_columns": sorted(required_fields - headers),
    "expected_edges": len(expected_edges),
    "exported_edges": len(exported_edges),
    "missing_edges": [list(edge) for edge in sorted(missing_edges)],
    "unexpected_edges": [list(edge) for edge in sorted(unexpected_edges)],
    "dangling_edges": [list(edge) for edge in sorted(exported_edges)
                       if edge[0] not in counts or edge[1] not in deal_ids],
    "expected_files": len(source_files),
    "downloaded_files": len(package_files),
    "missing_files": sorted(source_files.keys() - package_files.keys()),
    "hash_mismatch_files": sorted(k for k in source_files.keys() & package_files.keys()
                                  if hashlib.sha256(source_files[k]).digest()
                                  != hashlib.sha256(package_files[k]).digest()),
}
assert result["export_rows"] == result["expected_contacts"] == 6
assert result["distinct_contact_ids"] == 5
assert result["missing_ids"] == ["C06"]
assert result["duplicate_ids"] == ["C03"]
assert result["missing_edges"] == [["C02", "D01"]]
assert result["dangling_edges"] == [["C05", "D99"]]
assert result["missing_files"] == ["F02"]
assert result["hash_mismatch_files"] == ["F01"]
print(json.dumps(result, indent=2, sort_keys=True))
