#!/usr/bin/env python3
"""TSC: diagnosa kegagalan tulis meta — pesan fault lengkap + peran user watibot."""
import base64, json, 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_tsc", f"{WS}/cfg_tsc.py")
mod = importlib.util.module_from_spec(spec); spec.loader.exec_module(mod)
CFG = mod.CFG
DOM = CFG["domain"]
USER, PASS = 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.status, x.read().decode("utf-8", "replace")
    except urllib.error.HTTPError as e:
        return e.code, e.read().decode("utf-8", "replace")


print("=== 1. pesan fault lengkap saat menulis meta ===")
st, isi = rpc("wp.editPost", [1, USER, PASS, 409,
                              {"custom_fields": [{"id": 5216, "key": "_yoast_wpseo_metadesc",
                                                  "value": "Uji simpan meta."}]}])
fault = re.search(r"<name>faultString</name><value><string>(.*?)</string>", isi, re.S)
kode = re.search(r"<name>faultCode</name><value><int>(\d+)</int>", isi)
print(f"   HTTP {st} | faultCode={kode.group(1) if kode else '-'} | pesan: {fault.group(1)[:200] if fault else isi[:200]}")

print("\n=== 2. peran user watibot ===")
r = urllib.request.Request(f"https://{DOM}/wp-json/wp/v2/users/me?context=edit",
                           headers={"Authorization": f"Basic {AUTH}", **UA})
try:
    with urllib.request.urlopen(r, timeout=90) as x:
        me = json.loads(x.read())
    print(f"   nama: {me.get('name')} | id {me.get('id')} | roles: {me.get('roles')}")
    caps = me.get("capabilities") or {}
    print(f"   edit_pages: {caps.get('edit_pages')} | edit_others_posts: {caps.get('edit_others_posts')} | "
          f"manage_options: {caps.get('manage_options')} | unfiltered_html: {caps.get('unfiltered_html')}")
except urllib.error.HTTPError as e:
    print("   gagal:", e.code, e.read().decode()[:150])

print("\n=== 3. coba tulis lewat REST dulu (kunci meta Yoast terdaftar?) ===")
r = urllib.request.Request(f"https://{DOM}/wp-json/wp/v2/pages/409?context=edit&_fields=id,meta",
                           headers={"Authorization": f"Basic {AUTH}", **UA})
with urllib.request.urlopen(r, timeout=90) as x:
    d = json.loads(x.read())
kunci = sorted((d.get("meta") or {}).keys())
print(f"   {len(kunci)} kunci meta: {kunci[:12]}")
print(f"   yoast terdaftar: {'YA' if any('yoast' in k for k in kunci) else 'TIDAK'}")

print("\n=== 4. uji tulis meta lewat REST ===")
body = json.dumps({"meta": {"_yoast_wpseo_metadesc": "Uji simpan lewat REST."}}).encode()
r = urllib.request.Request(f"https://{DOM}/wp-json/wp/v2/pages/409", data=body,
                           headers={"Authorization": f"Basic {AUTH}", "Content-Type": "application/json", **UA},
                           method="POST")
try:
    with urllib.request.urlopen(r, timeout=120) as x:
        res = json.loads(x.read())
    print(f"   HTTP {x.status} | meta tersimpan: {res.get('meta')}")
except urllib.error.HTTPError as e:
    print(f"   HTTP {e.code} | {e.read().decode()[:200]}")
