"""For runners with no buy in the first window: walk forward from launch in 1 h windows (max 48) to find the first buy, then fetch 30 min from it."""
import json, sys, time, threading, os
from concurrent.futures import ThreadPoolExecutor
sys.path.insert(0, '/tmp/run'); from rpc import *
import feat3
H = int(rpc('eth_blockNumber', []), 16)
todo = json.load(open('/tmp/run/fix_todo.json'))
done = set()
if os.path.exists('/tmp/run/raw_fix.jsonl'):
    for l in open('/tmp/run/raw_fix.jsonl'): done.add(json.loads(l)['tok'])
lock = threading.Lock(); out = open('/tmp/run/raw_fix.jsonl', 'a')
def grab(tok, lo, hi, depth=0):
    r = rpc('eth_getLogs', [{'address': tok, 'topics': [TR], 'fromBlock': hex(lo), 'toBlock': hex(hi)}])
    if isinstance(r, list): return r
    if depth < 9 and hi > lo:
        m = (lo + hi) // 2; return grab(tok, lo, m, depth + 1) + grab(tok, m + 1, hi, depth + 1)
    raise RuntimeError(str(r)[:100])
def conv(r): return [(int(l['blockNumber'], 16), int(l['logIndex'], 16), '0x' + l['topics'][1][-40:], '0x' + l['topics'][2][-40:], l['data'], l['transactionHash'][:18]) for l in r if len(l['topics']) >= 3]
def one(o):
    tok = o['tok']; b = max(o.get('launch_block') or 0, o.get('mint_block') or 0)
    for k in range(48):
        lo, hi = b + k * 32000, b + (k + 1) * 32000 - 1
        if lo > H: break
        tr = conv(grab(tok, lo, min(hi, H)))
        T = feat3.nets(tr)
        S = next((bb for bb, li, h, net, m in T if feat3.kind_of(net, m) == 'buy'), None)
        if S:
            tr2 = conv(grab(tok, S, min(H, S + 18000)))
            o2 = dict(o); o2['launch_block'] = S; o2['tr'] = tr2; o2['fixed_from'] = o.get('launch_block'); o2['launch_ts'] = None
            return o2
    o2 = dict(o); o2['fix_err'] = 'no_buy_48h'; return o2
def work(o):
    if o['tok'] in done: return
    try: r = one(o)
    except Exception as e: r = dict(tok=o['tok'], kind=o['kind'], fix_err=repr(e)[:150])
    with lock: out.write(json.dumps(r) + '\n'); out.flush()
with ThreadPoolExecutor(3) as ex: list(ex.map(work, todo))
print('done')
