"""livematch.py (FW Analyst 1, sup-to-a1 v20 job 1): every 5 min, replay each CLOSED fmmc5 coin (fw/mc5live.txt) with mc5replay.py
and post MATCH (|x live - x replay| <= max(0.05, 5% of x replay)) or MISMATCH. Live rows first; watch rows listed for reference.
Writes /root/fwa1/live/a1-live-match.txt (main pulls it to fw/a1-live-match.txt)."""
import urllib.request, subprocess, re, json, os, time, datetime
from lpclass import lp_class   # A1.26 tag (sup-to-a1 v23)
os.makedirs("/root/fwa1/live", exist_ok=True)
CACHE = "/root/fwa1/live/replays.json"
done = json.load(open(CACHE)) if os.path.exists(CACHE) else {}
txt = urllib.request.urlopen(urllib.request.Request("http://159.223.88.168/hx-c9ois/fw/mc5live.txt", headers={"User-Agent": "Mozilla/5.0"}), timeout=30).read().decode()
rows = []
for l in txt.split("\n"):
    f = [x.strip() for x in l.split("|")]
    if len(f) < 15 or not f[0].startswith("0x") or f[5] != "BUY" or f[14] != "closed": continue
    rows.append(dict(pool=f[0], token=f[1], t0=f[2], cap=f[3], mode=f[6], delay=f[7], fill=f[8], x=f[9], exit=f[10]))
for r in rows:
    if r["pool"] in done: continue
    try:
        out = subprocess.run(["python3", "-W", "ignore", "/root/fwa1/mc5replay.py", r["pool"]], capture_output=True, text=True, timeout=240, cwd="/root/fwa1").stdout.strip().split("\n")[-1]
    except Exception as e:
        out = "replay failed: %s" % type(e).__name__
    done[r["pool"]] = out; json.dump(done, open(CACHE + ".tmp", "w")); os.replace(CACHE + ".tmp", CACHE)
def verdict(r):
    out = done.get(r["pool"], "")
    m = re.search(r"cap \+5m \$(\d+)k .*exit (\S+) at \+(\S+) s \| x ([\d.]+)", out)
    if "NO TRADE" in out: return "MISMATCH", "my rule does not trade it (dust guard)", "-", "-", "-"
    if not m: return "PENDING", out[:120], "-", "-", "-"
    try: xl = float(r["x"])
    except ValueError: return "PENDING", "live x not readable", m.group(1), m.group(2), m.group(4)
    v = "MATCH" if abs(xl - float(m.group(4))) <= max(0.05, 0.05 * float(m.group(4))) else "MISMATCH"
    return v, "", "$%sk" % m.group(1), "%s at +%s s" % (m.group(2), m.group(3)), m.group(4)
now = datetime.datetime.utcfromtimestamp(time.time() + 7 * 3600).strftime("%d %b %H:%M")
L = ["fmmc5 live match (FW Analyst 1). Made %s Bangkok, refreshed every 5 min. MATCH = live x within 0.05x or 5%% (whichever is bigger) of my replay of the same coin." % now,
     "Replay = mc5 spec (http://159.223.88.168/hx-c9ois/fw/a1-mc5-spec.md), $100 real depth from swaps, 3 s delay; live = fmmc5 real fill at its ticket size.", ""]
for lab, sel in (("LIVE coins", lambda r: r["mode"] == "live"), ("Watch (paper) coins, for reference", lambda r: r["mode"] != "live")):
    S = [r for r in rows if sel(r)]
    vs = [verdict(r) for r in S]
    L.append("%s: %d closed, %d MATCH, %d MISMATCH, %d pending" % (lab, len(S), sum(v[0] == "MATCH" for v in vs), sum(v[0] == "MISMATCH" for v in vs), sum(v[0] == "PENDING" for v in vs)))
    L.append("  verdict | pool | token | first swap (Bangkok) | cap live / mine | live: fill delay s, fill/sim, exit, x | mine: exit, x | lp_class | note")
    for r, v in zip(S, vs):
        L.append("  %s | %s | %s | %s | %s / %s | %s s, %s, %s, %sx | %s, %sx | %s | %s" % (v[0], r["pool"], r["token"], r["t0"], r["cap"], v[2], r["delay"], r["fill"], r["exit"], r["x"], v[3], v[4], lp_class(r["pool"]), v[1]))
    L.append("")
open("/root/fwa1/live/a1-live-match.txt.tmp", "w").write("\n".join(L) + "\n"); os.replace("/root/fwa1/live/a1-live-match.txt.tmp", "/root/fwa1/live/a1-live-match.txt")
