"""Tests for the credential_check convenience transform.

Verifies that creating a resource against a known SaaS endpoint without
credentials raises a clear error, and that passing api_key or credentials
bypasses the check.
"""

import pytest

from goodmem._transforms import apply_convenience_transforms


def _apply(ns, kwargs):
    apply_convenience_transforms((ns, "create"), kwargs)
    return kwargs


# ---------------------------------------------------------------------------
# SaaS endpoints require credentials
# ---------------------------------------------------------------------------

class TestSaasEndpointRequiresCredentials:
    def test_openai_embedder_without_credentials_raises(self):
        with pytest.raises(ValueError, match="requires an API key"):
            _apply("embedders", {
                "model_identifier": "text-embedding-3-small",
                "display_name": "Test",
            })

    def test_openai_llm_without_credentials_raises(self):
        with pytest.raises(ValueError, match="requires an API key"):
            _apply("llms", {
                "model_identifier": "gpt-4o",
                "display_name": "Test",
            })

    def test_cohere_reranker_without_credentials_raises(self):
        with pytest.raises(ValueError, match="requires an API key"):
            _apply("rerankers", {
                "model_identifier": "rerank-v3.5",
                "display_name": "Test",
            })

    def test_voyage_embedder_without_credentials_raises(self):
        with pytest.raises(ValueError, match="requires an API key"):
            _apply("embedders", {
                "model_identifier": "voyage-3",
                "display_name": "Test",
            })

    def test_jina_reranker_without_credentials_raises(self):
        with pytest.raises(ValueError, match="requires an API key"):
            _apply("rerankers", {
                "model_identifier": "jina-reranker-v2-base-multilingual",
                "display_name": "Test",
            })


# ---------------------------------------------------------------------------
# Providing api_key or credentials bypasses the check
# ---------------------------------------------------------------------------

class TestCredentialsProvided:
    def test_openai_embedder_with_api_key_passes(self):
        result = _apply("embedders", {
            "model_identifier": "text-embedding-3-small",
            "display_name": "Test",
            "api_key": "sk-test",
        })
        assert "credentials" in result

    def test_openai_llm_with_api_key_passes(self):
        result = _apply("llms", {
            "model_identifier": "gpt-4o",
            "display_name": "Test",
            "api_key": "sk-test",
        })
        assert "credentials" in result

    def test_cohere_reranker_with_credentials_passes(self):
        creds = {"kind": "CREDENTIAL_KIND_API_KEY", "api_key": {"inline_secret": "key"}}
        result = _apply("rerankers", {
            "model_identifier": "rerank-v3.5",
            "display_name": "Test",
            "credentials": creds,
        })
        assert result["credentials"] == creds


# ---------------------------------------------------------------------------
# Non-SaaS endpoints don't require credentials
# ---------------------------------------------------------------------------

class TestNonSaasEndpoints:
    def test_custom_openai_endpoint_passes_without_credentials(self):
        """Custom localhost endpoint for OPENAI provider should not require credentials."""
        result = _apply("llms", {
            "provider_type": "OPENAI",
            "endpoint_url": "http://localhost:8000/v1",
            "display_name": "Local vLLM",
            "model_identifier": "my-model",
        })
        assert "credentials" not in result

    def test_vllm_provider_passes_without_credentials(self):
        """VLLM is not in providers.json — no credential check applies."""
        result = _apply("llms", {
            "provider_type": "VLLM",
            "endpoint_url": "http://my-server:8000/v1",
            "display_name": "vLLM",
            "model_identifier": "llama-3",
        })
        assert "credentials" not in result

    def test_unknown_provider_passes_without_credentials(self):
        """Provider not in registry — no check applied."""
        result = _apply("embedders", {
            "provider_type": "TEI",
            "endpoint_url": "http://localhost:8080",
            "display_name": "TEI",
            "model_identifier": "bge-m3",
        })
        assert "credentials" not in result


# ---------------------------------------------------------------------------
# No endpoint_url → no check
# ---------------------------------------------------------------------------

class TestNoEndpointUrl:
    def test_no_endpoint_url_no_check(self):
        """When endpoint_url is not resolved, credential check is skipped."""
        result = _apply("embedders", {
            "model_identifier": "unknown-model",
            "display_name": "Test",
        })
        # Unknown model → no endpoint_url → no error
        assert "credentials" not in result


# ---------------------------------------------------------------------------
# OpenAI-compatible SaaS endpoints (Google, Anthropic, Mistral via OPENAI provider)
# ---------------------------------------------------------------------------

class TestOpenAICompatibleSaasEndpoints:
    def test_google_openai_compatible_requires_credentials(self):
        with pytest.raises(ValueError, match="requires an API key"):
            _apply("llms", {
                "provider_type": "OPENAI",
                "endpoint_url": "https://generativelanguage.googleapis.com/v1beta/openai",
                "display_name": "Gemini",
                "model_identifier": "gemini-2.0-flash",
            })

    def test_anthropic_openai_compatible_requires_credentials(self):
        with pytest.raises(ValueError, match="requires an API key"):
            _apply("llms", {
                "provider_type": "OPENAI",
                "endpoint_url": "https://api.anthropic.com/v1",
                "display_name": "Claude",
                "model_identifier": "claude-3-5-sonnet",
            })

    def test_mistral_openai_compatible_requires_credentials(self):
        with pytest.raises(ValueError, match="requires an API key"):
            _apply("llms", {
                "provider_type": "OPENAI",
                "endpoint_url": "https://api.mistral.ai/v1",
                "display_name": "Mistral",
                "model_identifier": "mistral-large",
            })
