"""Confirm the marketdata/pricelimits response shape before serving it (it just froze).

We returned {"minPrice":150,"maxPrice":15000} (an OBJECT) and the client froze at the
price screen -> classic container-type desync (0x1801c7f1a). The doc says the response
is a BARE TOP-LEVEL ARRAY of {defId,minPrice,maxPrice}, deser 0x180163ee0
(GETSUGGESTEDPRICING). Verify the element fields and types so the fix does not re-freeze.

CONTROL: minPrice=0x1ca, maxPrice=0x1c2 must appear; find the defId/id atom the element
keys identity on, and confirm each is read with the INT primitive 0x1801c79d0 (scalar),
so our int values are type-correct.
"""
import re, traceback

DESER = 0x180163EE0

try:
    src = dec(DESER)
    f = func(DESER)
    print("%#x GetSuggestedPricing deser  body %d / decompile %d chars (IN FULL)"
          % (DESER, f.getBody().getNumAddresses() if f else -1, len(src)))
    print("=" * 78)
    print(src)

    print("\n=== atoms this deser (and its element callee) dispatch on ===")
    atoms = {}
    for line in open("/home/alex/Documents/OpenFUT/fifa17-recon/docs/fut_atoms.tsv"):
        p = line.rstrip("\n").split("\t")
        if len(p) >= 3:
            try: atoms[int(p[1], 16)] = p[2]
            except ValueError: pass
    scan = [DESER] + [a for a, _ in callees(DESER)]
    for ent in scan:
        try: d = dec(ent)
        except Exception: continue
        found = set()
        for m in re.finditer(r"(case |== |!= )(0x[0-9a-f]+)\b", d):
            found.add(int(m.group(2), 16))
        rel = [(a, atoms.get(a, "?")) for a in sorted(found)
               if a in (0x1ca, 0x1c2, 0x2e6, 0x65, 0x24d) or (atoms.get(a, "").lower() in
               ("defid", "id", "minprice", "maxprice", "startingbid", "buynowprice"))]
        if rel:
            print("  %#x %-20s -> %s" % (ent, fname(ent),
                  ", ".join("%s(%#x)" % (n, a) for a, n in rel)))
        # is it an array reader? look for the 0xd (END_ARRAY) sentinel loop
        if "!= 0xd" in d or "== 0xd" in d:
            print("    (has an END_ARRAY 0xd loop -> reads an ARRAY, consistent with bare-array root)")

except Exception:
    traceback.print_exc()
