"""Integration tests for auth/rate-limit/quota on gateway endpoints."""

from __future__ import annotations

import time

import pytest
from fastapi.testclient import TestClient

from sagellm_gateway import server
from sagellm_gateway.adapters.base import BaseAdapter
from sagellm_gateway.config import (
    APIKeyConfig,
    QuotaConfig,
    RateLimitConfig,
    SecurityConfig,
    set_security_config,
)
from sagellm_gateway.models import (
    ChatCompletionChoice,
    ChatCompletionResponse,
    ChatCompletionUsage,
    ChatMessage,
    EmbeddingData,
    EmbeddingResponse,
    EmbeddingUsage,
)


class _FakeAdapter(BaseAdapter):
    async def chat_completions(self, request):
        return ChatCompletionResponse(
            id="chatcmpl-test",
            object="chat.completion",
            created=int(time.time()),
            model=request.model,
            choices=[
                ChatCompletionChoice(
                    index=0,
                    message=ChatMessage(role="assistant", content="ok"),
                    finish_reason="stop",
                )
            ],
            usage=ChatCompletionUsage(prompt_tokens=3, completion_tokens=2, total_tokens=5),
        )

    async def embeddings(self, request):
        return EmbeddingResponse(
            object="list",
            data=[EmbeddingData(object="embedding", embedding=[0.1, 0.2], index=0)],
            model=request.model,
            usage=EmbeddingUsage(prompt_tokens=2, total_tokens=2),
        )

    async def list_models(self):
        return [{"id": "test-model", "object": "model", "created": int(time.time())}]


@pytest.fixture(autouse=True)
def _reset_security_singletons(monkeypatch):
    monkeypatch.setattr("sagellm_gateway.auth._auth_manager", None)
    monkeypatch.setattr("sagellm_gateway.rate_limit._rate_limiter", None)
    monkeypatch.setattr("sagellm_gateway.quota._quota_manager", None)
    set_security_config(SecurityConfig())
    yield
    monkeypatch.setattr("sagellm_gateway.auth._auth_manager", None)
    monkeypatch.setattr("sagellm_gateway.rate_limit._rate_limiter", None)
    monkeypatch.setattr("sagellm_gateway.quota._quota_manager", None)
    set_security_config(SecurityConfig())


class TestSecurityIntegration:
    def test_chat_requires_api_key_when_enabled(self, client: TestClient) -> None:
        set_security_config(
            SecurityConfig(
                api_key=APIKeyConfig(enabled=True, api_keys={"sk-integration": "user_alice"}),
            )
        )
        server.set_adapter(_FakeAdapter())

        response = client.post(
            "/v1/chat/completions",
            json={
                "model": "test-model",
                "messages": [{"role": "user", "content": "hello"}],
                "stream": False,
            },
        )

        assert response.status_code == 401

    def test_chat_rate_limit_enforced(self, client: TestClient) -> None:
        set_security_config(
            SecurityConfig(
                api_key=APIKeyConfig(enabled=True, api_keys={"sk-integration": "user_alice"}),
                rate_limit=RateLimitConfig(enabled=True, rpm_per_user={"user_alice": 1}),
            )
        )
        server.set_adapter(_FakeAdapter())

        headers = {"Authorization": "Bearer sk-integration"}
        payload = {
            "model": "test-model",
            "messages": [{"role": "user", "content": "hello"}],
            "stream": False,
        }

        first = client.post("/v1/chat/completions", json=payload, headers=headers)
        assert first.status_code == 200

        second = client.post("/v1/chat/completions", json=payload, headers=headers)
        assert second.status_code == 429

    def test_chat_quota_enforced(self, client: TestClient) -> None:
        set_security_config(
            SecurityConfig(
                api_key=APIKeyConfig(enabled=True, api_keys={"sk-integration": "user_alice"}),
                quota=QuotaConfig(enabled=True, daily_requests_per_user={"user_alice": 1}),
            )
        )
        server.set_adapter(_FakeAdapter())

        headers = {"Authorization": "Bearer sk-integration"}
        payload = {
            "model": "test-model",
            "messages": [{"role": "user", "content": "hello"}],
            "stream": False,
        }

        first = client.post("/v1/chat/completions", json=payload, headers=headers)
        assert first.status_code == 200

        second = client.post("/v1/chat/completions", json=payload, headers=headers)
        assert second.status_code == 403
