import pytest
from unittest.mock import patch, MagicMock
import ai_client

def test_deepseek_model_selection():
    """
    Verifies that ai_client.set_provider('deepseek', 'deepseek-chat') correctly updates the internal state.
    """
    ai_client.set_provider("deepseek", "deepseek-chat")
    assert ai_client._provider == "deepseek"
    assert ai_client._model == "deepseek-chat"

def test_deepseek_completion_logic():
    """
    Verifies that ai_client.send() correctly calls the DeepSeek API and returns content.
    """
    ai_client.set_provider("deepseek", "deepseek-chat")
    
    with patch("requests.post") as mock_post:
        mock_response = MagicMock()
        mock_response.status_code = 200
        mock_response.json.return_value = {
            "choices": [{
                "message": {"role": "assistant", "content": "DeepSeek Response"},
                "finish_reason": "stop"
            }],
            "usage": {"prompt_tokens": 10, "completion_tokens": 5}
        }
        mock_post.return_value = mock_response
        
        result = ai_client.send(md_content="Context", user_message="Hello", base_dir=".")
        assert result == "DeepSeek Response"
        assert mock_post.called

def test_deepseek_reasoning_logic():
    """
    Verifies that reasoning_content is captured and wrapped in <thinking> tags.
    """
    ai_client.set_provider("deepseek", "deepseek-reasoner")
    
    with patch("requests.post") as mock_post:
        mock_response = MagicMock()
        mock_response.status_code = 200
        mock_response.json.return_value = {
            "choices": [{
                "message": {
                    "role": "assistant", 
                    "content": "Final Answer", 
                    "reasoning_content": "Chain of thought"
                },
                "finish_reason": "stop"
            }],
            "usage": {"prompt_tokens": 10, "completion_tokens": 20}
        }
        mock_post.return_value = mock_response
        
        result = ai_client.send(md_content="Context", user_message="Reasoning test", base_dir=".")
        assert "<thinking>\nChain of thought\n</thinking>" in result
        assert "Final Answer" in result

def test_deepseek_tool_calling():
    """
    Verifies that DeepSeek provider correctly identifies and executes tool calls.
    """
    ai_client.set_provider("deepseek", "deepseek-chat")
    
    with patch("requests.post") as mock_post, \
         patch("mcp_client.dispatch") as mock_dispatch:
        
        # 1. Mock first response with a tool call
        mock_resp1 = MagicMock()
        mock_resp1.status_code = 200
        mock_resp1.json.return_value = {
            "choices": [{
                "message": {
                    "role": "assistant", 
                    "content": "Let me read that file.",
                    "tool_calls": [{
                        "id": "call_123",
                        "type": "function",
                        "function": {
                            "name": "read_file",
                            "arguments": '{"path": "test.txt"}'
                        }
                    }]
                },
                "finish_reason": "tool_calls"
            }],
            "usage": {"prompt_tokens": 50, "completion_tokens": 10}
        }
        
        # 2. Mock second response (final answer)
        mock_resp2 = MagicMock()
        mock_resp2.status_code = 200
        mock_resp2.json.return_value = {
            "choices": [{
                "message": {
                    "role": "assistant", 
                    "content": "File content is: Hello World"
                },
                "finish_reason": "stop"
            }],
            "usage": {"prompt_tokens": 100, "completion_tokens": 20}
        }
        
        mock_post.side_effect = [mock_resp1, mock_resp2]
        mock_dispatch.return_value = "Hello World"
        
        result = ai_client.send(md_content="Context", user_message="Read test.txt", base_dir=".")
        
        assert "File content is: Hello World" in result
        assert mock_dispatch.called
        assert mock_dispatch.call_args[0][0] == "read_file"
        assert mock_dispatch.call_args[0][1] == {"path": "test.txt"}

def test_deepseek_streaming():
    """
    Verifies that DeepSeek provider correctly aggregates streaming chunks.
    """
    ai_client.set_provider("deepseek", "deepseek-chat")
    
    with patch("requests.post") as mock_post:
        # Mock a streaming response
        mock_response = MagicMock()
        mock_response.status_code = 200
        
        # Simulate OpenAI-style server-sent events (SSE) for streaming
        # Each line starts with 'data: ' and contains a JSON object
        chunks = [
            'data: {"choices": [{"delta": {"role": "assistant", "content": "Hello"}, "index": 0, "finish_reason": null}]}',
            'data: {"choices": [{"delta": {"content": " World"}, "index": 0, "finish_reason": null}]}',
            'data: {"choices": [{"delta": {}, "index": 0, "finish_reason": "stop"}]}',
            'data: [DONE]'
        ]
        mock_response.iter_lines.return_value = [c.encode('utf-8') for c in chunks]
        mock_post.return_value = mock_response
        
        result = ai_client.send(md_content="Context", user_message="Stream test", base_dir=".", stream=True)
        assert result == "Hello World"
