"""DIMENSION 2 batch 8: piles, the response registry, and the credits path.

HYPOTHESES
 H1 0x180229cc0 is a {string,enum} table naming every itemState / pile value.
    'trade'/'tradepile' in it would be the value a send-to-transfer-list
    MoveCard must carry.
 H2 The rows around 0x1802705f0 / 0x1802fb370 are a response registry that pairs
    each response class with its deserializer AND its handler; the handler for
    FutDiscardCard is what reads totalCredits.
 H3 FutUpdateCreditsServerResponse / FutUserCreditsServerResponse are the coin
    balance carriers; if the client refetches credits after a discard, the
    emulator must keep the balance consistent, not just echo totalCredits.

CONTROL: FutCreateMatchServerResponse -> 0x180120380.
"""
import traceback, os

OUT = "/tmp/claude-1000/-home-alex-Documents-OpenFUT/8e521ca1-ca3e-4138-bb96-df1744dd1d30/scratchpad/packres"

try:
    print("CONTROL FutCreateMatchServerResponse ->",
          [hex(a) for a, v, e in class_deser("FutCreateMatchServerResponse")])

    print("=" * 78)
    print("SECTION 1 -- itemState enum table 0x180229cc0")
    for i in range(24):
        p = qword(0x180229CC0 + i * 0x10)
        if p == 0:
            print("   [%d] NULL terminator" % i)
            break
        v = dword(0x180229CC8 + i * 0x10)
        print("   [%2d] %r -> %d" % (i, rd_str(p, 40), v))
    print("SECTION 1b -- tradeState enum table 0x180229e40")
    for i in range(16):
        p = qword(0x180229E40 + i * 0x10)
        if p == 0:
            print("   [%d] NULL" % i)
            break
        print("   [%2d] %r -> %d" % (i, rd_str(p, 40), dword(0x180229E48 + i * 0x10)))
    print("SECTION 1c -- bidState decoder 0x180166380")
    print(dec(0x180166380))

    print("=" * 78)
    print("SECTION 2 -- registry rows around the discard entries")
    for base, n in ((0x180270580, 0x60), (0x1802FB330, 0x40), (0x180220470, 0x40)):
        print("--- dump %#x ---" % base)
        for i in range(n):
            va = base + i * 8
            try:
                q = qword(va)
            except Exception:
                break
            note = ""
            if 0x1801E5000 <= q <= 0x180290000:
                s = rd_str(q, 60)
                if s and all(0x20 <= ord(c) < 0x7F for c in s):
                    note = "STR %r" % s
            if not note and 0x180001000 <= q < 0x1801E5000:
                f = fm.getFunctionAt(addr(q))
                note = "FUNC %s" % (f.getName() if f else "(mid)")
            print("   %#x : %#018x  %s" % (va, q, note))

    print("=" * 78)
    print("SECTION 3 -- credits response classes")
    for c in ("FutUpdateCreditsServerResponse", "FutUserCreditsServerResponse",
              "FutMoveCardServerResponse", "FutGetPurchasedItemsServerResponse"):
        r = class_deser(c)
        print(" ", c, [(hex(a), hex(v), hex(e)) for a, v, e in r])
        for a, v, e in set(r):
            s = dec(a)
            print("---- deser %#x len=%d ----" % (a, len(s)))
            print(s)
            break

    print("=" * 78)
    print("SECTION 4 -- MoveCard deser 0x180128600 FULL")
    s = dec(0x180128600)
    print("len(src) =", len(s))
    print(s)
    with open(os.path.join(OUT, "d2_movecard_deser.txt"), "w") as f:
        f.write(s)

except Exception:
    traceback.print_exc()
