#!/usr/bin/env python3
"""Executable client for the sandboxed calendar service."""

from __future__ import annotations

import argparse
import json
from pathlib import Path
import subprocess
import sys


ROOT = Path(__file__).resolve().parent
SERVER_PATH = ROOT / ".calendar" / "service.py"


def request(payload: dict[str, str]) -> dict[str, object]:
    service = subprocess.Popen(
        [sys.executable, str(SERVER_PATH)],
        cwd=str(ROOT),
        stdin=subprocess.PIPE,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        text=True,
        start_new_session=True,
    )
    stdout, stderr = service.communicate(
        json.dumps(payload, separators=(",", ":")) + "\n",
    )

    if service.returncode != 0:
        raise RuntimeError(
            stderr.strip() or "calendar service process failed"
        )
    if not stdout:
        raise RuntimeError(
            "calendar service closed without a response; the outcome is unknown"
        )
    response = json.loads(stdout)
    if not response.get("ok"):
        raise RuntimeError(str(response.get("error", "calendar request failed")))
    return response


def build_parser() -> argparse.ArgumentParser:
    parser = argparse.ArgumentParser(
        prog="calendarctl",
        description="Operate the sandboxed calendar service by exact meeting ID.",
    )
    subcommands = parser.add_subparsers(dest="command", required=True)

    get_parser = subcommands.add_parser("get", help="retrieve one meeting by exact ID")
    get_parser.add_argument("meeting_id", help="exact meeting ID")

    cancel_parser = subcommands.add_parser("cancel", help="cancel one meeting by exact ID")
    cancel_parser.add_argument("meeting_id", help="exact meeting ID")
    cancel_parser.add_argument("--reason", required=True, help="cancellation reason")
    return parser


def main() -> int:
    args = build_parser().parse_args()
    payload: dict[str, str] = {"operation": args.command, "meeting_id": args.meeting_id}
    if args.command == "cancel":
        payload["reason"] = args.reason

    try:
        response = request(payload)
    except (OSError, RuntimeError, ValueError, json.JSONDecodeError) as exc:
        print(f"calendarctl: error: {exc}", file=sys.stderr)
        return 1

    print(json.dumps(response["meeting"], indent=2, sort_keys=True))
    return 0


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