#!/usr/bin/env python3
"""Penyapu akhir: cari SISA tautan ke slug lama di semua artikel/halaman, lalu perbarui.

Pakai --go untuk menulis. Pemindaian penuh (dengan jeda) supaya tidak kena pembatasan situs.
"""
import base64, importlib.util, json, os, re, sys, time, urllib.error, urllib.request

WS = "/home/mantapman/.hermes/profiles/atun/workspace"
BACKUP = f"{WS}/tsc_backup_link_slug"
os.makedirs(BACKUP, exist_ok=True)
spec = importlib.util.spec_from_file_location("cfg", f"{WS}/cfg_tsc.py")
m = importlib.util.module_from_spec(spec)
spec.loader.exec_module(m)
CFG = m.CFG
DOM = CFG["domain"]
AUTH = base64.b64encode(f"{CFG['user']}:{CFG['pass']}".encode()).decode()
UA = {"User-Agent": "Mozilla/5.0"}
LAMA = json.load(open(f"{WS}/drafts/tsc_slug_lama.json"))


def rest(path, method="GET", data=None):
    h = {"Authorization": f"Basic {AUTH}", **UA}
    body = None
    if data is not None:
        body = json.dumps(data).encode()
        h["Content-Type"] = "application/json"
    r = urllib.request.Request(f"https://{DOM}{path}", data=body, headers=h, method=method)
    for i in range(4):
        try:
            with urllib.request.urlopen(r, timeout=90) as x:
                return x.status, json.loads(x.read())
        except urllib.error.HTTPError as e:
            if e.code in (429, 404):
                time.sleep(4 * (i + 1))
                continue
            return e.code, e.read().decode()[:160]
        except Exception:
            time.sleep(4)
    return 0, "gagal"


peta = {}
for x in LAMA:
    st, o = rest(f"/wp-json/wp/v2/posts/{x['id']}?_fields=id,slug")
    if isinstance(o, dict) and o.get("slug") and o["slug"] != x["slug"]:
        peta[x["slug"]] = o["slug"]
    time.sleep(0.6)
print(f"slug berganti: {len(peta)}", flush=True)

go = "--go" in sys.argv
ketemu = beres = gagal = 0
for jenis in ("posts", "pages"):
    page = 1
    while True:
        st, d = rest(f"/wp-json/wp/v2/{jenis}?per_page=100&page={page}&status=publish&context=edit"
                     f"&_fields=id,link,content")
        if not isinstance(d, list) or not d:
            break
        for x in d:
            raw = x["content"]["raw"]
            baru, n = raw, 0
            for l, g in peta.items():
                n += len(re.findall(re.escape(l), baru))
                baru = baru.replace(l, g)
            if not n:
                continue
            ketemu += 1
            print(f"  #{x['id']:<6} {jenis:<6} {n} tautan | {x['link'][:62]}", flush=True)
            if go:
                open(f"{BACKUP}/post_{x['id']}_sapu.txt", "w").write(raw)
                st2, _ = rest(f"/wp-json/wp/v2/{jenis}/{x['id']}", "POST", {"content": baru})
                time.sleep(1.5)
                _, cek = rest(f"/wp-json/wp/v2/{jenis}/{x['id']}?context=edit&_fields=content")
                sisa = sum(len(re.findall(re.escape(l), cek.get("content", {}).get("raw", ""))) for l in peta) \
                    if isinstance(cek, dict) else -1
                ok = st2 == 200 and sisa == 0
                print(f"        {'✅' if ok else '❌'} HTTP {st2} · sisa: {sisa}", flush=True)
                beres += ok
                gagal += (not ok)
            time.sleep(1)
        if len(d) < 100:
            break
        page += 1

print(f"\nkonten dengan tautan lama: {ketemu} · diperbarui: {beres} · gagal: {gagal}")
if not go:
    print("(dry run — pakai --go)")
