"""Tests for LLM gateway."""
import pytest
from greymatter_core.gateway import CompletionResult, OllamaGateway


def test_completion_result_dataclass():
    result = CompletionResult(
        content="Hello", model="test", provider="ollama",
        tokens_used=10, latency_ms=100, cost_estimate=0.0,
    )
    assert result.content == "Hello"
    assert result.cost_estimate == 0.0


def test_ollama_gateway_init():
    gw = OllamaGateway(base_url="http://localhost:11434", model="mistral-nemo")
    assert gw.provider == "ollama"
    assert gw.model_name == "mistral-nemo"


def test_completion_result_has_tool_calls():
    result = CompletionResult(
        content="hello",
        model="test",
        provider="test",
        tokens_used=10,
        latency_ms=100,
        cost_estimate=0.0,
        tool_calls=[{"function": {"name": "read_file", "arguments": {"path": "/tmp/x"}}}],
    )
    assert result.tool_calls is not None
    assert len(result.tool_calls) == 1
    assert result.tool_calls[0]["function"]["name"] == "read_file"


def test_completion_result_tool_calls_default_none():
    result = CompletionResult(
        content="hello",
        model="test",
        provider="test",
        tokens_used=10,
        latency_ms=100,
        cost_estimate=0.0,
    )
    assert result.tool_calls is None


@pytest.mark.asyncio
async def test_ollama_gateway_unavailable():
    """Gateway reports unavailable when Ollama is not running."""
    gw = OllamaGateway(base_url="http://localhost:59999", model="test")
    assert await gw.check_available() is False


# --- Task 2: OllamaGateway tool-calling tests ---

from unittest.mock import AsyncMock, patch, MagicMock


@pytest.mark.asyncio
async def test_ollama_complete_with_tools():
    """Test that OllamaGateway passes tools to Ollama and parses tool_calls."""
    gateway = OllamaGateway(base_url="http://fake:11434", model="test-model")

    mock_response = MagicMock()
    mock_response.status_code = 200
    mock_response.raise_for_status = MagicMock()
    mock_response.json.return_value = {
        "message": {
            "role": "assistant",
            "content": "",
            "tool_calls": [
                {
                    "function": {
                        "name": "search_patterns",
                        "arguments": {"domain": "testing"},
                    }
                }
            ],
        },
        "eval_count": 50,
        "prompt_eval_count": 100,
    }

    tools = [
        {
            "type": "function",
            "function": {
                "name": "search_patterns",
                "description": "Search patterns",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "domain": {"type": "string"}
                    },
                },
            },
        }
    ]

    with patch("httpx.AsyncClient") as mock_client_cls:
        mock_client = AsyncMock()
        mock_client.post = AsyncMock(return_value=mock_response)
        mock_client.__aenter__ = AsyncMock(return_value=mock_client)
        mock_client.__aexit__ = AsyncMock(return_value=False)
        mock_client_cls.return_value = mock_client

        result = await gateway.complete(
            [{"role": "user", "content": "search testing patterns"}],
            tools=tools,
        )

    assert result.tool_calls is not None
    assert len(result.tool_calls) == 1
    assert result.tool_calls[0]["function"]["name"] == "search_patterns"
    assert result.content == ""

    # Verify tools were passed in the request
    call_args = mock_client.post.call_args
    request_body = call_args.kwargs["json"]
    assert "tools" in request_body


@pytest.mark.asyncio
async def test_ollama_complete_without_tools():
    """Test that OllamaGateway works without tools (backward compatible)."""
    gateway = OllamaGateway(base_url="http://fake:11434", model="test-model")

    mock_response = MagicMock()
    mock_response.status_code = 200
    mock_response.raise_for_status = MagicMock()
    mock_response.json.return_value = {
        "message": {"role": "assistant", "content": "Hello there!"},
        "eval_count": 20,
        "prompt_eval_count": 50,
    }

    with patch("httpx.AsyncClient") as mock_client_cls:
        mock_client = AsyncMock()
        mock_client.post = AsyncMock(return_value=mock_response)
        mock_client.__aenter__ = AsyncMock(return_value=mock_client)
        mock_client.__aexit__ = AsyncMock(return_value=False)
        mock_client_cls.return_value = mock_client

        result = await gateway.complete(
            [{"role": "user", "content": "hello"}],
        )

    assert result.content == "Hello there!"
    assert result.tool_calls is None

    # Verify no tools key in request
    call_args = mock_client.post.call_args
    request_body = call_args.kwargs["json"]
    assert "tools" not in request_body
