"""Tests for auth_service: JWT creation/validation, dev login, user creation."""
import uuid

import pytest

from services.auth_service import AuthService


@pytest.fixture
def auth_service():
    return AuthService()


class TestJWT:
    def test_create_and_validate_token(self, auth_service):
        """Token round-trip: create → validate → same payload."""
        from models.sql.user import UserModel

        user = UserModel(
            id=uuid.uuid4(),
            email="jwt@test.com",
            display_name="JWT User",
            role="user",
            is_active=True,
        )
        token = auth_service.create_session_jwt(user)
        payload = auth_service.validate_token(token)

        assert payload is not None
        assert payload["sub"] == str(user.id)
        assert payload["email"] == "jwt@test.com"
        assert payload["role"] == "user"

    def test_validate_invalid_token(self, auth_service):
        assert auth_service.validate_token("garbage.token.here") is None

    def test_validate_tampered_token(self, auth_service):
        from models.sql.user import UserModel

        user = UserModel(
            id=uuid.uuid4(),
            email="tamper@test.com",
            display_name="Tamper",
            role="user",
            is_active=True,
        )
        token = auth_service.create_session_jwt(user)
        # Tamper with the token
        tampered = token[:-5] + "XXXXX"
        assert auth_service.validate_token(tampered) is None


class TestDevLogin:
    async def test_dev_login_success(self, auth_service, session):
        """Dev mode: correct password creates user."""
        user = await auth_service.dev_login("dev@test.com", "testpass", session)
        assert user is not None
        assert user.email == "dev@test.com"

    async def test_dev_login_wrong_password(self, auth_service, session):
        user = await auth_service.dev_login("dev@test.com", "wrongpass", session)
        assert user is None

    async def test_dev_login_idempotent(self, auth_service, session):
        """Logging in twice with same email returns same user."""
        user1 = await auth_service.dev_login("dev@test.com", "testpass", session)
        user2 = await auth_service.dev_login("dev@test.com", "testpass", session)
        assert user1.id == user2.id


class TestDevMode:
    def test_is_dev_mode_when_no_azure(self, auth_service):
        """Without AZURE_AD_TENANT_ID, service is in dev mode."""
        assert auth_service.is_dev_mode is True

    def test_get_authorization_url_raises_in_dev_mode(self, auth_service):
        with pytest.raises(ValueError, match="dev login"):
            auth_service.get_authorization_url()
