"""Wikipedia pageview trend by agent class (human / spider / automated), from the open
Wikimedia Pageviews API. No key required.

  python wikipedia_pageview_trend.py
"""
import json
import time
import urllib.parse
import urllib.request

UA = "vibeagentmaking-research/1.0 (+https://vibeagentmaking.com/)"
BASE = "https://wikimedia.org/api/rest_v1/metrics/pageviews"


def get(url):
    req = urllib.request.Request(url, headers={"User-Agent": UA, "Accept": "application/json"})
    for attempt in range(3):
        try:
            with urllib.request.urlopen(req, timeout=60) as r:
                return json.load(r)
        except Exception as exc:
            if attempt == 2:
                return {"__error__": f"{type(exc).__name__}: {exc}"}
            time.sleep(2)


def agg(project, agent, start, end, gran="monthly"):
    u = f"{BASE}/aggregate/{project}/all-access/{agent}/{gran}/{start}/{end}"
    d = get(u)
    if "__error__" in d:
        return None, d["__error__"]
    return {i["timestamp"][:6]: i["views"] for i in d.get("items", [])}, None


def article(proj, title, start, end, agent="user", gran="monthly"):
    t = urllib.parse.quote(title, safe="")
    u = f"{BASE}/per-article/{proj}/all-access/{agent}/{t}/{gran}/{start}/{end}"
    d = get(u)
    if "__error__" in d:
        return None, d["__error__"]
    return {i["timestamp"][:6]: i["views"] for i in d.get("items", [])}, None


if __name__ == "__main__":
    START, END = "2021010100", "2026080100"
    out = {}
    for agent in ("user", "spider", "automated"):
        m, err = agg("en.wikipedia", agent, START, END)
        out[agent] = m
        print(f"# agent={agent}: {'ERROR ' + err if err else str(len(m)) + ' months'}")
    json.dump(out, open("wmf_agg.json", "w"), indent=0)

    print("\nmonth      user(M)   spider(M)  automated(M)   user YoY%")
    u = out.get("user") or {}
    s = out.get("spider") or {}
    a = out.get("automated") or {}
    for k in sorted(u):
        yr, mo = int(k[:4]), k[4:]
        prev = f"{yr-1}{mo}"
        yoy = ((u[k] - u[prev]) / u[prev] * 100) if prev in u else None
        print(f"{k}   {u[k]/1e6:9.0f} {s.get(k,0)/1e6:10.0f} {a.get(k,0)/1e6:12.0f}"
              f"   {('%+.1f' % yoy) if yoy is not None else '   n/a'}")
