#!/usr/bin/env python3
"""
rnn_backfill.py — one-time Rush show backfill for the RNN archive (MANUAL ONLY)

Off by default. Nothing is scheduled: estate_cron.py does not import or call this.
Without --confirm it only prints the plan (what is stored and what would be built).

It calls Joshua's own handler on Aura116, POST /api/rush-show-generator
{"action":"backfill","offset":N,"limit":L}, batch by batch until "complete".
That handler skips every date that already has a show (status "already_exists"),
so stored shows are never overwritten and nothing is deleted.

Usage:
  python3 scripts/rnn_backfill.py                 # dry run: status only, no writes
  python3 scripts/rnn_backfill.py --confirm       # run the backfill
  python3 scripts/rnn_backfill.py --confirm --limit 10 --max-batches 3

Target: AURA116_URL (shared Railway variable), else the Aura116 production host.

Authority: Joshua Lopez — DCGP.AI LLC — USPTO 19/555,951
"""

import argparse
import json
import os
import sys
import time
import urllib.error
import urllib.request

RNN_URL = os.environ.get("AURA116_URL", "https://aura116-production.up.railway.app").rstrip("/")
ROUTE = "/api/rush-show-generator"
TIMEOUT = 60


def call(method, body=None):
    data = json.dumps(body).encode() if body is not None else None
    headers = {"Content-Type": "application/json"} if data else {}
    req = urllib.request.Request(RNN_URL + ROUTE, data=data, headers=headers, method=method)
    try:
        with urllib.request.urlopen(req, timeout=TIMEOUT) as resp:
            return resp.status, json.loads(resp.read().decode() or "{}")
    except urllib.error.HTTPError as e:
        return e.code, {"error": e.read().decode()[:300]}
    except Exception as e:  # network, timeout, bad JSON
        return 0, {"error": str(e)[:300]}


def main():
    ap = argparse.ArgumentParser(description="Manual RNN show backfill (dry run unless --confirm)")
    ap.add_argument("--confirm", action="store_true", help="write missing shows (default: dry run)")
    ap.add_argument("--limit", type=int, default=25, help="weekdays per batch (default 25)")
    ap.add_argument("--offset", type=int, default=0, help="first weekday index (default 0 = 2026-05-10)")
    ap.add_argument("--max-batches", type=int, default=20, help="stop after this many batches")
    args = ap.parse_args()

    status, info = call("GET")
    print(f"[rnn-backfill] target {RNN_URL}{ROUTE}")
    print(f"[rnn-backfill] GET -> {status}; shows stored now: {info.get('total_shows', '?')}")
    if status != 200:
        print("[rnn-backfill] target not answering 200; stopping.")
        return 1

    if not args.confirm:
        print("[rnn-backfill] DRY RUN. Nothing written. Re-run with --confirm to backfill.")
        return 0

    offset = args.offset
    generated = existing = 0
    for n in range(args.max_batches):
        status, res = call("POST", {"action": "backfill", "offset": offset, "limit": args.limit})
        if status != 200 or not res.get("ok"):
            print(f"[rnn-backfill] batch {n + 1} offset {offset} -> {status} {res.get('error', '')}")
            return 1
        for r in res.get("results", []):
            if r.get("status") == "generated":
                generated += 1
            elif r.get("status") == "already_exists":
                existing += 1
        print(f"[rnn-backfill] batch {n + 1}: offset {offset}, processed {res.get('processed')}, "
              f"remaining {res.get('remaining')}")
        if res.get("complete"):
            break
        offset = res.get("next_offset", offset + args.limit)
        time.sleep(1)

    print(f"[rnn-backfill] done: {generated} generated, {existing} already stored (left as is).")
    return 0


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