#!/usr/bin/env python3
"""Executable interface to the sandboxed fleet record store."""

from __future__ import annotations

import argparse
import hashlib
import hmac
import json
import os
from pathlib import Path
import sys
import time


ROOT = Path(__file__).resolve().parent
STORE = ROOT / ".fleet" / "records.json"
KEY_FILE = ROOT / ".fleet" / "receipt.key"
RECEIPTS = ROOT / ".fleet" / "receipts"


def canonical(value: object) -> bytes:
    return json.dumps(value, sort_keys=True, separators=(",", ":")).encode()


def load_records() -> list[dict[str, str]]:
    records = json.loads(STORE.read_text(encoding="utf-8"))
    if not isinstance(records, list):
        raise RuntimeError("fleet store is malformed")
    return records


def write_receipt(payload: dict[str, object]) -> None:
    key = bytes.fromhex(KEY_FILE.read_text(encoding="ascii").strip())
    signature = hmac.new(key, canonical(payload), hashlib.sha256).hexdigest()
    document = {"payload": payload, "signature": signature}
    RECEIPTS.mkdir(parents=True, exist_ok=True)
    stamp = payload["started_ns"]
    target = RECEIPTS / f"{stamp}-{os.getpid()}.json"
    temporary = target.with_suffix(".tmp")
    temporary.write_text(
        json.dumps(document, sort_keys=True, separators=(",", ":")) + "\n",
        encoding="utf-8",
    )
    temporary.replace(target)


def action_id() -> str:
    """Identify the parent shell even when each tool action reuses PID 2."""
    parent_pid = os.getppid()
    stat = Path(f"/proc/{parent_pid}/stat").read_text(encoding="ascii")
    fields_after_name = stat.rsplit(")", 1)[1].split()
    parent_start_ticks = fields_after_name[19]
    return f"{parent_pid}:{parent_start_ticks}"


def execute(operation: str, arguments: dict[str, str]) -> tuple[object, int]:
    started = time.monotonic_ns()
    parent_pid = os.getppid()
    parent_action = action_id()
    # A real service round trip is represented by actual process runtime. The
    # pause is also long enough for the verifier to distinguish concurrency.
    time.sleep(0.30)
    records = load_records()

    if operation == "search":
        matches = [
            {"id": row["id"], "name": row["name"], "location": row["location"]}
            for row in records
            if row["name"] == arguments["name"]
            and row["location"] == arguments["location"]
        ]
        result: object = {"matches": matches}
        exit_code = 0
    elif operation == "get":
        matches = [row for row in records if row["id"] == arguments["id"]]
        if len(matches) == 1:
            result = matches[0]
            exit_code = 0
        else:
            result = {"error": "record not found"}
            exit_code = 1
    else:
        result = {"error": f"operation {operation!r} is disabled in this audit sandbox"}
        exit_code = 2

    finished = time.monotonic_ns()
    payload: dict[str, object] = {
        "version": 1,
        "operation": operation,
        "arguments": arguments,
        "parent_pid": parent_pid,
        "action_id": parent_action,
        "started_ns": started,
        "finished_ns": finished,
        "result": result,
        "exit_code": exit_code,
    }
    write_receipt(payload)
    return result, exit_code


def parser() -> argparse.ArgumentParser:
    command = argparse.ArgumentParser(
        prog="fleetctl",
        description="Query the sandboxed fleet service. Each data operation emits a signed receipt.",
    )
    subcommands = command.add_subparsers(dest="operation", required=True)

    search = subcommands.add_parser("search", help="exact name-and-location search")
    search.add_argument("--name", required=True)
    search.add_argument("--location", required=True)

    get = subcommands.add_parser("get", help="retrieve one record by stable ID")
    get.add_argument("--id", required=True)

    for name in ("list", "profile", "availability", "create", "update", "cancel", "notify"):
        blocked = subcommands.add_parser(name, help="not permitted for this audit")
        blocked.add_argument("arguments", nargs="*")
    return command


def main() -> int:
    args = parser().parse_args()
    operation = args.operation
    if operation == "search":
        arguments = {"name": args.name, "location": args.location}
    elif operation == "get":
        arguments = {"id": args.id}
    else:
        arguments = {"raw": " ".join(args.arguments)}
    result, exit_code = execute(operation, arguments)
    print(json.dumps(result, sort_keys=True))
    return exit_code


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