#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""scripts.verify_callback_owner_contract — task-2553+49 AUTHORITATIVE CLI.

Runs the real runtime guards (NOT mocks) over a callback-owner contract
descriptor and prints the consolidated verdict. Used by the independent ANU
collector session to re-verify the §5.A/§5.C/§5.D guarantees against the
live entrypoints (``dispatch.core`` re-exports + anu_v3 runtime guards).

Exit code: 0 == PASS, 1 == FAIL, 2 == HOLD_FOR_CHAIR.

Usage:
  python3 scripts/verify_callback_owner_contract.py \
      --task-id task-2553+49 --executor-key <K> --collector-key <K> \
      --collector-role ANU --dispatch-cron D --normal-cron NC \
      --fallback-cron FB --chat 6937032012 [--anu-key c119085addb0f8b7]
  python3 scripts/verify_callback_owner_contract.py --fixture <path.json>
  python3 scripts/verify_callback_owner_contract.py --self-test
"""
from __future__ import annotations

import argparse
import json
import sys
from pathlib import Path

_ROOT = Path(__file__).resolve().parent.parent
if str(_ROOT) not in sys.path:
    sys.path.insert(0, str(_ROOT))


def _verify(args) -> dict:
    # Real entrypoint imports (dispatch.core is the REAL dispatch entrypoint
    # facade; anu_v3 modules are the runtime guards). No mocks.
    from dispatch.core import (
        guard_callback_registration,
        select_runtime_authoritative_verdict,
    )
    from anu_v3.callback_owner_validator import CallbackRegistrationBlocked
    from anu_v3.authoritative_verdict_selector import VerdictRecord

    anu_keys = tuple(args.anu_key) if args.anu_key else None
    out: dict = {"task_id": args.task_id}
    try:
        val, self_guard, allowed = guard_callback_registration(
            task_id=args.task_id,
            executor_key=args.executor_key,
            collector_key=args.collector_key,
            collector_owner_key=args.collector_key,
            collector_role=args.collector_role,
            dispatch_cron_id=args.dispatch_cron,
            normal_collector_cron_id=args.normal_cron,
            fallback_callback_cron_id=args.fallback_cron,
            chat_id=args.chat,
            prompt_claims_anu_collector=True,
            entry_path="cokacdir_cron_direct",
            anu_keys=anu_keys,
        )
        out["registration"] = {
            "verdict": val.verdict,
            "registration_allowed": allowed,
            "validation": val.to_json(),
            "self_collector_guard": self_guard.to_json(),
        }
    except CallbackRegistrationBlocked as exc:
        out["registration"] = {
            "verdict": "FAIL",
            "registration_allowed": False,
            "blocked": str(exc),
        }

    # Authoritative selector self-chain exclusion demonstration.
    self_chain = [
        VerdictRecord(
            kind="collector_result",
            verdict="PASS",
            task_id=args.task_id,
            executor_key=args.executor_key,
            collector_key=args.executor_key,
            collector_role="ANU",
            session_is_executor_self=True,
        )
    ]
    sel = select_runtime_authoritative_verdict(
        self_chain, task_id=args.task_id, anu_keys=anu_keys
    )
    out["authoritative_selector_self_chain_only"] = sel.to_json()

    reg_pass = out["registration"]["verdict"] == "PASS"
    overall = "PASS" if reg_pass else out["registration"]["verdict"]
    out["overall"] = overall
    return out


def _fixture_mode(path: Path) -> dict:
    data = json.loads(path.read_text(encoding="utf-8"))
    from dispatch.core import select_runtime_authoritative_verdict
    from anu_v3.authoritative_verdict_selector import VerdictRecord

    si = data.get("selector_input")
    if si is None:
        return {"error": "fixture has no selector_input", "fixture": str(path)}
    keys = tuple(data.get("anu_keys") or ["c119085addb0f8b7"])
    recs = [VerdictRecord(**r) for r in si["records"]]
    res = select_runtime_authoritative_verdict(
        recs, task_id=si["task_id"], anu_keys=keys
    )
    return {
        "fixture": str(path),
        "expected": data.get("expected"),
        "actual": res.to_json(),
    }


def _self_test() -> dict:
    from anu_v3.callback_owner_validator import (
        validate_callback_owner_runtime,
    )

    exec_self = validate_callback_owner_runtime(
        task_id="task-2553+49",
        executor_key="1e41a2324a3ccdd0",
        collector_key="1e41a2324a3ccdd0",
        collector_role="ANU",
        normal_collector_cron_id="NC",
        fallback_callback_cron_id="FB",
        dispatch_cron_id="D",
        chat_id="6937032012",
        prompt_claims_anu_collector=True,
        anu_keys=("c119085addb0f8b7",),
    )
    anu = validate_callback_owner_runtime(
        task_id="task-2553+49",
        executor_key="1e41a2324a3ccdd0",
        collector_key="c119085addb0f8b7",
        collector_role="ANU",
        normal_collector_cron_id="NC",
        fallback_callback_cron_id="FB",
        dispatch_cron_id="D",
        chat_id="6937032012",
        prompt_claims_anu_collector=True,
        anu_keys=("c119085addb0f8b7",),
    )
    ok = exec_self.verdict == "FAIL" and anu.verdict == "PASS"
    return {
        "self_test": "PASS" if ok else "FAIL",
        "executor_self_key_blocked": exec_self.verdict == "FAIL",
        "independent_anu_key_allowed": anu.verdict == "PASS",
    }


def main(argv=None) -> int:
    p = argparse.ArgumentParser(description=__doc__)
    p.add_argument("--task-id", default="task-2553+49")
    p.add_argument("--executor-key", default="")
    p.add_argument("--collector-key", default="")
    p.add_argument("--collector-role", default="ANU")
    p.add_argument("--dispatch-cron", default="D")
    p.add_argument("--normal-cron", default="NC")
    p.add_argument("--fallback-cron", default="FB")
    p.add_argument("--chat", default="6937032012")
    p.add_argument("--anu-key", action="append", default=[])
    p.add_argument("--fixture")
    p.add_argument("--self-test", action="store_true")
    a = p.parse_args(argv)

    if a.self_test:
        res = _self_test()
        print(json.dumps(res, ensure_ascii=False, indent=2))
        return 0 if res["self_test"] == "PASS" else 1
    if a.fixture:
        res = _fixture_mode(Path(a.fixture))
        print(json.dumps(res, ensure_ascii=False, indent=2))
        return 0
    res = _verify(a)
    print(json.dumps(res, ensure_ascii=False, indent=2))
    if res["overall"] == "PASS":
        return 0
    if res["overall"] == "HOLD_FOR_CHAIR":
        return 2
    return 1


if __name__ == "__main__":
    raise SystemExit(main())
