#!/usr/bin/env python3
"""Diff the served manifest of the last-WORKING 1.0.111 upload vs the first-FAILING one.
Both are 1.0.111, same server, same SDK. If they differ structurally, that's the Aug-7 trigger.
"""
import urllib.request, json, re

BASE = "https://ota.46-4-121-190.sslip.io"
def call(m, u, d=None, t=None):
    h = {"Content-Type": "application/json"}
    if t: h["Authorization"] = f"Bearer {t}"
    req = urllib.request.Request(u, data=(json.dumps(d).encode() if d else None), headers=h, method=m)
    with urllib.request.urlopen(req, timeout=30) as r: return json.loads(r.read())

tok = call("POST", f"{BASE}/authentication", {"strategy":"local","username":"admin","password":"353fde0a0fe4e8a0b2799e54"})["accessToken"]

# Temporarily release the last-working 1.0.111 (6a75c495) to fetch its manifest
call("PATCH", f"{BASE}/uploads/6a75c495bce64410088d0757", {"status":"released"}, tok)
call("PATCH", f"{BASE}/uploads/6a772081bce64410088d075c", {"status":"obsolete"}, tok)

def fetch_manifest(rv):
    req = urllib.request.Request(f"{BASE}/api/manifest", headers={
        "expo-platform":"android","expo-project":"pixiesprout","expo-channel-name":"default","expo-runtime-version":rv})
    with urllib.request.urlopen(req, timeout=30) as r:
        raw = r.read().decode("utf-8","replace")
    i = raw.find('{"id"'); st = raw.find("{", i); d=0; end=None
    for k in range(st, len(raw)):
        if raw[k]=="{": d+=1
        elif raw[k]=="}":
            d-=1
            if d==0: end=k+1; break
    return json.loads(raw[st:end])

# last-working 1.0.111
w = fetch_manifest("1.0.111")
print("=== last-WORKING 1.0.111 manifest ===")
print("  id:", w.get("id"))
print("  top keys:", sorted(w.keys()))
print("  extra keys:", sorted(w.get("extra",{}).keys()))
print("  scopeKey:", repr(w.get("extra",{}).get("scopeKey")))
print("  expoClient revisionId:", repr(w.get("extra",{}).get("expoClient",{}).get("revisionId")))
print("  launchAsset keys:", sorted(w.get("launchAsset",{}).keys()))
print("  assets count:", len(w.get("assets",[])))
print("  metadata:", json.dumps(w.get("metadata"))[:200])

# restore 1.0.113 as released
call("PATCH", f"{BASE}/uploads/6a772081bce64410088d075c", {"status":"released"}, tok)
call("PATCH", f"{BASE}/uploads/6a75c495bce64410088d0757", {"status":"obsolete"}, tok)
print("\n(restored 1.0.113 as released)")
