#!/usr/bin/env python3
"""Offline parser-repair triage exercise; Python 3.9+, standard library only.

All rows are synthetic. The program makes no network requests, stores no data,
and changes no collector, proxy, schedule, or historical result. It separates a
local replay that corrects a labelled historical output from a new observation.
"""
from collections import Counter
import json


VALID_PERMISSION = {"allowed", "unknown", "denied"}
VALID_INPUT = {"retained_snapshot", "expired_snapshot", "missing"}
VALID_PARSE = {"affected", "unaffected"}


def decide(record):
    """Return one safe disposition for a synthetic record.

    A retained snapshot can be replayed only when retention and the separate
    replay purpose are both explicitly allowed. An expired or missing input can
    lead to a new observation only when the current task is needed and current
    request permission is explicitly allowed. A retained input with an unknown,
    denied, or absent replay permission fails closed; it does not automatically
    become a new request.
    """
    required = {"id", "parse", "input", "retention_permitted",
                "replay_permission", "context_complete", "current_needed",
                "current_permission"}
    if set(record) != required:
        raise ValueError("Each record needs exactly the declared audit fields")
    if record["parse"] not in VALID_PARSE or record["input"] not in VALID_INPUT:
        raise ValueError("Unknown parse or input state")
    if record["replay_permission"] not in VALID_PERMISSION or record["current_permission"] not in VALID_PERMISSION:
        raise ValueError("Replay and current permission must be allowed, unknown, or denied")
    if not isinstance(record["retention_permitted"], bool) or not isinstance(record["context_complete"], bool) or not isinstance(record["current_needed"], bool):
        raise ValueError("Boolean policy fields required")

    if record["parse"] == "unaffected":
        return {"id": record["id"], "decision": "SKIP", "reason": "parser path not affected", "observation_kind": None}
    if record["input"] == "retained_snapshot":
        if record["retention_permitted"] and record["replay_permission"] == "allowed" and record["context_complete"]:
            return {"id": record["id"], "decision": "REPLAY_LOCAL", "reason": "retention and replay permission allow a labelled historical correction", "observation_kind": "historical_correction"}
        return {"id": record["id"], "decision": "HOLD", "reason": "retained input lacks retention, replay permission, or complete context", "observation_kind": None}
    if record["current_needed"] and record["current_permission"] == "allowed":
        return {"id": record["id"], "decision": "RECOLLECT", "reason": "expired or missing input; explicitly allowed current observation is still needed", "observation_kind": "new_observation"}
    return {"id": record["id"], "decision": "HOLD", "reason": "expired or missing input, but no current need or explicit current permission", "observation_kind": None}


def fixture():
    return [
        {"id": "A", "parse": "affected", "input": "retained_snapshot", "retention_permitted": True, "replay_permission": "allowed", "context_complete": True, "current_needed": True, "current_permission": "allowed"},
        {"id": "B", "parse": "affected", "input": "expired_snapshot", "retention_permitted": False, "replay_permission": "denied", "context_complete": True, "current_needed": True, "current_permission": "allowed"},
        {"id": "C", "parse": "affected", "input": "missing", "retention_permitted": False, "replay_permission": "unknown", "context_complete": False, "current_needed": True, "current_permission": "allowed"},
        {"id": "D", "parse": "affected", "input": "missing", "retention_permitted": False, "replay_permission": "unknown", "context_complete": False, "current_needed": True, "current_permission": "unknown"},
        {"id": "E", "parse": "unaffected", "input": "retained_snapshot", "retention_permitted": True, "replay_permission": "allowed", "context_complete": True, "current_needed": False, "current_permission": "allowed"},
        {"id": "F", "parse": "affected", "input": "retained_snapshot", "retention_permitted": True, "replay_permission": "unknown", "context_complete": True, "current_needed": True, "current_permission": "allowed"},
    ]


def run():
    results = [decide(row) for row in fixture()]
    by_id = {row["id"]: row for row in results}
    assert by_id["A"]["decision"] == "REPLAY_LOCAL"
    assert by_id["A"]["observation_kind"] == "historical_correction"
    assert by_id["B"]["decision"] == "RECOLLECT"  # expiry blocks replay, not an allowed current observation
    assert by_id["C"]["decision"] == "RECOLLECT"
    assert by_id["C"]["observation_kind"] == "new_observation"
    assert by_id["D"]["decision"] == "HOLD"  # unknown permission never recollects
    assert by_id["E"]["decision"] == "SKIP"
    assert by_id["F"]["decision"] == "HOLD"  # unknown replay permission does not auto-recollect
    # Counterexamples: malformed policy, unapproved retention, and unknown replay permission fail closed.
    bad = dict(fixture()[0]); bad["current_permission"] = "maybe"
    try:
        decide(bad)
    except ValueError:
        pass
    else:
        raise AssertionError("invalid current permission vocabulary accepted")
    unapproved = dict(fixture()[0]); unapproved["retention_permitted"] = False
    assert decide(unapproved)["decision"] == "HOLD"
    unknown_replay = dict(fixture()[0]); unknown_replay["replay_permission"] = "unknown"
    assert decide(unknown_replay)["decision"] == "HOLD"
    counts = Counter(row["decision"] for row in results)
    return {"mode": "offline_synthetic_parser_repair", "network_requests": 0,
            "records": results, "decision_counts": dict(counts),
            "minimal_recollection_ids": [row["id"] for row in results if row["decision"] == "RECOLLECT"],
            "counterexamples_passed": 3,
            "limits": "Synthetic policy inputs only; no source permission, replay permission, retention state, parser correctness, current freshness, provider behavior, or business outcome is verified."}


if __name__ == "__main__":
    print(json.dumps(run(), indent=2))
