#!/usr/bin/env python3
"""DAS: cari ID penulis yang valid, lalu pasang kanonik + noindex dengan penulis itu."""
import base64, html, json, re, sys, 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()
UA = {"User-Agent": "Mozilla/5.0"}

PASANGAN = {6304: 5569, 6566: 5569, 8081: 5657, 6708: 5684, 6705: 5684,
            6932: 6392, 5600: 6392, 6435: 6430, 5603: 6430, 6711: 8296}


def rpc(method, params=()):
    def val(v):
        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=180) as x:
            return x.read().decode("utf-8", "replace")
    except Exception as e:
        return f"ERR {str(e)[:80]}"


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


print("=== penulis yang valid ===")
isi = rpc("wp.getAuthors", [1, USER, PASS])
for mm in re.finditer(r"<name>user_id</name><value><string>(\d+)</string></value>.*?<name>display_name</name><value><string>([^<]*)</string>", isi, re.S):
    print(f"   id {mm.group(1):<4} {mm.group(2)}")
ids = re.findall(r"<name>user_id</name><value><string>(\d+)</string>", isi)
if not ids:
    print("   (wp.getAuthors kosong) — coba dari artikel yang sudah berhasil")
    for pid in (5657, 6392):
        p = rest(f"/wp-json/wp/v2/posts/{pid}?context=edit&_fields=author")
        print(f"   #{pid} penulis: {p.get('author')}")
    ids = [str(rest("/wp-json/wp/v2/posts/5657?context=edit&_fields=author").get("author", 1))]

print("\n=== penulis artikel yang bermasalah ===")
for pid in PASANGAN:
    p = rest(f"/wp-json/wp/v2/posts/{pid}?context=edit&_fields=author,slug")
    print(f"   #{pid} penulis {p.get('author')} | /{str(p.get('slug'))[:44]}")

PENULIS = str(ids[0]) if ids else "1"
print(f"\n=== memasang kanonik + noindex dengan penulis id {PENULIS} ===")
if "--apply" in sys.argv:
    for pid, mid in PASANGAN.items():
        if rest(f"/wp-json/wp/v2/posts/{pid}?context=edit&_fields=link").get("err"):
            continue
        link_menang = rest(f"/wp-json/wp/v2/posts/{mid}?context=edit&_fields=link").get("link", "")
        isi2 = rpc("wp.editPost", [1, USER, PASS, pid, {"post_author": PENULIS, "custom_fields": [
            {"key": "_yoast_wpseo_canonical", "value": link_menang},
            {"key": "_yoast_wpseo_meta-robots-noindex", "value": "1"}]}])
        gagal = re.search(r"<name>faultString</name><value><string>(.*?)</string>", isi2, re.S)
        cek = rpc("wp.getPost", [1, USER, PASS, pid])
        md = {}
        for mm in re.finditer(r"<member><name>key</name><value><string>(_[^<]+)</string></value></member>\s*"
                              r"<member><name>value</name><value><string>(.*?)</string>", cek, re.S):
            md.setdefault(mm.group(1), html.unescape(mm.group(2)))
        ok = md.get("_yoast_wpseo_meta-robots-noindex") == "1" and md.get("_yoast_wpseo_canonical", "").startswith("http")
        print(f"   #{pid} → #{mid} : {'✅ terpasang' if ok else '❌ gagal ' + str(gagal.group(1) if gagal else '')[:60]}")
else:
    print("   (dry run, pakai --apply)")
