"""Unit tests for search_tools function.

This module contains tests for the search_tools convenience function.
"""

from unittest.mock import AsyncMock, MagicMock, patch

import pytest

from hezor_common.data_model.searching.data.api_models import (
    ParameterPropertySchema,
    ParameterSchema,
    SearchResponse,
    ToolSchema,
)
from hezor_common.transfer.datahub_sdk.base.meta_info import MetaInfo
from hezor_common.transfer.datahub_sdk.search_tools import search_tools


@pytest.fixture
def mock_meta_info():
    """Create a mock MetaInfo object."""
    return MetaInfo(
        subject="测试主体",
        subject_code="test_001",
        caller_id="user_123",
        data_coverage="202401-202412",
        creation_slug="test_model",
        creation_name="测试模型",
    )


@pytest.fixture
def sample_tool_schema():
    """Create a sample ToolSchema for testing."""
    param_schema = ParameterSchema(
        type="object",
        desc="Tool parameters",
        props={
            "city": ParameterPropertySchema(type="string", desc="City name"),
            "date": ParameterPropertySchema(type="string", desc="Date"),
            "temperature": ParameterPropertySchema(type="number", desc="Temperature"),
        },
        required=["city"],
    )

    return ToolSchema(
        name="get_weather",
        desc="Get weather information",
        params=param_schema,
        returns="Weather data",
    )


@pytest.fixture
def sample_search_response(sample_tool_schema):
    """Create a sample SearchResponse."""
    return SearchResponse(tools=[sample_tool_schema])


class TestSearchTools:
    """Tests for search_tools function."""

    @pytest.mark.asyncio
    async def test_search_tools_basic(self, sample_search_response):
        """Test basic tool search."""
        with patch(
            "hezor_common.transfer.datahub_sdk.search_tools.DataAPIClient"
        ) as mock_client_class:
            mock_client = MagicMock()
            mock_client.__aenter__ = AsyncMock(return_value=mock_client)
            mock_client.__aexit__ = AsyncMock(return_value=None)
            mock_client.search_tools = AsyncMock(return_value=sample_search_response)
            mock_client_class.return_value = mock_client

            result = await search_tools("test query", top_k=5)

            assert isinstance(result, SearchResponse)
            assert len(result.tools) == 1
            assert result.tools[0].name == "get_weather"

            mock_client.search_tools.assert_called_once_with("test query", 5)

    @pytest.mark.asyncio
    async def test_search_tools_with_auth(self, sample_search_response, mock_meta_info):
        """Test search_tools with authentication."""
        with patch(
            "hezor_common.transfer.datahub_sdk.search_tools.DataAPIClient"
        ) as mock_client_class:
            mock_client = MagicMock()
            mock_client.__aenter__ = AsyncMock(return_value=mock_client)
            mock_client.__aexit__ = AsyncMock(return_value=None)
            mock_client.search_tools = AsyncMock(return_value=sample_search_response)
            mock_client_class.return_value = mock_client

            result = await search_tools(
                "test query",
                top_k=3,
                api_key="test_api_key",
                meta_info=mock_meta_info,
                private_key_path="/path/to/key",
                password=b"test_password",
                meta_info_expires_in=7200,
            )

            assert isinstance(result, SearchResponse)

            # Verify DataAPIClient was called with correct parameters
            mock_client_class.assert_called_once()
            call_kwargs = mock_client_class.call_args[1]
            assert call_kwargs["api_key"] == "test_api_key"
            assert call_kwargs["meta_info"] == mock_meta_info
            assert call_kwargs["private_key_path"] == "/path/to/key"
            assert call_kwargs["password"] == b"test_password"
            assert call_kwargs["meta_info_expires_in"] == 7200

    @pytest.mark.asyncio
    async def test_search_tools_default_top_k(self, sample_search_response):
        """Test search_tools with default top_k."""
        with patch(
            "hezor_common.transfer.datahub_sdk.search_tools.DataAPIClient"
        ) as mock_client_class:
            mock_client = MagicMock()
            mock_client.__aenter__ = AsyncMock(return_value=mock_client)
            mock_client.__aexit__ = AsyncMock(return_value=None)
            mock_client.search_tools = AsyncMock(return_value=sample_search_response)
            mock_client_class.return_value = mock_client

            result = await search_tools("test query")

            assert isinstance(result, SearchResponse)
            mock_client.search_tools.assert_called_once_with("test query", 3)
