#!/usr/bin/env python3
"""Moruneva synthetic webhook failure-path demonstration. No external calls."""
import hashlib
import json
from pathlib import Path

SCENARIOS = [
    {"id": "missing-input", "label": "Missing required contact", "mode": "missing"},
    {"id": "duplicate-event", "label": "Duplicate webhook delivered twice", "mode": "duplicate"},
    {"id": "upstream-timeout", "label": "External provider times out", "mode": "timeout"},
    {"id": "false-ok", "label": "HTTP 200 response embeds an error", "mode": "body_error"},
    {"id": "partial-failure", "label": "CRM write succeeds; notification fails", "mode": "partial"},
    {"id": "happy-path", "label": "Normal authorized synthetic request", "mode": "normal"},
]


def legacy(events, mode):
    """Deliberately flawed illustrative implementation (not an actual client system)."""
    notifications = []
    stored = set()
    statuses = []
    for event in events:
        try:
            email = event["email"]
            stored.add(event["id"])
            if mode == "timeout":
                raise TimeoutError("simulated provider timeout")
            response = {"http_status": 200, "body": {"error": "quota_exhausted"}} if mode == "body_error" else {"http_status": 503 if mode == "partial" else 200, "body": {"ok": mode != "partial"}}
            if response["http_status"] == 200:
                notifications.append(email)
            # Bug: reports complete even after non-2xx or application-level failures
            statuses.append("completed")
        except (KeyError, TimeoutError) as exc:
            statuses.append("unhandled:" + type(exc).__name__)
    return {"statuses": statuses, "notifications": len(notifications), "crm_writes": len(stored)}


def guarded(events, mode):
    """Synthetic guarded implementation, not a certified production solution."""
    notifications = []
    stored = set()
    completed = set()
    statuses = []
    for event in events:
        identity = event.get("id")
        email = event.get("email", "")
        if not identity or not isinstance(email, str) or "@" not in email:
            statuses.append("rejected_invalid_input")
            continue
        if identity in completed:
            statuses.append("duplicate_skipped")
            continue
        stored.add(identity)
        if mode in ("timeout", "partial"):
            statuses.append("pending_retry")
            continue
        if mode == "body_error":
            statuses.append("needs_review")
            continue
        notifications.append(email)
        completed.add(identity)
        statuses.append("completed")
    return {"statuses": statuses, "notifications": len(notifications), "crm_writes": len(stored)}


def make_events(case):
    event = {"id": "synthetic-001", "email": "test@example.invalid"}
    if case == "missing":
        event.pop("email")
    if case == "duplicate":
        return [event.copy(), event.copy()]
    return [event]


def classify(case, result):
    flags = {
        "missing": result["statuses"] == ["rejected_invalid_input"] and result["notifications"] == 0,
        "duplicate": result["statuses"] == ["completed", "duplicate_skipped"] and result["notifications"] == 1,
        "timeout": result["statuses"] == ["pending_retry"] and result["notifications"] == 0,
        "body_error": result["statuses"] == ["needs_review"] and result["notifications"] == 0,
        "partial": result["statuses"] == ["pending_retry"] and result["crm_writes"] == 1 and result["notifications"] == 0,
        "normal": result["statuses"] == ["completed"] and result["notifications"] == 1,
    }
    return flags[case]


def main():
    rows = []
    for scenario in SCENARIOS:
        events = make_events(scenario["mode"])
        before = legacy(events, scenario["mode"])
        after = guarded(events, scenario["mode"])
        assert classify(scenario["mode"], after), scenario["id"]
        rows.append({
            "case_id": scenario["id"],
            "scenario": scenario["label"],
            "legacy_observed": before,
            "guarded_observed": after,
            "guarded_expected_check": "PASS",
        })
    # Ensure intentionally flawed baseline and corrected case are meaningfully different.
    assert sum(a["legacy_observed"] != a["guarded_observed"] for a in rows) >= 5
    raw = Path(__file__).read_bytes()
    evidence = {
        "project": "Moruneva synthetic webhook reliability demonstration",
        "date": "2026-10-22",
        "verification_type": "Local deterministic Python simulation, not live n8n, voice provider, or customer production testing",
        "code_sha256": hashlib.sha256(raw).hexdigest(),
        "external_api_calls": 0,
        "customer_records": 0,
        "scenarios_run": len(rows),
        "guarded_checks_passed": sum(r["guarded_expected_check"] == "PASS" for r in rows),
        "cases": rows,
    }
    output = Path(__file__).with_suffix(".json")
    output.write_text(json.dumps(evidence, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
    print(f"Verified {len(rows)}/{len(rows)} guarded checks. Evidence: {output.name}")
    print(f"SHA256: {evidence['code_sha256']}")


if __name__ == "__main__":
    main()