"""Tests for auth module."""

from __future__ import annotations

import pytest
import respx
from httpx import Response

from melogenai.auth import AuthManager
from melogenai.config import Config
from melogenai.exceptions import AuthenticationError

from conftest import TEST_API_KEY, TEST_BASE_URL, TEST_JWT


class TestAuthManager:
    def test_get_token_success(self, config: Config, mock_api: respx.MockRouter) -> None:
        auth = AuthManager(config)
        token_data = auth.get_token(TEST_API_KEY)

        assert token_data["token"] == TEST_JWT
        assert token_data["user_id"] == "user_123"
        assert "expires_at" in token_data

    def test_get_token_cached(self, config: Config, mock_api: respx.MockRouter) -> None:
        auth = AuthManager(config)

        # First call hits the API
        token_data1 = auth.get_token(TEST_API_KEY)
        # Second call should use cache
        token_data2 = auth.get_token(TEST_API_KEY)

        assert token_data1["token"] == token_data2["token"]
        assert mock_api["auth_verify"].call_count == 1

    def test_get_token_invalid_key(self, config: Config, mock_api: respx.MockRouter) -> None:
        mock_api.post("/api/api-keys/verify").respond(
            json={"valid": False},
        )
        auth = AuthManager(config)

        with pytest.raises(AuthenticationError, match="Invalid API key"):
            auth.get_token(TEST_API_KEY)

    def test_invalidate_clears_cache(self, config: Config, mock_api: respx.MockRouter) -> None:
        auth = AuthManager(config)
        auth.get_token(TEST_API_KEY)

        auth.invalidate(TEST_API_KEY)

        # Next call should hit the API again
        auth.get_token(TEST_API_KEY)
        assert mock_api["auth_verify"].call_count == 2

    @pytest.mark.asyncio
    async def test_async_get_token_success(self, config: Config, mock_api: respx.MockRouter) -> None:
        auth = AuthManager(config)
        token_data = await auth.async_get_token(TEST_API_KEY)

        assert token_data["token"] == TEST_JWT
        assert token_data["user_id"] == "user_123"

    @pytest.mark.asyncio
    async def test_async_get_token_cached(self, config: Config, mock_api: respx.MockRouter) -> None:
        auth = AuthManager(config)
        await auth.async_get_token(TEST_API_KEY)
        await auth.async_get_token(TEST_API_KEY)

        assert mock_api["auth_verify"].call_count == 1
