"""Tests fuer die Admin-Selbstanmeldung in die App (GET /api/admin/login).

Der Endpunkt liegt in Produktion hinter Authelia (nginx setzt Remote-User).
Hier wird die Forward-Auth ueber den vertrauten Proxy simuliert.
"""
import pytest
from fastapi.testclient import TestClient

import app.dependencies as deps
from app.auth import CAPABILITY_COOKIE
from app.config import settings
from app.main import app

client = TestClient(app)

HEADER = "X-Remote-User"
# Starlette-TestClient meldet sich als Host "testclient" -> als vertrauten Proxy setzen.
TRUSTED = "testclient"


@pytest.fixture
def forward_auth(monkeypatch):
    monkeypatch.setattr(settings, "trusted_auth_header", HEADER)
    monkeypatch.setattr(settings, "trusted_proxy_ips", TRUSTED)
    monkeypatch.setattr(settings, "admin_users", "dschlueter")
    monkeypatch.setattr(settings, "auth_enabled", True)


def test_admin_login_sets_cookie_and_redirects(forward_auth):
    r = client.get("/api/admin/login", headers={HEADER: "dschlueter"},
                   follow_redirects=False)
    assert r.status_code == 303
    assert r.headers["location"] == "/"
    set_cookie = r.headers.get("set-cookie", "")
    assert f"{CAPABILITY_COOKIE}=" in set_cookie
    assert "HttpOnly" in set_cookie


def test_admin_login_cookie_token_authenticates(forward_auth):
    r = client.get("/api/admin/login", headers={HEADER: "dschlueter"},
                   follow_redirects=False)
    # Den frisch gesetzten Token aus dem Set-Cookie ziehen ...
    raw = r.headers["set-cookie"].split(f"{CAPABILITY_COOKIE}=", 1)[1].split(";", 1)[0]
    # ... und pruefen, dass er den Admin-Nutzer authentifiziert.
    user = deps.get_store().get_user_by_token(raw)
    assert user is not None
    assert user.external_id == "dschlueter"


def test_admin_login_rotates_token(forward_auth):
    r1 = client.get("/api/admin/login", headers={HEADER: "dschlueter"},
                    follow_redirects=False)
    raw1 = r1.headers["set-cookie"].split(f"{CAPABILITY_COOKIE}=", 1)[1].split(";", 1)[0]
    r2 = client.get("/api/admin/login", headers={HEADER: "dschlueter"},
                    follow_redirects=False)
    raw2 = r2.headers["set-cookie"].split(f"{CAPABILITY_COOKIE}=", 1)[1].split(";", 1)[0]
    assert raw1 != raw2
    # Der alte Token ist nach der Rotation ungueltig.
    assert deps.get_store().get_user_by_token(raw1) is None
    assert deps.get_store().get_user_by_token(raw2) is not None


def test_admin_login_rejects_non_admin(forward_auth):
    r = client.get("/api/admin/login", headers={HEADER: "lieschen"},
                   follow_redirects=False)
    assert r.status_code == 403


def test_admin_login_rejects_without_identity(forward_auth):
    # Vertrauter Proxy, aber kein Identitaets-Header -> keine Admin-Identitaet -> 403.
    # (In Produktion faengt nginx das vorher mit dem Authelia-Redirect ab.)
    r = client.get("/api/admin/login", follow_redirects=False)
    assert r.status_code == 403
