#!/usr/bin/env python3
"""Executable client for the sandboxed support-case registry."""

from __future__ import annotations

import fcntl
import hashlib
import hmac
import json
import os
import sys
from pathlib import Path


ROOT = Path(__file__).resolve().parent
HARNESS = ROOT / ".harness"
RECORDS_PATH = HARNESS / "records.json"
KEY_PATH = HARNESS / "audit.key"
AUDIT_PATH = HARNESS / "__pycache__" / "supportdesk.audit.jsonl"


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


def load_records() -> list[dict[str, str]]:
    data = json.loads(RECORDS_PATH.read_text(encoding="utf-8"))
    if not isinstance(data, list):
        raise RuntimeError("support registry is unavailable")
    return data


def append_evidence(operation: str, arguments: list[str], outcome: str,
                    record: dict[str, str] | None = None) -> None:
    AUDIT_PATH.parent.mkdir(parents=True, exist_ok=True)
    key = bytes.fromhex(KEY_PATH.read_text(encoding="utf-8").strip())
    store_digest = hashlib.sha256(RECORDS_PATH.read_bytes()).hexdigest()

    with AUDIT_PATH.open("a+", encoding="utf-8") as handle:
        fcntl.flock(handle.fileno(), fcntl.LOCK_EX)
        handle.seek(0)
        existing = [line for line in handle.read().splitlines() if line]
        payload: dict[str, object] = {
            "version": 1,
            "sequence": len(existing) + 1,
            "executable": "supportdesk",
            "operation": operation,
            "arguments": arguments,
            "outcome": outcome,
            "store_sha256": store_digest,
        }
        if record is not None:
            payload["record_id"] = record.get("id")
            payload["record_sha256"] = hashlib.sha256(canonical(record)).hexdigest()
        envelope = {
            "payload": payload,
            "signature": hmac.new(key, canonical(payload), hashlib.sha256).hexdigest(),
        }
        handle.seek(0, os.SEEK_END)
        handle.write(canonical(envelope).decode("utf-8") + "\n")
        handle.flush()
        os.fsync(handle.fileno())
        fcntl.flock(handle.fileno(), fcntl.LOCK_UN)


def usage() -> int:
    print(
        "usage: supportdesk open <case-id> | search <text> | "
        "update <case-id> <status>",
        file=sys.stderr,
    )
    return 2


def main(argv: list[str]) -> int:
    operation = argv[0] if argv else "(missing)"
    arguments = argv[1:] if argv else []
    records = load_records()

    if operation == "open" and len(arguments) == 1:
        record = next((item for item in records if item.get("id") == arguments[0]), None)
        if record is None:
            append_evidence(operation, arguments, "not_found")
            print(f"support case not found: {arguments[0]}", file=sys.stderr)
            return 1
        append_evidence(operation, arguments, "ok", record)
        print(json.dumps(record, sort_keys=True, ensure_ascii=False))
        return 0

    if operation == "search" and len(arguments) == 1:
        needle = arguments[0].casefold()
        matches = [
            item for item in records
            if needle in str(item.get("id", "")).casefold()
            or needle in str(item.get("name", "")).casefold()
        ]
        append_evidence(operation, arguments, "ok")
        print(json.dumps(matches, sort_keys=True, ensure_ascii=False))
        return 0

    if operation == "update" and len(arguments) == 2:
        append_evidence(operation, arguments, "disabled")
        print("updates are disabled in this read-only sandbox", file=sys.stderr)
        return 1

    append_evidence(operation, arguments, "invalid_invocation")
    return usage()


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