"""_oauth_redirect_uri decides where Google sends the OAuth code back. In production it must ALWAYS
use the fixed configured URL and never trust the request Host (a forged Host must not be able to
redirect the code); in local dev it honors a small allowlist of dev origins so a login started on the
Vite server (:5173) returns to :5173."""
from types import SimpleNamespace

from app import auth


def _req(host):
    """Minimal stand-in for a Starlette Request: only .headers.get('host') is read."""
    return SimpleNamespace(headers={"host": host} if host is not None else {})


def _dev_settings():
    return SimpleNamespace(
        session_https_only=False,
        oauth_redirect_url="http://localhost:8080/auth/callback",
    )


def _prod_settings():
    return SimpleNamespace(
        session_https_only=True,
        oauth_redirect_url="https://siftlode.example.eu/auth/callback",
    )


def test_dev_known_host_returns_to_that_origin(monkeypatch):
    monkeypatch.setattr(auth, "settings", _dev_settings())
    # Each allowlisted host keeps the whole round-trip on one origin (all four are registered in the
    # Google console), so the redirect_uri matches the host the flow started on.
    assert auth._oauth_redirect_uri(_req("localhost:5173")) == "http://localhost:5173/auth/callback"
    assert auth._oauth_redirect_uri(_req("localhost:8080")) == "http://localhost:8080/auth/callback"
    assert auth._oauth_redirect_uri(_req("127.0.0.1:5173")) == "http://127.0.0.1:5173/auth/callback"
    assert auth._oauth_redirect_uri(_req("127.0.0.1:8080")) == "http://127.0.0.1:8080/auth/callback"


def test_dev_host_is_case_insensitive(monkeypatch):
    monkeypatch.setattr(auth, "settings", _dev_settings())
    assert auth._oauth_redirect_uri(_req("LOCALHOST:5173")) == "http://localhost:5173/auth/callback"


def test_dev_unknown_or_missing_host_falls_back_to_configured(monkeypatch):
    monkeypatch.setattr(auth, "settings", _dev_settings())
    # An origin not on the allowlist (or a request with no Host) must not drive the redirect.
    assert auth._oauth_redirect_uri(_req("evil.example.com")) == "http://localhost:8080/auth/callback"
    assert auth._oauth_redirect_uri(_req(None)) == "http://localhost:8080/auth/callback"


def test_prod_ignores_host_even_when_it_matches_a_dev_origin(monkeypatch):
    monkeypatch.setattr(auth, "settings", _prod_settings())
    # The host-injection guard: in production the fixed URL wins regardless of the Host header.
    assert (
        auth._oauth_redirect_uri(_req("localhost:5173"))
        == "https://siftlode.example.eu/auth/callback"
    )
    assert (
        auth._oauth_redirect_uri(_req("attacker.test"))
        == "https://siftlode.example.eu/auth/callback"
    )
