"""Shared wordpress test helper — install-wizard client + admin credentials.

A fresh CI deploy of the recipe does NOT run `core_install` (no POST_DEPLOY_CMDS in the CI
env), so the app serves the WP install wizard until something completes it. The custom tests
complete it here (run-scoped class-B credentials; the whole app — DB volume + secrets — is
destroyed at teardown) and then exercise the real APIs (wp-json + XML-RPC) as an installed
site. `ensure_installed` is idempotent so any custom test can call it first regardless of
alphabetical ordering.
"""

from __future__ import annotations

import ssl
import urllib.error
import urllib.parse
import urllib.request

# Per-run *.ci.commoninternet.net domains use the operator wildcard cert via the Traefik file
# provider; the real-cert chain check is done once in the generic install assertion.
_CTX = ssl.create_default_context()
_CTX.check_hostname = False
_CTX.verify_mode = ssl.CERT_NONE

ADMIN_USER = "ccci-admin"
ADMIN_PW = "Ccci-Wp-Test-Pw-2026!x"  # strong so the wizard needs no pw_weak confirmation
ADMIN_EMAIL = "ccci-admin@ccci.example.com"
BLOG_TITLE = "CCCI Test Site"


def _open(url: str, data: bytes | None = None, timeout: int = 60) -> tuple[int, str]:
    req = urllib.request.Request(url, data=data)
    if data is not None:
        req.add_header("Content-Type", "application/x-www-form-urlencoded")
    try:
        with urllib.request.urlopen(req, timeout=timeout, context=_CTX) as resp:
            return resp.getcode(), resp.read().decode(errors="replace")
    except urllib.error.HTTPError as e:
        try:
            return e.code, e.read().decode(errors="replace")
        except Exception:  # noqa: BLE001
            return e.code, ""


def fetch_text(url: str, timeout: int = 60) -> tuple[int, str]:
    """GET a URL and return (status, body-text) — for HTML-content assertions."""
    return _open(url, timeout=timeout)


def ensure_installed(domain: str) -> bool:
    """Complete the WP install wizard if it hasn't been completed yet.

    Returns True if THIS call ran the install, False if the site was already installed.
    Fails the calling test (assert) if the wizard is reachable but the install POST fails.
    """
    base = f"https://{domain}"
    status, body = _open(f"{base}/wp-admin/install.php")
    assert status == 200, f"GET /wp-admin/install.php HTTP {status} (body[:200]={body[:200]!r})"
    if "already installed" in body.lower():
        return False
    assert "wordpress" in body.lower(), (
        f"/wp-admin/install.php does not look like the WP installer: {body[:300]!r}"
    )
    assert "database connection" not in body.lower(), (
        "WP installer reports a database connection problem — app→mariadb wiring is broken"
    )

    form = urllib.parse.urlencode(
        {
            "weblog_title": BLOG_TITLE,
            "user_name": ADMIN_USER,
            "admin_password": ADMIN_PW,
            "admin_password2": ADMIN_PW,
            "admin_email": ADMIN_EMAIL,
            "blog_public": "1",
            "Submit": "Install WordPress",
            "language": "",
        }
    ).encode()
    status, body = _open(f"{base}/wp-admin/install.php?step=2", data=form, timeout=180)
    assert status == 200, f"install POST HTTP {status} (body[:300]={body[:300]!r})"
    lowered = body.lower()
    assert "success" in lowered or "wordpress has been installed" in lowered, (
        f"install POST did not report success: {body[:400]!r}"
    )
    return True
