"""Authoritative worker status transitions for one persisted team-state."""
from __future__ import annotations

import argparse
import json
import sys
from pathlib import Path

from .dispatch_state import DispatchError, WORKER_STATUSES, transition_worker_status


def _validated_team_state_path(value: str) -> Path:
    path = Path(value).resolve()
    if not any(parent.name == ".okstra" for parent in (path.parent, *path.parents)):
        raise DispatchError(
            f"team-state is outside a project .okstra directory: {path}"
        )
    return path


_CLI_EPILOG = r"""Usage:
  okstra worker-state transition --team-state <path> --worker <worker-id> \
    --status <in-progress|completed|timeout|error|not-run> \
    [--reason <text>] [--model <execution-value>]

in-progress records startedAt and clears endedAt. completed, timeout, and error
record endedAt. timeout, error, and not-run require --reason.
"""
_CLI_DESCRIPTION = "Atomically transition persisted worker status."


def _parser() -> argparse.ArgumentParser:
    parser = argparse.ArgumentParser(
        description=_CLI_DESCRIPTION,
        epilog=_CLI_EPILOG,
        formatter_class=argparse.RawDescriptionHelpFormatter,
        prog="okstra worker-state")
    commands = parser.add_subparsers(dest="command", required=True)
    transition = commands.add_parser(
        "transition", help="atomically transition one worker status"
    )
    transition.add_argument("--team-state", required=True)
    transition.add_argument("--worker", required=True)
    transition.add_argument("--status", required=True, choices=sorted(WORKER_STATUSES))
    transition.add_argument("--reason", default="")
    transition.add_argument("--model", default="")
    return parser


def main(argv: list[str] | None = None) -> int:
    parser = _parser()
    args = parser.parse_args(argv)
    try:
        team_state_path = _validated_team_state_path(args.team_state)
        transition_worker_status(
            team_state_path,
            args.worker,
            args.status,
            args.reason,
            model_execution_value=args.model,
        )
    except DispatchError as exc:
        print(f"error: {exc}", file=sys.stderr)
        return 1
    print(
        json.dumps(
            {
                "ok": True,
                "teamStatePath": str(team_state_path),
                "workerId": args.worker,
                "status": args.status,
            },
            ensure_ascii=False,
        )
    )
    return 0


if __name__ == "__main__":
    raise SystemExit(main(sys.argv[1:]))
