#!/usr/bin/env python3
"""Ticker crowd before each breakout. Query ($SYM OR "Name") via xsafe (scams removed). Windows end at the breakout
bar OPEN (nothing from the breakout hour itself): last10 = [T-10h, T), base = [T-34h, T-10h). Resumable."""
import json, os, sys, time, importlib.util, re
sp = importlib.util.spec_from_file_location("xsafe", "/opt/common/xsafe/xsafe.py")
xs = importlib.util.module_from_spec(sp); sp.loader.exec_module(xs)
xs.budget(int(sys.argv[1]) if len(sys.argv) > 1 else 7000)
SH, NSH = int(sys.argv[2]), int(sys.argv[3])
EV = json.load(open("/opt/bostudy/events.json"))
OUT = f"/opt/bostudy/xraw_{SH}.jsonl"
import glob
done = set()
for fn in glob.glob("/opt/bostudy/xraw*.jsonl"):
    for l in open(fn):
        try: done.add(json.loads(l)["k"])
        except Exception: pass
keep = ("id", "text", "createdAt", "likeCount", "retweetCount", "replyCount", "viewCount", "isReply", "lang")
def slim(t):
    d = {k: t.get(k) for k in keep}; a = t.get("author") or {}
    d["user"] = a.get("userName"); d["fol"] = a.get("followers"); d["why"] = t.get("_why"); d["ts"] = xs.ts(t)
    return d
def q(e):
    sym = (e["symbol"] or "").strip().lstrip("$"); nm = (e["name"] or "").strip()
    nm = re.sub(r'["()]', "", nm)
    return f'(${sym} OR "{nm}")' if nm and nm.lower() != sym.lower() and len(nm) >= 3 else f"${sym}"
n = 0
with open(OUT, "a") as f:
    for idx, e in enumerate(EV):
        if idx % NSH != SH: continue
        k = f'{e["address"]}:{e["t"]}'
        if k in done: continue
        st = xs.status()
        if st.get("brake"): print("brake on, sleeping", flush=True); time.sleep(120)
        T = e["t"]; rec = {"k": k, "query": q(e)}
        try:
            for lab, a, b in (("last10", T - 36000, T), ("base", T - 34 * 3600, T - 36000)):
                r = xs.search(rec["query"], since=a, until=b, pages=2)
                rec[lab] = {"real": [slim(t) for t in r["real"]], "spam": len(r["spam"]), "complete": r["complete"], "pages": r["n_pages"]}
        except Exception as ex:
            print("ERR", k, str(ex)[:200], flush=True)
            if "run cap" in str(ex): break
            if "brake" in str(ex).lower(): time.sleep(90)
            continue
        f.write(json.dumps(rec) + "\n"); f.flush(); n += 1
        if n % 25 == 0: print(time.strftime("%H:%M:%S"), "done", n, "credits", xs.credits(), flush=True)
print("FINISHED", n, flush=True)
