import httpx

from auditor.core.base import Validator


class OpenAIValidator(Validator):
    """Validates OpenAI API keys via the models endpoint."""

    name = "openai"

    async def validate(self, client: httpx.AsyncClient, key: str) -> bool:
        return await self._safe_fetch(
            client,
            "https://api.openai.com/v1/models",
            headers={"Authorization": f"Bearer {key}"},
        )


class AnthropicValidator(Validator):
    """Validates Anthropic (Claude) API keys via the models endpoint."""

    name = "anthropic"

    async def validate(self, client: httpx.AsyncClient, key: str) -> bool:
        return await self._safe_fetch(
            client,
            "https://api.anthropic.com/v1/models",
            headers={
                "x-api-key": key,
                "anthropic-version": "2023-06-01",
            },
        )


class GeminiValidator(Validator):
    """Validates Google Gemini API keys via the models listing endpoint."""

    name = "gemini"

    async def validate(self, client: httpx.AsyncClient, key: str) -> bool:
        return await self._safe_fetch(
            client,
            f"https://generativelanguage.googleapis.com/v1beta/models?key={key}",
        )


class DeepSeekValidator(Validator):
    """Validates DeepSeek API keys via the user balance endpoint.

    Uses ``/user/balance`` instead of ``/models`` because the balance
    endpoint requires strict authentication, providing a more reliable
    validation signal.
    """

    name = "deepseek"

    async def validate(self, client: httpx.AsyncClient, key: str) -> bool:
        return await self._safe_fetch(
            client,
            "https://api.deepseek.com/user/balance",
            headers={
                "Authorization": f"Bearer {key}",
                "Accept": "application/json",
            },
        )


class GroqValidator(Validator):
    """Validates Groq API keys via the OpenAI-compatible models endpoint."""

    name = "groq"

    async def validate(self, client: httpx.AsyncClient, key: str) -> bool:
        return await self._safe_fetch(
            client,
            "https://api.groq.com/openai/v1/models",
            headers={"Authorization": f"Bearer {key}"},
        )


class PerplexityValidator(Validator):
    """Validates Perplexity API keys via the models endpoint.

    Perplexity returns HTTP 400 for authenticated but malformed requests,
    so we add 400 to the set of valid confirmation codes alongside the
    standard 200 and 429.
    """

    name = "perplexity"

    async def validate(self, client: httpx.AsyncClient, key: str) -> bool:
        return await self._safe_fetch(
            client,
            "https://api.perplexity.ai/models",
            headers={
                "Authorization": f"Bearer {key}",
                "Accept": "application/json",
            },
            valid_codes=(200, 400, 429),
        )


class HuggingFaceValidator(Validator):
    """Validates Hugging Face API tokens via the whoami endpoint."""

    name = "huggingface"

    async def validate(self, client: httpx.AsyncClient, key: str) -> bool:
        return await self._safe_fetch(
            client,
            "https://huggingface.co/api/whoami-v2",
            headers={"Authorization": f"Bearer {key}"},
        )


class OpenRouterValidator(Validator):
    """Validates OpenRouter API keys via the auth/key endpoint."""

    name = "openrouter"

    async def validate(self, client: httpx.AsyncClient, key: str) -> bool:
        return await self._safe_fetch(
            client,
            "https://openrouter.ai/api/v1/auth/key",
            headers={"Authorization": f"Bearer {key}"},
        )


class ReplicateValidator(Validator):
    """Validates Replicate API tokens via the account endpoint."""

    name = "replicate"

    async def validate(self, client: httpx.AsyncClient, key: str) -> bool:
        return await self._safe_fetch(
            client,
            "https://api.replicate.com/v1/account",
            headers={"Authorization": f"Bearer {key}"},
        )


class RunwayMLValidator(Validator):
    """Validates RunwayML API keys via the models endpoint."""

    name = "runwayml"

    async def validate(self, client: httpx.AsyncClient, key: str) -> bool:
        return await self._safe_fetch(
            client,
            "https://api.runwayml.com/v1/models",
            headers={
                "Authorization": f"Bearer {key}",
                "X-Runway-Version": "2024-05-15",
            },
        )
