#!/usr/bin/env python3
"""fee_path_walk.py — ARION upstream fee-path walk for MuseBank (club dare /
Data's three cold rows). Stdlib only.

For each tx hash given on argv: pull receipt, decode every ERC20 Transfer leg,
print token/from/to/value so the split can be recomputed by any stranger.
Then prints standing balances (the "queue") on the known hands, plus code size
of the collector 0x8366a39c.

Usage: python3 fee_path_walk.py [txhash ...] [--queue] [--code]
"""
import json, os, sys, time, urllib.request

HERE = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, os.path.join(HERE, "..", "..", "tools"))
from eth_call import keccak256  # noqa: E402

RPCS = ["https://rpc.ordofi.network", "https://rpc.mainnet.chain.robinhood.com",
        "https://robinhood-rpc.publicnode.com", "https://robinhood.drpc.org"]
H = {"Content-Type": "application/json", "User-Agent": "ARION-feepath/1.0"}

TOK = {
    "0x0e7f299713fbbe0635f9edc4ecb4e17f0d76bba3": ("MB",  "musebank"),
    "0x91a2dae9699f0b82540b5886b0d8759c22820ba3": ("MUS", "musebook"),
}
NAMES = {
    "0x8366a39cc670b4001a1121b8f6a443a643e40951": "collector(launchpad PM)",
    "0x4e3468951d49f2eea976ed0d6e75ffcb44a9a544": "keeper-smart-acct",
    "0xe7a39ed4d3b799019df086a29a18b37c5df6e5ec": "fee-wallet/deployer",
    "0xe7a39c82b0f34ba04a2e6c83eab4d20f5f7ee5ec": "LOOKALIKE-empty",
    "0x5209fe38c66e23e00e5ee693ba3e1f9e72d95d4a": "vault-deployer-2",
    "0x38f2cd3b6ae0ce6528d7c62a3494439c7f284908": "V1",
    "0xb5fbdae914c696467d6d9e6de0c476d8d8402f45": "V2",
}
TRANSFER = "0x" + keccak256(b"Transfer(address,address,uint256)").hex()

_i = 0
def rpc(method, params, budget=25):
    global _i
    body = json.dumps({"jsonrpc": "2.0", "id": 1, "method": method,
                       "params": params}).encode()
    t0, delay, last = time.time(), 0.4, None
    while True:
        url = RPCS[_i % len(RPCS)]; _i += 1
        try:
            d = json.load(urllib.request.urlopen(
                urllib.request.Request(url, data=body, headers=H), timeout=30))
            if "result" in d:
                return d["result"]
            last = d.get("error")
        except Exception as e:
            last = e
        if time.time() - t0 > budget:
            raise RuntimeError(f"{method} budget: {last}")
        time.sleep(delay)
        delay = min(delay * 1.7, 2.5)


def nm(a):
    a = a.lower()
    return NAMES.get(a, a[:10] + "…" + a[-4:])


def trace_tx(h):
    tx = rpc("eth_getTransactionByHash", [h])
    rc = rpc("eth_getTransactionReceipt", [h])
    print(f"=== tx {h}")
    print(f"  blk {int(tx['blockNumber'],16)}  from {nm(tx['from'])}  "
          f"to {nm(tx['to']) if tx.get('to') else 'CREATE'}  sel {tx['input'][:10]}")
    for lg in rc["logs"]:
        if lg["topics"] and lg["topics"][0] == TRANSFER and len(lg["topics"]) == 3:
            tok = TOK.get(lg["address"].lower(), (lg["address"][:12] + "…", "?"))[0]
            frm = "0x" + lg["topics"][1][-40:]
            to = "0x" + lg["topics"][2][-40:]
            val = int(lg["data"], 16) / 1e18
            print(f"  {tok:>4} {val:>18,.6f}  {nm(frm)} -> {nm(to)}")
        else:
            print(f"  [log] {lg['address'][:12]}… topics={[t[:18]+'…' for t in lg['topics']]}")


def balance(token, who, tag=""):
    data = "0x70a08231" + "0" * 24 + who[2:].lower()
    r = rpc("eth_call", [{"to": token, "data": data}, "latest"])
    v = int(r, 16) / 1e18
    print(f"  balanceOf {TOK.get(token.lower(),(token[:12],'?'))[0]:>4} "
          f"{nm(who):<24} {tag:<14} = {v:,.6f}")
    return v


def main():
    args = [a for a in sys.argv[1:] if not a.startswith("--")]
    for h in args:
        trace_tx(h)
    if "--code" in sys.argv or not args:
        for a in ["0x8366a39cc670b4001a1121b8f6a443a643e40951",
                  "0x4e3468951d49f2eea976ed0d6e75ffcb44a9a544"]:
            code = rpc("eth_getCode", [a, "latest"])
            print(f"  code {nm(a)}: {len(code)//2 - 1} bytes")
    if "--queue" in sys.argv or not args:
        for tok in TOK:
            for who, tag in [
                ("0x8366a39cc670b4001a1121b8f6a443a643e40951", "collector"),
                ("0x4e3468951d49f2eea976ed0d6e75ffcb44a9a544", "keeper acct"),
                ("0xe7a39ed4d3b799019df086a29a18b37c5df6e5ec", "fee wallet"),
                ("0x38f2cd3b6ae0ce6528d7c62a3494439c7f284908", "V1"),
                ("0xb5fbdae914c696467d6d9e6de0c476d8d8402f45", "V2"),
            ]:
                balance(tok, who, tag)


if __name__ == "__main__":
    main()
