"""Issues #218 / #219 (tg12): outbound Wikipedia + Wikidata calls must
identify ShadowBroker via the Wikimedia-recommended User-Agent /
Api-User-Agent headers.

Before this fix, ``backend/services/region_dossier.py`` called
``fetch_with_curl(url)`` with no explicit headers, falling back to the
generic project default UA. That sent a too-anonymous identifier to
Wikimedia. Per Wikimedia's policy
(https://foundation.wikimedia.org/wiki/Policy:Wikimedia_Foundation_User-Agent_Policy)
the API caller should send a stable, contactable identifier so Wikimedia
operators can rate-limit or reach the project.

This test does NOT make network calls. It patches ``fetch_with_curl``
and asserts the headers that get passed through.
"""
from __future__ import annotations

from unittest.mock import MagicMock, patch

import pytest


def _fake_resp(payload: dict, status: int = 200) -> MagicMock:
    r = MagicMock()
    r.status_code = status
    r.json.return_value = payload
    return r


def test_wikidata_call_passes_wikimedia_request_headers():
    from services import region_dossier

    calls = []

    def fake_fetch(url, **kwargs):
        calls.append(kwargs.get("headers"))
        return _fake_resp({"results": {"bindings": []}})

    with patch.object(region_dossier, "fetch_with_curl", side_effect=fake_fetch):
        region_dossier._fetch_wikidata_leader("Testlandia")

    assert calls, "fetch_with_curl was not called"
    headers = calls[0] or {}
    assert "User-Agent" in headers
    assert "Api-User-Agent" in headers
    # Stable identifier should mention the project + a contact path.
    assert "Shadowbroker" in headers["Api-User-Agent"] or "ShadowBroker" in headers["Api-User-Agent"]
    assert "github.com" in headers["Api-User-Agent"].lower()


def test_wikipedia_summary_call_passes_wikimedia_request_headers():
    from services import region_dossier

    calls = []

    def fake_fetch(url, **kwargs):
        calls.append((url, kwargs.get("headers")))
        return _fake_resp(
            {
                "type": "standard",
                "description": "test desc",
                "extract": "test extract",
                "thumbnail": {"source": ""},
            }
        )

    with patch.object(region_dossier, "fetch_with_curl", side_effect=fake_fetch):
        region_dossier._fetch_local_wiki_summary("Paris", "France")

    # At least one Wikipedia REST call was issued.
    wikipedia_calls = [c for c in calls if "wikipedia.org" in c[0]]
    assert wikipedia_calls, "no Wikipedia call was issued"
    for url, headers in wikipedia_calls:
        headers = headers or {}
        assert "User-Agent" in headers, f"missing User-Agent on {url}"
        assert "Api-User-Agent" in headers, f"missing Api-User-Agent on {url}"
        assert "github.com" in headers["Api-User-Agent"].lower()


def test_wikimedia_headers_helper_is_stable():
    """Regression guard: if someone removes the contact path or the
    per-operator handle from the Wikimedia headers, we want a loud
    test failure, not a silent ToS drift.

    Round 7a: the original ``_WIKIMEDIA_REQUEST_HEADERS`` constant was
    replaced with the ``_wikimedia_request_headers()`` function so the
    per-install operator handle is embedded at call time. This test
    pins both the project identifier AND the contact path AND the
    per-operator format.
    """
    from services.region_dossier import _wikimedia_request_headers

    headers = _wikimedia_request_headers()
    aua = headers.get("Api-User-Agent", "")
    ua = headers.get("User-Agent", "")
    for h, label in ((ua, "User-Agent"), (aua, "Api-User-Agent")):
        assert "Shadowbroker" in h or "ShadowBroker" in h, f"{label} missing project id"
        assert "github.com" in h.lower(), f"{label} missing contact URL"
        assert "issues" in h.lower(), f"{label} missing /issues contact path"
        # Round 7a: must include the per-operator handle.
        assert "operator:" in h, f"{label} missing per-operator handle: {h!r}"
