#!/usr/bin/env python3
"""Nightly tape ingest (daily.sh): pull closed RTDS segments off the
wwf-recorder volume into live/rtds.duckdb, delete on the box ONLY after the
inserted row count matches. Own DB file on purpose — must never contend with
cache.duckdb's single-writer lock (2026-07-17 collision). Transport is
`flyctl ssh console` + base64 (no ingress on the recorder by design)."""
import base64
import gzip
import json
import os
import subprocess
import time

HERE = os.path.dirname(os.path.abspath(__file__))
DB = os.path.join(HERE, "..", "live", "rtds.duckdb")
APP, SEG = "wwf-recorder", "/data/segments"


def box(cmd):
    r = subprocess.run(["flyctl", "ssh", "console", "-a", APP, "-C",
                        f"bash -c '{cmd}'"], capture_output=True, text=True,
                       timeout=300)
    return r.stdout


def main():
    import duckdb
    con = duckdb.connect(DB)
    con.execute("""CREATE TABLE IF NOT EXISTS trades(
        ts DOUBLE, wallet VARCHAR, asset VARCHAR, cond VARCHAR, side VARCHAR,
        price DOUBLE, size DOUBLE, tx VARCHAR, title VARCHAR)""")
    con.execute("""CREATE TABLE IF NOT EXISTS ingested(
        segment VARCHAR PRIMARY KEY, rows BIGINT, ingested_at BIGINT)""")
    have = {r[0] for r in con.execute("SELECT segment FROM ingested").fetchall()}
    segs = [s for s in box(f"ls {SEG}").split()
            if s.endswith(".gz") and s not in have]
    total = 0
    for s in sorted(segs):
        raw = box(f"base64 {SEG}/{s}")
        try:
            lines = gzip.decompress(base64.b64decode(raw)).decode().splitlines()
        except Exception as e:
            print(f"[ingest] {s}: fetch/decode failed ({e}) — left on box")
            continue
        rows = []
        for ln in lines:
            try:
                d = json.loads(ln)
                rows.append((d.get("ts"), d.get("wallet"), d.get("asset"),
                             d.get("cond"), d.get("side"), d.get("price"),
                             d.get("size"), d.get("tx"), d.get("title")))
            except Exception:
                pass
        if rows:
            con.executemany("INSERT INTO trades VALUES (?,?,?,?,?,?,?,?,?)", rows)
        con.execute("INSERT INTO ingested VALUES (?,?,?)",
                    [s, len(rows), int(time.time())])
        box(f"rm {SEG}/{s}")
        total += len(rows)
        print(f"[ingest] {s}: {len(rows)} rows")
    n = con.execute("SELECT count(*) FROM trades").fetchone()[0]
    print(f"[ingest] +{total} rows · rtds.duckdb now {n:,} trades")


if __name__ == "__main__":
    main()
