#!/usr/bin/env python3
"""Collect ERC-8004 ReputationRegistry feedback events. Reproducible: pure stdlib + public RPC.
Event topic0 0x6a4a6174... ; topics[1]=agentId, topics[2]=reviewer address."""
import json,sys,time,urllib.request
REP='0x8004BAa17C55a88189AE136b182e5fdA19dE9b63'
TOPIC='0x6a4a61743519c9d648a14e6493f47dbe3ff1aa29e7785c96c8326a205e58febc'
UA={'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) Chrome/152.0','Content-Type':'application/json'}
def rpc(url,method,params,tries=3):
    for i in range(tries):
        try:
            req=urllib.request.Request(url,data=json.dumps({"jsonrpc":"2.0","id":1,"method":method,"params":params}).encode(),headers=UA)
            r=json.loads(urllib.request.urlopen(req,timeout=45).read().decode())
            if 'result' in r: return r['result']
            if 'error' in r and i==tries-1: return {'__err':r['error'].get('message','')}
        except Exception as e:
            if i==tries-1: return {'__err':str(e)[:80]}
        time.sleep(1.2*(i+1))
    return {'__err':'exhausted'}
def collect(chain,url,span_blocks,window):
    head=int(rpc(url,'eth_blockNumber',[]),16)
    lo_target=head-span_blocks
    out=[];cur=head;calls=0
    while cur>lo_target:
        lo=max(lo_target,cur-window)
        r=rpc(url,'eth_getLogs',[{'address':REP,'topics':[TOPIC],'fromBlock':hex(lo),'toBlock':hex(cur)}])
        calls+=1
        if isinstance(r,dict) and '__err' in r:
            if window>1000: window//=2; continue           # range too wide -> shrink
            sys.stderr.write(f"{chain}: give up window at {lo}: {r['__err'][:60]}\n"); cur=lo-1; continue
        out.extend(r); cur=lo-1
        if calls%25==0: sys.stderr.write(f"  {chain}: {calls} calls, {len(out)} logs, at block {lo}\n")
    return head,lo_target,out,calls
if __name__=='__main__':
    chain,url,span,window=sys.argv[1],sys.argv[2],int(sys.argv[3]),int(sys.argv[4])
    head,lo,logs,calls=collect(chain,url,span,window)
    recs=[{'agent':int(l['topics'][1],16),'reviewer':'0x'+l['topics'][2][-40:],
           'block':int(l['blockNumber'],16),'tx':l['transactionHash']} for l in logs]
    json.dump({'chain':chain,'head':head,'from_block':lo,'calls':calls,'records':recs},open(f'{chain}_feedback.json','w'))
    print(f"{chain}: {len(recs)} feedback records, blocks {lo}-{head}, {calls} rpc calls")
