import json, sys, time, urllib.request, urllib.error, ssl, gzip, re

BOT = "RevvSourceCheck/0.1 (one-off source verification)"
BRW = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0 Safari/537.36"

def get(url, ua, method="GET", data=None, headers=None):
    h = {"User-Agent": ua, "Accept": "*/*", "Accept-Encoding": "gzip"}
    if headers: h.update(headers)
    req = urllib.request.Request(url, data=data, headers=h, method=method)
    try:
        with urllib.request.urlopen(req, timeout=25) as r:
            body = r.read(3_000_000)
            if r.headers.get("Content-Encoding") == "gzip":
                body = gzip.decompress(body)
            return r.status, r.headers.get("Content-Type", ""), body, r.geturl()
    except urllib.error.HTTPError as e:
        b = e.read(200_000)
        try:
            if e.headers.get("Content-Encoding") == "gzip": b = gzip.decompress(b)
        except Exception: pass
        return e.code, e.headers.get("Content-Type", ""), b, url
    except Exception as e:
        return None, type(e).__name__ + ": " + str(e)[:80], b"", url

def mark(body):
    t = body[:200_000].decode("utf-8", "ignore").lower()
    if "just a moment" in t or "cf-chl" in t or "challenge-platform" in t: return "cloudflare-challenge"
    if "you have been blocked" in t: return "cloudflare-block"
    if "access denied" in t and "akamai" in t or "errors.edgesuite" in t: return "akamai-deny"
    return ""

CHECKS = json.load(open(sys.argv[1]))
out = []
for c in CHECKS:
    res = {"id": c["id"], "url": c["url"]}
    for label, ua in (("bot", BOT), ("browser", BRW)):
        data = c.get("data")
        st, ct, body, final = get(c["url"], ua, c.get("method", "GET"), data.encode() if data else None, c.get("headers"))
        kw = c.get("expect")
        found = bool(kw and re.search(kw, body[:3_000_000].decode("utf-8", "ignore"), re.I))
        res[label] = {"status": st, "type": ct[:40], "bytes": len(body), "final": final if final != c["url"] else "", "block": mark(body), "expect_found": found}
        if st == 200 and found: break
        time.sleep(1)
    out.append(res)
    print(json.dumps(res), flush=True)
