"""Q12: the UI group tables around 0x180203260 and every family caption key.

Known: consumables group table at 0x180203260 (7 rows, stride 0x18, indexed by the
switch in FUN_180096670 case 0xb) and staff at 0x180203310 (5 rows, case 8). The
club-item claim "there is no equivalent table" is exactly the kind of absence this
project keeps getting wrong, so walk the WHOLE region 0x180203100..0x180203700 as
stride-0x18 triples and print anything string-shaped, then xref each candidate
table start.

Also print every .rdata literal containing BADGE / STADIUM / BALL / KIT / LOGO /
TROPHY (upper case, i.e. loc keys) with its xrefs. Q4 of the brief.

CONTROL: the consumables table at 0x180203260 must come out as the seven rows
already recorded (TRAINING/CONTRACT/FITNESS/HEALING/PLAYSTYLE/MANAGER_LEAGUE/
TACTIC_TRAINING with codes 0,1,4,3,0x17,0x18,0x11). If the walk does not reproduce
it, the stride/layout assumption is wrong and nothing else in this query counts.
"""
import traceback


def walk(lo, hi, stride):
    a = lo
    while a < hi:
        cells = []
        for k in range(0, stride, 8):
            try:
                q = qword(a + k)
            except Exception:
                q = 0
            s = ""
            if 0x180000000 <= q < 0x181000000:
                try:
                    t = rd_str(q, 80)
                    if t and all(0x20 <= ord(c) < 0x7F for c in t):
                        s = t
                except Exception:
                    pass
            cells.append("%#x%s" % (q, (" %r" % s) if s else ""))
        print("  %#x  %s" % (a, " | ".join(cells)))
        a += stride


try:
    print("=== stride-0x18 walk 0x180203200..0x180203460 ===")
    walk(0x180203200, 0x180203460, 0x18)
    print()
    print("=== xrefs to plausible table starts ===")
    for a in range(0x180203200, 0x180203460, 8):
        xs = xrefs_to(a)
        if xs:
            print("  %#x:" % a)
            for frm, typ, fn, ent in xs:
                print("     %#x %s in %s(%#x)" % (frm, typ, fn, ent))
    print()
    print("=== upper-case family loc keys ===")
    seen = set()
    for pat in (b"BADGE", b"STADIUM", b"BALL", b"KIT", b"LOGO", b"TROPHY"):
        for h in find_all(pat):
            # walk back to the start of the C string
            p = h
            for _ in range(80):
                try:
                    if mem.getByte(addr(p - 1)) & 0xFF == 0:
                        break
                except Exception:
                    break
                p -= 1
            s = rd_str(p, 120)
            if p in seen or len(s) < 4:
                continue
            seen.add(p)
            xs = xrefs_to(p)
            who = ",".join(sorted({"%s(%#x)" % (fn, ent) for _f, _t, fn, ent in xs}))
            print("  %#x %-52r <- %s" % (p, s, who or "-"))
except Exception:
    traceback.print_exc()
