"""Google/Gemini LLM provider for Local Deep Research."""

from loguru import logger

from ....security.log_sanitizer import redact_secrets
from ..openai_base import OpenAICompatibleProvider


class GoogleProvider(OpenAICompatibleProvider):
    """Google Gemini provider using OpenAI-compatible endpoint.

    This uses Google's OpenAI-compatible API endpoint to access Gemini models,
    which automatically supports all current and future Gemini models without
    needing to update the code.
    """

    provider_name = "Google Gemini"
    api_key_setting = "llm.google.api_key"
    default_base_url = "https://generativelanguage.googleapis.com/v1beta/openai"
    default_model = ""  # User must explicitly pick a model — no silent fallback

    # Metadata for auto-discovery
    provider_key = "GOOGLE"
    company_name = "Google"
    is_cloud = True

    @classmethod
    def requires_auth_for_models(cls):
        """Google requires authentication for listing models.

        Note: Google's OpenAI-compatible /models endpoint has a bug (returns 401).
        The native Gemini API endpoint requires an API key.
        """
        return True

    @classmethod
    def list_models_for_api(cls, api_key=None, base_url=None):
        """List available models using Google's native API.

        Args:
            api_key: Google API key
            base_url: Not used - Google uses a fixed endpoint

        Google's OpenAI-compatible /models endpoint returns 401 (bug),
        so we use the native Gemini API endpoint instead.
        """
        if not api_key:
            logger.debug("Google Gemini requires API key for listing models")
            return []

        try:
            from ....security import safe_get

            # Use the native Gemini API endpoint (not OpenAI-compatible).
            # Pass the key via the x-goog-api-key header rather than a
            # ?key=... query parameter so the secret never appears in the
            # request URL — and therefore cannot leak into requests /
            # urllib3 exception messages, which embed the URL but not
            # headers. This is the prevention-by-construction control
            # called for in issue #4184; the redact_secrets() wrap below
            # remains as defense-in-depth.
            url = "https://generativelanguage.googleapis.com/v1beta/models"

            response = safe_get(
                url,
                headers={"x-goog-api-key": api_key},
                timeout=10,
            )

            if response.status_code == 200:
                data = response.json()
                models = []

                for model in data.get("models", []):
                    model_name = model.get("name", "")
                    # Extract just the model ID from "models/gemini-1.5-flash"
                    if model_name.startswith("models/"):
                        model_id = model_name[7:]  # Remove "models/" prefix
                    else:
                        model_id = model_name

                    # Only include generative models (not embedding models)
                    supported_methods = model.get(
                        "supportedGenerationMethods", []
                    )
                    if "generateContent" in supported_methods and model_id:
                        models.append(
                            {
                                "value": model_id,
                                "label": model_id,
                            }
                        )

                logger.info(
                    f"Found {len(models)} generative models from Google Gemini API"
                )
                return models
            logger.warning(
                f"Google Gemini API returned status {response.status_code}"
            )
            return []

        except Exception as e:
            # Defense-in-depth: the primary defense is now the
            # x-goog-api-key header above (prevention by construction —
            # the URL no longer carries the key, so requests/urllib3
            # exception messages cannot embed it). This redact_secrets()
            # wrap stays as a second layer in case a future code path
            # reintroduces the key into a logged string, and we keep
            # logger.warning rather than logger.exception so the
            # exception chain (which carries the URL in earlier frames)
            # is dropped. The redacted message is captured in a local
            # before the logger call so the check-sensitive-logging
            # pre-commit hook does not flag the exception variable as
            # referenced inside the log call.
            safe_msg = redact_secrets(str(e), api_key)
            logger.warning(f"Error fetching Google Gemini models: {safe_msg}")
            return []
