from __future__ import annotations

import argparse
import json
import secrets
from pathlib import Path

from relay_gateway.keys import hash_token, CHANNELS_FOR_LEVEL


def _read(path: Path) -> dict:
    try:
        return json.loads(Path(path).read_text(encoding="utf-8"))
    except (FileNotFoundError, json.JSONDecodeError):
        return {}


def _write(path: Path, body: dict) -> None:
    Path(path).write_text(json.dumps(body, indent=2), encoding="utf-8")


def add_key(path: Path, *, name: str, level: str) -> str:
    if level not in CHANNELS_FOR_LEVEL:
        raise ValueError(f"level must be one of {sorted(CHANNELS_FOR_LEVEL)}")
    token = secrets.token_urlsafe(32)
    body = _read(path)
    body[hash_token(token)] = {"name": name, "level": level}
    _write(path, body)
    return token


def list_keys(path: Path) -> list[dict]:
    return [{"hash": h, **meta} for h, meta in _read(path).items()]


def revoke(path: Path, name: str) -> int:
    body = _read(path)
    to_remove = [h for h, meta in body.items() if meta.get("name") == name]
    for h in to_remove:
        del body[h]
    _write(path, body)
    return len(to_remove)


def main() -> None:
    ap = argparse.ArgumentParser(description="Manage relay gateway keys")
    ap.add_argument("--file", required=True, type=Path)
    sub = ap.add_subparsers(dest="cmd", required=True)
    a = sub.add_parser("add"); a.add_argument("--name", required=True); a.add_argument("--level", required=True)
    sub.add_parser("list")
    r = sub.add_parser("revoke"); r.add_argument("--name", required=True)
    args = ap.parse_args()
    if args.cmd == "add":
        token = add_key(args.file, name=args.name, level=args.level)
        print(f"Token for {args.name!r} (level={args.level}) — store it now, shown once:\n{token}")
    elif args.cmd == "list":
        for e in list_keys(args.file):
            print(f"{e['name']:20s} {e['level']:4s} {e['hash'][:12]}…")
    elif args.cmd == "revoke":
        print(f"Removed {revoke(args.file, args.name)} key(s) named {args.name!r}")


if __name__ == "__main__":
    main()
