"""#3402: sell sim (1% supply, UniversalRouter eth_call at a HISTORICAL block) for hlate pools at touch time. No money."""
import sys, json
sys.path.insert(0, "/opt/sw"); sys.path.insert(0, "/opt/sw/sellsim")
import sellsim as S
from sellprobe import *
def blk_at(t):
    lo, hi = 1, int(rpc("eth_blockNumber", [])["result"], 16)
    while lo < hi:
        m = (lo + hi) // 2
        bt = int(rpc("eth_getBlockByNumber", [hex(m), False])["result"]["timestamp"], 16)
        if bt < t: lo = m + 1
        else: hi = m
    return lo
def sim_at(pid, token, init_block, block, frac=0.01):
    key = S.pool_key(pid, init_block)
    tag = hex(block)
    ts = rpc("eth_call", [{"to": token, "data": "0x18160ddd"}, tag])
    if "result" not in ts: return dict(pool=pid, sell_ok=None, err="hist_state:" + str(ts)[:150])
    amt = int(int(ts["result"], 16) * frac)
    b = probe_balance(token); a = probe_allow(token, W, P2)
    if not b or not a: return dict(pool=pid, sell_ok=None, err="slot_probe_fail")
    slot2 = h(k(pad(UR) + k(pad(token) + k(pad(W) + pad(1)))))
    ov = {token: {"stateDiff": {b[1]: h(pad(amt)), a[1]: h(pad(BIG))}},
          P2: {"stateDiff": {slot2: h(pad(((1 << 48) - 1) << 160 | (1 << 160) - 1))}},
          W: {"balance": "0x" + "f" * 20}}
    out = dict(pool=pid, hooks=key["hooks"], fee=key["fee"], block=block, amount_in=amt)
    def c(minout):
        return rpc("eth_call", [{"from": W, "to": UR, "data": S.build(key, token, amt, minout)}, tag, ov])
    r = c(0); out["sell_ok"] = "result" in r
    if "error" in r: out["revert"] = str(r["error"].get("data", r["error"].get("message")))[:160]
    r2 = c(1 << 120); d = r2.get("error", {}).get("data", "")
    if isinstance(d, str) and d.startswith("0x") and len(d) >= 138: out["eth_out_wei"] = int(d[-64:], 16)
    return out
def key_range(pid, b0, b1):
    for b in range(b0, b1 + 1, 100):
        r = rpc("eth_getLogs", [{"address": S.PM, "topics": [S.TI, pid], "fromBlock": hex(b), "toBlock": hex(min(b + 99, b1))}])
        if r.get("result"): return int(r["result"][0]["blockNumber"], 16)
    return None
if __name__ == "__main__":
    rows = json.load(open(sys.argv[1])); res = []
    for r in rows:
        try:
            t = int(r["entry_t"]); first = t - int(r["secs_since_first"])
            b0 = blk_at(first - 300); blk = blk_at(t)
            ib = key_range(r["pool"], b0, min(blk, blk_at(first + 150)))
            o = sim_at(r["pool"], r["token"], ib, blk)
            o.update(entry_t=t, age_s=int(r["secs_since_first"]), arm=r["arm"], src=r["src"])
        except Exception as e:
            o = dict(pool=r["pool"], err=repr(e)[:150])
        print(json.dumps(o), flush=True); res.append(o)
    json.dump(res, open(sys.argv[2], "w"))
