#!/usr/bin/env python3
"""Sisir tautan mati StudioSoft — versi hemat (ambil daftar dulu, isi menyusul satu per satu).

Hasil: drafts/ss_tautan_mati.json
"""
import base64, json, re, time, urllib.error, urllib.request

WS = "/home/mantapman/.hermes/profiles/atun/workspace"
DOM = "studiosoft.id"
S = f"https://{DOM}"
AUTH = base64.b64encode(b"bambangbot:q26r RePo BVy6 pwU2 F3z7 ouyl").decode()
H = {"Authorization": f"Basic {AUTH}", "User-Agent": "Mozilla/5.0"}
UA = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/124.0 Safari/537.36"}


def rest(p, ulang=4):
    akhir = ""
    for i in range(ulang):
        try:
            return json.loads(urllib.request.urlopen(urllib.request.Request(S + p, headers=H), timeout=120).read())
        except Exception as e:
            akhir = str(e)[:50]
            time.sleep(5 + i * 5)
    raise RuntimeError(akhir)


print("=== daftar artikel & halaman ===")
daftar = []
for jenis in ("posts", "pages"):
    hal = 1
    while hal <= 12:
        try:
            d = rest(f"/wp-json/wp/v2/{jenis}?per_page=50&page={hal}&status=publish&_fields=id,slug,link")
        except Exception as e:
            print(f"   {jenis} hal {hal} gagal: {e}")
            break
        if not isinstance(d, list) or not d:
            break
        daftar += [{"jenis": jenis, **x} for x in d]
        if len(d) < 50:
            break
        hal += 1
print(f"   {len(daftar)} entri")

print("\n=== ambil isi satu per satu ===")
tautan = {}
gagal_isi = 0
for i, p in enumerate(daftar, 1):
    try:
        c = rest(f"/wp-json/wp/v2/{p['jenis']}/{p['id']}?_fields=content", ulang=3)
        isi = c["content"]["rendered"] if isinstance(c.get("content"), dict) else (c.get("content") or "")
    except Exception:
        gagal_isi += 1
        continue
    for mo in re.finditer(r'<a[^>]+href="([^"#]+)"[^>]*>(.*?)</a>', isi, re.S):
        u = mo.group(1).strip()
        if u.startswith("#") or u.startswith("mailto:") or u.startswith("tel:") or u.startswith("whatsapp"):
            continue
        jangkar = re.sub(r"\s+", " ", re.sub("<[^>]+>", " ", mo.group(2))).strip()[:90]
        tautan.setdefault(u, {"jumlah": 0, "dari": []})
        tautan[u]["jumlah"] += 1
        if len(tautan[u]["dari"]) < 4:
            tautan[u]["dari"].append({"pid": p["id"], "jenis": p["jenis"], "slug": p["slug"], "jangkar": jangkar})
    if i % 40 == 0:
        print(f"   … {i}/{len(daftar)} · tautan unik: {len(tautan)}")
print(f"   {len(tautan)} tautan unik · gagal ambil isi: {gagal_isi}")

print("\n=== periksa tautan ===")
mati = {}
for i, (u, info) in enumerate(sorted(tautan.items()), 1):
    coba = S + u if u.startswith("/") else u
    if not coba.startswith("http"):
        continue
    status = None
    try:
        with urllib.request.urlopen(urllib.request.Request(coba, headers=UA), timeout=25) as r:
            status = r.status
    except urllib.error.HTTPError as e:
        status = e.code
    except Exception as e:
        status = f"GAGAL {str(e)[:26]}"
    if status == 200 or (isinstance(status, int) and 301 <= status <= 399):
        continue
    mati[u] = {**info, "status": status}
    if i % 50 == 0:
        print(f"   … {i}/{len(tautan)} diperiksa · bermasalah: {len(mati)}")

json.dump(mati, open(f"{WS}/drafts/ss_tautan_mati.json", "w"), ensure_ascii=False, indent=1)
print(f"\n=== {len(mati)} tautan bermasalah dari {len(tautan)} unik ===")
for u, v in mati.items():
    print(f"   {str(v['status'])[:14]:<16}{u[:96]}")
