#!/usr/bin/env python3
"""DAS: ambil meta Yoast SELURUH artikel lewat XML-RPC (wp.getPosts massal) → audit yang benar."""
import base64, html, json, os, re, time, urllib.request, urllib.error, importlib.util
from xml.sax.saxutils import escape

WS = "/home/mantapman/.hermes/profiles/atun/workspace"
spec = importlib.util.spec_from_file_location("cfg_das", f"{WS}/cfg_das.py")
m = importlib.util.module_from_spec(spec); spec.loader.exec_module(m)
CFG = m.CFG
DOM, USER, PASS = CFG["domain"], CFG["user"], CFG["pass"]
AUTH = base64.b64encode(f"{USER}:{PASS}".encode()).decode()


def rpc(method, params=()):
    def val(v):
        if isinstance(v, int):
            return f"<value><int>{v}</int></value>"
        if isinstance(v, bool):
            return f"<value><boolean>{1 if v else 0}</boolean></value>"
        if isinstance(v, list):
            return "<value><array><data>" + "".join(val(x) for x in v) + "</data></array></value>"
        if isinstance(v, dict):
            return "<value><struct>" + "".join(f"<member><name>{escape(str(k))}</name>{val(x)}</member>"
                                               for k, x in v.items()) + "</struct></value>"
        return f"<value><string>{escape(str(v))}</string></value>"
    body = ("<?xml version=\"1.0\"?><methodCall><methodName>" + method + "</methodName><params>" +
            "".join(f"<param>{val(p)}</param>" for p in params) + "</params></methodCall>").encode()
    r = urllib.request.Request(f"https://www.{DOM}/xmlrpc.php", data=body,
                               headers={"Content-Type": "text/xml", "User-Agent": "Mozilla/5.0",
                                        "Authorization": f"Basic {AUTH}"}, method="POST")
    for _ in range(3):
        try:
            with urllib.request.urlopen(r, timeout=180) as x:
                return x.read().decode("utf-8", "replace")
        except Exception:
            time.sleep(5)
    return ""


def meta_dari(isi):
    """Ambil pasangan key→value dari blok custom_fields."""
    out = {}
    for mm in re.finditer(r"<member><name>key</name><value><string>(_[^<]+)</string></value></member>\s*"
                          r"<member><name>value</name><value><string>(.*?)</string>", isi, re.S):
        out.setdefault(mm.group(1), html.unescape(mm.group(2)))
    return out


print("=== tarik semua artikel (100 per batch) ===")
semua = []
for offset in (0, 100):
    isi = rpc("wp.getPosts", [1, USER, PASS, {"post_type": "post", "number": 100, "offset": offset,
                                              "post_status": "publish"}])
    # pisahkan per <struct> di dalam array posts
    for blok in re.findall(r"<struct>(.*?)</struct>\s*(?=<struct>|</data>)", isi, re.S):
        pid = re.search(r"<name>post_id</name><value><string>(\d+)</string>", blok)
        slug = re.search(r"<name>post_name</name><value><string>([^<]*)</string>", blok)
        judul = re.search(r"<name>post_title</name><value><string>([^<]*)</string>", blok)
        if not pid or not slug:
            continue
        meta = meta_dari(blok)
        semua.append({"id": int(pid.group(1)), "slug": slug.group(1), "url": "/" + slug.group(1) + "/",
                      "judul": html.unescape(judul.group(1)) if judul else "",
                      "fokus": meta.get("_yoast_wpseo_focuskw") or "",
                      "seo_title": meta.get("_yoast_wpseo_title") or "",
                      "metadesc": meta.get("_yoast_wpseo_metadesc") or ""})
    print(f"   offset {offset}: total terkumpul {len(semua)}")
    if len(semua) == 0:
        break

print(f"\n=== audit meta dari {len(semua)} artikel (sumber: XML-RPC, bukan REST) ===")
tanpa_fokus = [a for a in semua if not a["fokus"]]
tanpa_desc = [a for a in semua if not a["metadesc"]]
tanpa_title = [a for a in semua if not a["seo_title"]]
title_panjang = [a for a in semua if len(a["seo_title"]) > 60]
desc_panjang = [a for a in semua if len(a["metadesc"]) > 158]
desc_pendek = [a for a in semua if a["metadesc"] and len(a["metadesc"]) < 70]
fokus_panjang = [a for a in semua if len(a["fokus"].split()) > 5]
brand_kapital = [a for a in semua if "BENGKEL DAS INDONESIA" in a["seo_title"]]

for nama, daftar in (("tanpa focus keyphrase", tanpa_fokus), ("tanpa meta description", tanpa_desc),
                     ("tanpa SEO title", tanpa_title), ("SEO title > 60 char (terpotong)", title_panjang),
                     ("meta desc > 158 char (terpotong)", desc_panjang),
                     ("meta desc < 70 char (terlalu pendek)", desc_pendek),
                     ("focus keyphrase > 5 kata", fokus_panjang),
                     ("SEO title memakai brand KAPITAL di judul", brand_kapital)):
    print(f"   {nama:<38} {len(daftar):>3} artikel")

print("\n=== 8 judul terpanjang (pasti terpotong di Google) ===")
for a in sorted(semua, key=lambda x: -len(x["seo_title"]))[:8]:
    print(f"   {len(a['seo_title']):>3} char | {a['seo_title'][:88]}")

json.dump(semua, open(f"{WS}/drafts/das_meta_artikel.json", "w"), indent=1, ensure_ascii=False)
print(f"\n→ drafts/das_meta_artikel.json")
