"""DIMENSION 2 batch 7: the client model singleton, the itemState/pile enum, the
RS4 census, and the readers of the discard response's totalCredits.

HYPOTHESES
 H1 DAT_1802e6398 (returned by FUN_18011a830) is the FUT client model. Slot
    0xa30 removes an item by id (discard), 0xa08 inserts a parsed item, 0x160
    returns the pack-reveal collection. Finding its vtable makes all three
    readable, including any credits mutator.
 H2 FUN_180166660 is the itemState string->enum used for atom 0x172, so it
    enumerates the piles ("free"/"pile"/"club"/"trade"/...). That names the
    value a send-to-transfer-list MoveCard has to carry.
 H3 A full RS4 census tells us whether a dedicated send-to-tradepile response
    class exists at all, or whether the reveal reuses MoveCard/ISStart.

CONTROL: FutSquadListServerResponse -> 0x180172140.
"""
import traceback, os

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


def dump(name, text):
    with open(os.path.join(OUT, name), "w") as f:
        f.write(text)


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

    print("=" * 78)
    print("SECTION 1 -- RS4 census")
    hits = find_all(b"RS4:")
    names = []
    for h in hits:
        s = rd_str(h, 80)
        names.append((h, s))
    names.sort(key=lambda x: x[1])
    print("count =", len(names))
    for h, s in names:
        print("  %#x  %s" % (h, s))
    dump("d2_rs4_census.txt", "\n".join("%#x %s" % (h, s) for h, s in names))

    print("=" * 78)
    print("SECTION 2 -- client model singleton DAT_1802e6398")
    for r in xrefs_to(0x1802E6398):
        print("   %#x %s %s %#x" % (r[0], r[1], r[2], r[3]))
    for e in sorted({r[3] for r in xrefs_to(0x1802E6398) if r[3] and r[1] == "WRITE"}):
        s = dec(e)
        print("---- writer %#x len=%d ----" % (e, len(s)))
        print(s if len(s) < 6000 else s[:6000] + "\n...TRUNCATED len=%d" % len(s))

    print("=" * 78)
    print("SECTION 3 -- itemState enum decoder FUN_180166660 (atom 0x172)")
    print(dec(0x180166660))
    print("SECTION 3b -- tradeState decoder 0x180166bd0, bidState 0x180166380")
    print(dec(0x180166BD0))

    print("=" * 78)
    print("SECTION 4 -- callers of the FutDiscardCard factories")
    for f in (0x180127160, 0x180127630, 0x180127890):
        print("  factory %#x callers:" % f)
        for r in xrefs_to(f):
            print("     %#x %s %s %#x" % (r[0], r[1], r[2], r[3]))

    print("=" * 78)
    print("SECTION 5 -- the fcc_discardcoins third key string")
    print("  0x18022315c ->", repr(rd_str(0x18022315C, 40)))
    print("  0x180223150 ->", repr(rd_str(0x180223150, 40)))
    print("  raw:", read_bytes(0x180223150, 32).hex())

except Exception:
    traceback.print_exc()
