"""Unit tests for tool calling types."""

from __future__ import annotations

import pytest

from llm_rotator._types import LLMResponse, StreamChunk, ToolCall, Usage


class TestToolCallDataclass:
    def test_creation(self):
        tc = ToolCall(id="call_1", name="get_weather", arguments='{"city": "London"}')
        assert tc.id == "call_1"
        assert tc.name == "get_weather"
        assert tc.arguments == '{"city": "London"}'

    def test_frozen(self):
        tc = ToolCall(id="call_1", name="fn", arguments="{}")
        with pytest.raises(AttributeError):
            tc.name = "other"  # type: ignore[misc]


class TestLLMResponseWithToolCalls:
    def test_text_only_backward_compat(self):
        resp = LLMResponse(
            content="Hello",
            usage=Usage(prompt_tokens=5, completion_tokens=3, total_tokens=8),
            model="gpt-4o",
            provider="openai",
            key_alias="key",
        )
        assert resp.content == "Hello"
        assert resp.tool_calls is None

    def test_with_tool_calls(self):
        calls = [
            ToolCall(id="call_1", name="get_weather", arguments='{"city": "SF"}'),
        ]
        resp = LLMResponse(
            content=None,
            usage=Usage(prompt_tokens=10, completion_tokens=20, total_tokens=30),
            model="gpt-4o",
            provider="openai",
            key_alias="key",
            tool_calls=calls,
        )
        assert resp.content is None
        assert resp.tool_calls is not None
        assert len(resp.tool_calls) == 1
        assert resp.tool_calls[0].name == "get_weather"

    def test_with_content_and_tool_calls(self):
        """Some providers return both text and tool_calls."""
        calls = [ToolCall(id="call_1", name="fn", arguments="{}")]
        resp = LLMResponse(
            content="Thinking...",
            usage=Usage(prompt_tokens=5, completion_tokens=5, total_tokens=10),
            model="model",
            provider="p",
            key_alias="k",
            tool_calls=calls,
        )
        assert resp.content == "Thinking..."
        assert resp.tool_calls is not None


class TestStreamChunkWithToolCalls:
    def test_stream_chunk_no_tool_calls(self):
        chunk = StreamChunk(delta="hello")
        assert chunk.tool_calls is None

    def test_stream_chunk_done_with_tool_calls(self):
        calls = [ToolCall(id="call_1", name="fn", arguments="{}")]
        chunk = StreamChunk(delta="", done=True, tool_calls=calls)
        assert chunk.tool_calls is not None
        assert len(chunk.tool_calls) == 1
