#!/usr/bin/env python3
"""TSC: uji apakah meta Yoast ARTIKEL bisa dibaca & ditulis lewat XML-RPC (kasus beranda gagal karena author hilang)."""
import base64, re, json, 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_tsc", f"{WS}/cfg_tsc.py")
mod = importlib.util.module_from_spec(spec); spec.loader.exec_module(mod)
CFG = mod.CFG
DOM, USER, PASS = CFG["domain"], CFG["user"], CFG["pass"]
AUTH = base64.b64encode(f"{USER}:{PASS}".encode()).decode()
UA = {"User-Agent": "Mozilla/5.0"}


def rpc(method, params=()):
    def val(v):
        if isinstance(v, bool):
            return f"<value><boolean>{1 if v else 0}</boolean></value>"
        if isinstance(v, int):
            return f"<value><int>{v}</int></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")
    try:
        with urllib.request.urlopen(r, timeout=120) as x:
            return x.read().decode("utf-8", "replace")
    except Exception as e:
        return f"ERR {str(e)[:100]}"


def fault(isi):
    m = re.search(r"<name>faultString</name><value><string>(.*?)</string>", isi, re.S)
    return m.group(1) if m else None


def rest(p):
    r = urllib.request.Request(f"https://{DOM}{p}", headers={"Authorization": f"Basic {AUTH}", **UA})
    with urllib.request.urlopen(r, timeout=120) as x:
        return json.loads(x.read())


UJI = [("klinik-dni-krian-sidoarjo", None), ("faq-dokter-kulit-krian", None)]
d = rest("/wp-json/wp/v2/posts?per_page=100&_fields=id,slug,author&status=publish")
for slug, _ in list(UJI):
    p = next((x for x in d if x["slug"] == slug), None)
    if not p:
        continue
    print(f"\n=== artikel #{p['id']} /{slug} (penulis id {p['author']}) ===")
    isi = rpc("wp.getPost", [1, USER, PASS, p["id"]])
    rows = re.findall(r"<member><name>key</name><value><string>(_yoast[^<]*)</string></value></member>\s*"
                      r"<member><name>value</name><value><string>(.*?)</string>", isi, re.S)
    print(f"   meta terbaca: {[(k, v[:40]) for k, v in rows][:6]}")
    res = rpc("wp.editPost", [1, USER, PASS, p["id"],
                              {"custom_fields": [{"key": "_yoast_wpseo_focuskw", "value": "uji hermes"}]}])
    f = fault(res)
    print(f"   uji tulis: {'GAGAL — ' + f[:70] if f else 'BERHASIL'}")
    if f:
        # coba betulkan penulis ke user yang ada lalu tulis ulang
        print("   → mencoba ubah penulis ke id 1 lalu tulis ulang")
        body = json.dumps({"author": 1}).encode()
        r = urllib.request.Request(f"https://{DOM}/wp-json/wp/v2/posts/{p['id']}", data=body,
                                   headers={"Authorization": f"Basic {AUTH}", "Content-Type": "application/json", **UA},
                                   method="POST")
        try:
            with urllib.request.urlopen(r, timeout=120) as x:
                print(f"      ubah penulis → HTTP {x.status}")
        except urllib.error.HTTPError as e:
            print(f"      ubah penulis → HTTP {e.code} {e.read().decode()[:80]}")
        res2 = rpc("wp.editPost", [1, USER, PASS, p["id"],
                                   {"custom_fields": [{"key": "_yoast_wpseo_focuskw", "value": "uji hermes"}]}])
        print(f"      tulis ulang: {'GAGAL — ' + (fault(res2) or '')[:60] if fault(res2) else 'BERHASIL ✅'}")
