"""Command-line boundary for fail-closed validation checkpoint control."""

from __future__ import annotations

import argparse
import json
import pathlib
import sys
from typing import Any


ROOT = pathlib.Path(__file__).resolve().parents[1]
SRC = ROOT / "src"
if str(SRC) not in sys.path:
    sys.path.insert(0, str(SRC))

from reliability_core.validation_control import (  # noqa: E402
    CheckpointStore,
    ValidationStateError,
    readiness_digest,
    receipt_digest,
)


def load_json(path: pathlib.Path) -> Any:
    return json.loads(path.read_text(encoding="utf-8"))


def emit(value: Any) -> None:
    print(json.dumps(value, ensure_ascii=False, sort_keys=True, indent=2))


def build_parser() -> argparse.ArgumentParser:
    parser = argparse.ArgumentParser(
        description="Tiered validation planner with append-only checkpoints and safe resume"
    )
    commands = parser.add_subparsers(dest="command", required=True)

    init = commands.add_parser("init", help="create a new immutable validation plan")
    init.add_argument("--state", type=pathlib.Path, required=True)
    init.add_argument("--policy", type=pathlib.Path, required=True)
    init.add_argument("--change", type=pathlib.Path, required=True)
    init.add_argument("--bindings", type=pathlib.Path, required=True)
    init.add_argument("--tasks", type=pathlib.Path)

    inspect = commands.add_parser("inspect", help="verify the complete checkpoint chain")
    inspect.add_argument("--state", type=pathlib.Path, required=True)

    status = commands.add_parser("status", help="decide whether exact-state resume is allowed")
    status.add_argument("--state", type=pathlib.Path, required=True)
    status.add_argument("--policy", type=pathlib.Path, required=True)
    status.add_argument("--change", type=pathlib.Path, required=True)
    status.add_argument("--bindings", type=pathlib.Path, required=True)

    session = commands.add_parser("session", help="bind a fresh runtime-readiness session")
    session.add_argument("--state", type=pathlib.Path, required=True)
    session.add_argument("--readiness", type=pathlib.Path, required=True)
    session.add_argument("--session-id")

    record = commands.add_parser("record", help="append one immutable task receipt")
    record.add_argument("--state", type=pathlib.Path, required=True)
    record.add_argument("--receipt", type=pathlib.Path, required=True)

    digest = commands.add_parser("digest", help="calculate a canonical evidence digest")
    digest.add_argument("--kind", choices=("receipt", "readiness"), required=True)
    digest.add_argument("--input", type=pathlib.Path, required=True)

    return parser


def main(argv: list[str] | None = None) -> int:
    args = build_parser().parse_args(argv)
    try:
        if args.command == "init":
            tasks = load_json(args.tasks) if args.tasks else None
            store = CheckpointStore.initialize(
                args.state,
                policy=load_json(args.policy),
                change=load_json(args.change),
                bindings=load_json(args.bindings),
                tasks=tasks,
            )
            emit(store.inspect())
        elif args.command == "inspect":
            emit(CheckpointStore(args.state).inspect())
        elif args.command == "status":
            emit(
                CheckpointStore(args.state).resume_decision(
                    policy=load_json(args.policy),
                    change=load_json(args.change),
                    bindings=load_json(args.bindings),
                )
            )
        elif args.command == "session":
            event = CheckpointStore(args.state).open_session(
                load_json(args.readiness), session_id=args.session_id
            )
            emit(event)
        elif args.command == "record":
            event = CheckpointStore(args.state).record_result(load_json(args.receipt))
            emit(event)
        elif args.command == "digest":
            value = load_json(args.input)
            digest = receipt_digest(value) if args.kind == "receipt" else readiness_digest(value)
            emit({"kind": args.kind, "sha256": digest})
        else:  # pragma: no cover - argparse owns this boundary
            raise ValidationStateError("unknown_command")
        return 0
    except (OSError, UnicodeError, json.JSONDecodeError, ValidationStateError) as exc:
        emit({"verdict": "BLOCKED", "reason": str(exc), "fail_closed": True})
        return 2


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