"""
测试Knowledge API不再默认使用MockEmbedder
- 无OpenAI Key时API返回503+明确错误信息
- 有OpenAI Key时使用OpenAIEmbedder
- MockEmbedder不再作为默认选择
"""
import pytest
from unittest.mock import patch, MagicMock

from app.services.knowledge.embedder import MockEmbedder, OpenAIEmbedder
from app.services.knowledge.rag_service import RAGService
from app.services.api_key_manager import APIKeyManager


class TestKnowledgeAPINoMockEmbedder:
    """验证knowledge.py不再默认使用MockEmbedder"""

    def test_get_rag_service_raises_without_openai_key(self):
        """无OpenAI Key时_get_rag_service必须抛出HTTPException"""
        from app.api.knowledge import _get_rag_service
        from fastapi import HTTPException

        key_manager = APIKeyManager()
        with patch("app.api.knowledge._key_manager", key_manager):
            with pytest.raises(HTTPException) as exc_info:
                _get_rag_service()
            assert exc_info.value.status_code == 503
            assert "OpenAI API Key" in exc_info.value.detail

    def test_get_rag_service_returns_openai_embedder_with_key(self):
        """有OpenAI Key时_get_rag_service必须返回使用OpenAIEmbedder的RAGService"""
        from app.api.knowledge import _get_rag_service

        key_manager = APIKeyManager()
        key_manager.add_key("chatgpt", "sk-test-key-1234567890", source="system")

        with patch("app.api.knowledge._key_manager", key_manager):
            rag_service = _get_rag_service()
            assert isinstance(rag_service, RAGService)
            assert isinstance(rag_service.embedder, OpenAIEmbedder)

    def test_get_rag_service_never_returns_mock_embedder(self):
        """_get_rag_service绝不能返回MockEmbedder"""
        from app.api.knowledge import _get_rag_service
        from fastapi import HTTPException

        key_manager = APIKeyManager()
        with patch("app.api.knowledge._key_manager", key_manager):
            with pytest.raises(HTTPException):
                _get_rag_service()

        key_manager_with_key = APIKeyManager()
        key_manager_with_key.add_key("chatgpt", "sk-test-key-1234567890", source="system")
        with patch("app.api.knowledge._key_manager", key_manager_with_key):
            rag_service = _get_rag_service()
            assert not isinstance(rag_service.embedder, MockEmbedder)

    def test_no_module_level_mock_rag_service(self):
        """模块级别不再存在使用MockEmbedder的_rag_service变量"""
        import app.api.knowledge as knowledge_module

        assert not hasattr(knowledge_module, "_rag_service"), (
            "_rag_service模块级变量仍然存在，必须删除"
        )

    def test_error_message_contains_configuration_guidance(self):
        """503错误信息必须包含配置指引"""
        from app.api.knowledge import _get_rag_service
        from fastapi import HTTPException

        key_manager = APIKeyManager()
        with patch("app.api.knowledge._key_manager", key_manager):
            with pytest.raises(HTTPException) as exc_info:
                _get_rag_service()
            detail = exc_info.value.detail
            assert "OpenAI API Key" in detail
            assert "设置" in detail or "配置" in detail

    def test_mock_embedder_class_still_exists(self):
        """MockEmbedder类必须保留（仅用于测试）"""
        assert MockEmbedder is not None
        embedder = MockEmbedder()
        assert isinstance(embedder, MockEmbedder)

    def test_get_rag_service_uses_api_key_manager(self):
        """_get_rag_service必须使用APIKeyManager获取Key"""
        from app.api.knowledge import _get_rag_service

        mock_km = MagicMock(spec=APIKeyManager)
        mock_km.get_key.return_value = "sk-test-key-1234567890"

        with patch("app.api.knowledge._key_manager", mock_km):
            rag_service = _get_rag_service()
            mock_km.get_key.assert_called_once_with("chatgpt")
            assert isinstance(rag_service.embedder, OpenAIEmbedder)
