import importlib
import sys


def test_mcp_endpoint_guarded_and_csrf_exempt(monkeypatch, tmp_path):
    # DB éphémère + secrets requis par init_auth/init_subscriptions.
    monkeypatch.setenv("USERS_DB_PATH", str(tmp_path / "users.test.sqlite"))
    monkeypatch.setenv("SECRET_KEY", "test-secret-key")
    monkeypatch.setenv("APP_BASE_URL", "http://localhost:8050")
    monkeypatch.setenv("DASH_MCP_ENABLED", "true")

    from src.auth import db as auth_db

    auth_db.reset_conn_for_tests()

    # Recharger src.app avec le flag activé ré-exécute la découverte use_pages,
    # qui REMPLACE les objets-modules src.pages.* dans sys.modules (Dash les
    # ré-exécute via exec_module). Sans restauration, un test ultérieur ayant
    # importé une fonction de page (ex. tests/test_grid.py: get_rows_tableau)
    # verrait son patch("src.pages.tableau.<x>") cibler un objet-module différent
    # de celui d'où provient la fonction importée → pollution inter-tests. On
    # snapshot les modules concernés puis on les restaure en fin de test.
    snapshot = {
        name: mod
        for name, mod in sys.modules.items()
        if name == "src.app" or name.startswith("src.pages")
    }
    try:
        import src.app as app_module

        app_module = importlib.reload(app_module)
        client = app_module.app.server.test_client()

        # Pas de jeton : le garde renvoie 401 (et NON une erreur CSRF 400/403),
        # ce qui prouve exemption CSRF + garde câblés sur /_mcp.
        resp = client.post("/_mcp", json={"jsonrpc": "2.0", "method": "ping", "id": 1})
        assert resp.status_code == 401
        assert resp.headers.get("WWW-Authenticate") == 'Bearer realm="colibre-mcp"'
    finally:
        # Restaurer les objets-modules d'origine et purger ceux créés par le
        # reload, pour ne pas polluer les tests suivants.
        for name in [
            n for n in sys.modules if n == "src.app" or n.startswith("src.pages")
        ]:
            if name in snapshot:
                sys.modules[name] = snapshot[name]
            else:
                del sys.modules[name]
        auth_db.reset_conn_for_tests()
