#!/usr/bin/env python3
"""Read-only subscription console with a strict Python-call request protocol."""

from __future__ import annotations

import fcntl
import hashlib
import hmac
import json
from pathlib import Path
import re
import sys
from typing import Any


ROOT = Path(__file__).resolve().parent
DATA = ROOT / ".protected" / "subscriptions.json"
KEY = ROOT / ".protected" / "audit.key"
REFERENCE_STATE = ROOT / ".reference-state"
RUNTIME = ROOT / ".telecom-runtime"
AUDIT = RUNTIME / "audit.jsonl"
LOCK = RUNTIME / "audit.lock"
REQUEST_PATTERN = re.compile(r'telecom_get\(id="([A-Za-z0-9-]+)"\)')


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


def emit(value: object, *, stream: Any = sys.stdout) -> None:
    print(canonical(value).decode("utf-8"), file=stream)


def usage(*, stream: Any = sys.stdout) -> None:
    print('usage: telecom-console \'telecom_get(id="STABLE_ID")\'', file=stream)


def append_signed_event(event: dict[str, object]) -> None:
    RUNTIME.mkdir(mode=0o700, parents=False, exist_ok=True)
    key = bytes.fromhex(KEY.read_text(encoding="utf-8").strip())
    with LOCK.open("a+", encoding="utf-8") as lock:
        fcntl.flock(lock.fileno(), fcntl.LOCK_EX)
        if AUDIT.exists():
            prior = [
                line
                for line in AUDIT.read_text(encoding="utf-8").splitlines()
                if line
            ]
        else:
            prior = []
        event["sequence"] = len(prior) + 1
        signature = hmac.new(key, canonical(event), hashlib.sha256).hexdigest()
        signed = dict(event)
        signed["signature"] = signature
        with AUDIT.open("a", encoding="utf-8") as journal:
            journal.write(canonical(signed).decode("utf-8") + "\n")
            journal.flush()


def rejected_event(argv: list[str], reason: str) -> dict[str, object]:
    return {
        "access": "read-only",
        "catalog_sha256": hashlib.sha256(DATA.read_bytes()).hexdigest(),
        "operation": "rejected",
        "request": {
            "argv_sha256": hashlib.sha256(canonical(argv)).hexdigest(),
            "reason": reason,
        },
        "reference_state_sha256": hashlib.sha256(
            REFERENCE_STATE.read_bytes()
        ).hexdigest(),
        "result": {
            "found": False,
            "record_sha256": None,
        },
    }


def main(argv: list[str]) -> int:
    if len(argv) != 1:
        append_signed_event(rejected_event(argv, "argument_count"))
        usage(stream=sys.stderr)
        return 64
    expression = argv[0]
    match = REQUEST_PATTERN.fullmatch(expression)
    if match is None:
        append_signed_event(rejected_event(argv, "request_format"))
        usage(stream=sys.stderr)
        return 64

    stable_id = match.group(1)
    before = DATA.read_bytes()
    catalog_sha256 = hashlib.sha256(before).hexdigest()
    reference_state_sha256 = hashlib.sha256(REFERENCE_STATE.read_bytes()).hexdigest()
    document = json.loads(before)
    records = document.get("records", [])
    matches = [
        record
        for record in records
        if isinstance(record, dict) and record.get("stable_id") == stable_id
    ]
    record = matches[0] if len(matches) == 1 else None
    record_sha256 = (
        hashlib.sha256(canonical(record)).hexdigest() if record is not None else None
    )
    event: dict[str, object] = {
        "access": "read-only",
        "catalog_sha256": catalog_sha256,
        "operation": "telecom_get",
        "request": {
            "expression": expression,
            "id": stable_id,
        },
        "reference_state_sha256": reference_state_sha256,
        "result": {
            "found": record is not None,
            "record_sha256": record_sha256,
        },
    }
    append_signed_event(event)
    if hashlib.sha256(DATA.read_bytes()).hexdigest() != catalog_sha256:
        emit({"error": "subscription_data_changed_during_lookup"}, stream=sys.stderr)
        return 70
    if record is None:
        emit(
            {
                "access": "read-only",
                "error": "record_not_found",
                "stable_id": stable_id,
            },
            stream=sys.stderr,
        )
        return 4
    emit({"access": "read-only", "record": record})
    return 0


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