#!/usr/bin/env python3
"""kuma-regroup.py — move Uptime Kuma monitors into groups [#435]

Founder ruling 2026-09-02: no monitors at the root; use the existing
groups. Uses the uptime-kuma-api library — raw socket.io editMonitor with
a hand-built payload times out on this Kuma build (missing form fields
the server requires before acking; the lib sends the full UI-shaped
payload). dns_resolve_type="A" is passed to satisfy lib-side validation
for monitors where the field is None (harmless for non-dns types).

Env (from ~/.creds/uptime-kuma.env):
  UPTIME_KUMA_URL, UPTIME_KUMA_TOKEN

Usage (host — needs python-socketio-compatible env via lib):
  python3 kuma-regroup.py --dry-move 211:48 213:13
  python3 kuma-regroup.py --move 211:48 213:13
    id:groupid pairs. --move executes; --dry-move prints the plan only.

Verify afterwards with kuma-inventory.py (the lib's get_monitors does
not map the parent field — trust the raw monitorList view).
"""
import argparse
import os
import sys

from uptime_kuma_api import UptimeKumaApi


def main():
    ap = argparse.ArgumentParser()
    ap.add_argument("--move", nargs="+", default=[], metavar="ID:GROUPID")
    ap.add_argument("--dry-move", nargs="+", default=[], metavar="ID:GROUPID")
    args = ap.parse_args()

    pairs = [(int(a), int(b)) for a, b in (p.split(":") for p in (args.move or args.dry_move))]
    dry = bool(args.dry_move)

    api = UptimeKumaApi(os.environ["UPTIME_KUMA_URL"], timeout=30)
    rc = 0
    try:
        api.login_by_token(os.environ["UPTIME_KUMA_TOKEN"])
        monitors = {m["id"]: m for m in api.get_monitors()}
        for mid, gid in pairs:
            m = monitors.get(mid)
            if not m:
                print(f"SKIP {mid}: not found")
                rc = 1
                continue
            g = monitors.get(gid)
            gname = g["name"] if g else "?"
            if dry:
                print(f"DRY {mid} '{m['name']}' -> group {gid} '{gname}'")
                continue
            try:
                r = api.edit_monitor(mid, parent=gid, dns_resolve_type="A")
                ok = isinstance(r, dict) and ("Saved" in str(r.get("msg", "")))
                print(f"MOVE {mid} '{m['name']}' -> {gid} '{gname}': {r.get('msg') if ok else r}")
                if not ok:
                    rc = 1
            except Exception as e:  # noqa: BLE001 — per-move isolation, batch continues
                print(f"MOVE {mid} FAIL: {str(e)[:120]}")
                rc = 1
    finally:
        api.disconnect()
    return rc


if __name__ == "__main__":
    sys.exit(main())
