"""OIDC SSO: login redirect, callback provisioning, and the disabled guard."""

from __future__ import annotations

from legate.config import get_settings
from legate.repositories import users as users_repo
from legate.security.oidc import OIDCIdentity, set_oidc_client_factory


class _FakeIdP:
    def authorization_url(self, state: str) -> str:
        return f"https://idp.example.com/authorize?state={state}"

    def exchange_code(self, code: str) -> OIDCIdentity:
        return OIDCIdentity(subject="idp-sub-1", email="sso.user@corp.com", name="SSO User")


def _enable():
    get_settings().oidc_enabled = True
    set_oidc_client_factory(lambda settings: _FakeIdP())


def test_sso_disabled_returns_404(client):
    assert client.get("/auth/oidc/login", follow_redirects=False).status_code == 404
    assert client.get("/auth/oidc/callback?code=x", follow_redirects=False).status_code == 404


def test_login_redirects_to_idp(client):
    _enable()
    resp = client.get("/auth/oidc/login", follow_redirects=False)
    assert resp.status_code == 307
    assert "idp.example.com/authorize" in resp.headers["location"]


def test_callback_provisions_user_and_returns_tokens(client, session_factory):
    _enable()
    resp = client.get("/auth/oidc/callback?code=abc123&state=s", follow_redirects=False)
    assert resp.status_code == 302
    location = resp.headers["location"]
    assert "access_token=" in location and "refresh_token=" in location

    # The user was provisioned just-in-time.
    session = session_factory()
    user = users_repo.get_by_email(session, "sso.user@corp.com")
    session.close()
    assert user is not None and user.is_active
