#!/usr/bin/env python3
"""Read-only Wikipedia API demo extracted from the official Android APK.
Python 3.10+, standard library only. Run: python3 wikipedia_client.py
"""
import argparse
import json
import sys
from datetime import datetime, timezone
from urllib.error import HTTPError, URLError
from urllib.parse import urlencode
from urllib.request import Request, urlopen

PATHS = {'fullTextSearch': 'w/api.php?format=json&formatversion=2&errorformat=html&errorsuselocal=1&action=query&converttitles=&prop=description|pageimages|pageprops|coordinates|info&ppprop=mainpage|disambiguation&generator=search&gsrnamespace=0&gsrwhat=text&inprop=varianttitles|displaytitle&gsrinfo=&gsrprop=redirecttitle&piprop=thumbnail&pilicense=any&pithumbsize=330', 'getInfoWithExtractsByPageTitles': 'w/api.php?format=json&formatversion=2&errorformat=html&errorsuselocal=1&action=query&prop=info|description|pageimages|extracts&exchars=500&exintro=1&explaintext=1&pilicense=any&inprop=varianttitles|displaytitle&redirects=1&pithumbsize=330', 'getLangLinks': 'w/api.php?format=json&formatversion=2&errorformat=html&errorsuselocal=1&action=query&prop=langlinks&lllimit=500&redirects=&converttitles='}
USER_AGENT = "SimpaLabs-APK-Demo/1.0 (https://www.simpalabs.com; security@simpalabs.com)"

class WikipediaClient:
    def __init__(self):
        self.results = []

    def _get(self, method, **params):
        url = "https://en.wikipedia.org/" + PATHS[method] + "&" + urlencode(params)
        request = Request(url, headers={"User-Agent": USER_AGENT, "Accept": "application/json"})
        with urlopen(request, timeout=30) as response:
            status = response.status
            data = json.load(response)
        if "error" in data or "errors" in data:
            raise RuntimeError("Wikipedia returned an API error: " + json.dumps(data))
        pages = data.get("query", {}).get("pages", [])
        if not pages or any("missing" in page for page in pages):
            raise RuntimeError("No matching article. Try another search or title.")
        self.results.append({"method": method, "http_status": status, "url": url})
        return pages

    def search(self, query, limit=3):
        return sorted(self._get("fullTextSearch", gsrsearch=query, gsrlimit=limit), key=lambda page: page.get("index", 0))

    def article(self, title):
        return self._get("getInfoWithExtractsByPageTitles", titles=title)[0]

    def languages(self, title):
        return self._get("getLangLinks", titles=title)[0].get("langlinks", [])


def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("--query", default="Lagos")
    parser.add_argument("--json", action="store_true", help="Print the verification record as JSON")
    args = parser.parse_args()
    client = WikipediaClient()
    try:
        pages = client.search(args.query)
        article = client.article(pages[0]["title"])
        languages = client.languages(article["title"])
        if not article.get("extract") or not languages:
            raise RuntimeError("The article is missing an extract or language links.")
    except (HTTPError, URLError, TimeoutError, ValueError, RuntimeError) as error:
        print("Demo failed: " + str(error), file=sys.stderr)
        return 1
    record = {
        "verified_at": datetime.now(timezone.utc).isoformat(),
        "query": args.query,
        "search_titles": [page["title"] for page in pages],
        "article_title": article["title"],
        "article_page_id": article["pageid"],
        "article_extract_present": bool(article.get("extract")),
        "language_count": len(languages),
        "requests": client.results,
        "passed": len(client.results) == 3 and all(item["http_status"] == 200 for item in client.results),
    }
    if args.json:
        print(json.dumps(record, indent=2))
    else:
        print("Wikipedia APK → Python client")
        print("PASS  Search: " + ", ".join(record["search_titles"]))
        print("PASS  Article: " + record["article_title"] + " (extract returned)")
        print("PASS  Languages: " + str(record["language_count"]) + " returned")
        print("3 API calls · 3 HTTP 200 responses")
    return 0

if __name__ == "__main__":
    sys.exit(main())
