"""Tests for pipeline mode tool call routing (search_extension focus)."""

import json
import asyncio
import pytest
from unittest.mock import MagicMock, AsyncMock, patch
from conftest import MockSession

from qwen_pipeline_server import PipelineSession


class TestPipelineSearchExtensionRouting:
    """Tests for search_extension routing in pipeline mode.

    Pipeline mode processes tool calls inline in _run_llm. Since that method
    is deeply coupled to LLM streaming, we test the search_extension routing
    logic by simulating the conditions and checking the results.
    """

    def _make_session(self, extensions):
        session = MockSession(extensions_directory=extensions)
        session.agents = {
            'a': {
                'name': 'Receptionist',
                'history': [],
                'instructions_raw_map': {'en': 'Test instructions'},
                'instructions_decorations': '',
            }
        }
        session.active_agent = 'a'
        # Mock loop with queue
        session.loop = MagicMock()
        session.queue = asyncio.Queue()
        session.loop.call_soon_threadsafe = MagicMock()
        return session

    def test_search_result_in_history(self, sample_extensions):
        """After search_extension, result should be in agent history."""
        session = self._make_session(sample_extensions)
        agent = session.agents['a']
        tool_call_args = json.dumps({'name': 'Zack'})

        # Simulate pipeline routing logic
        result = PipelineSession._handle_search_extension(session, {'name': 'Zack'})

        # Simulate what pipeline does: append to history
        agent['history'].append({
            'role': 'assistant', 'content': None,
            'tool_calls': [{
                'id': 'call_search_extension',
                'type': 'function',
                'function': {'name': 'search_extension', 'arguments': tool_call_args}
            }]
        })
        agent['history'].append({
            'role': 'tool',
            'tool_call_id': 'call_search_extension',
            'content': result
        })

        assert len(agent['history']) == 2
        assert agent['history'][0]['role'] == 'assistant'
        assert agent['history'][0]['tool_calls'][0]['function']['name'] == 'search_extension'
        assert agent['history'][1]['role'] == 'tool'
        assert 'Zack Jong' in agent['history'][1]['content']

    def test_search_returns_empty_text_response(self, sample_extensions):
        """search_extension should return response with empty text."""
        session = self._make_session(sample_extensions)
        result = PipelineSession._handle_search_extension(session, {'name': 'Zack'})
        # Pipeline routing returns {'type': 'response', 'text': ''}
        assert result is not None
        assert 'Zack Jong' in result

    def test_search_no_results(self, sample_extensions):
        """search_extension with no matches should return error message."""
        session = self._make_session(sample_extensions)
        result = PipelineSession._handle_search_extension(
            session, {'name': 'Nobody'})
        assert 'No person found' in result

    def test_search_department(self, sample_extensions):
        """search_extension by department should return all members."""
        session = self._make_session(sample_extensions)
        result = PipelineSession._handle_search_extension(
            session, {'department': 'Mobile'})
        assert 'Mohamad Shazwan' in result
        assert 'Tan Kar Khim' in result
        assert 'Jacky Su' in result

    def test_multiple_turns_in_history(self, sample_extensions):
        """Simulate search → confirm → dial flow across history."""
        session = self._make_session(sample_extensions)
        agent = session.agents['a']

        # Turn 1: User says "connect me to Zack"
        agent['history'].append({'role': 'user', 'content': 'Connect me to Zack'})

        # LLM calls search_extension
        search_result = PipelineSession._handle_search_extension(
            session, {'name': 'Zack'})
        agent['history'].append({
            'role': 'assistant', 'content': None,
            'tool_calls': [{'id': 'call_1', 'type': 'function',
                           'function': {'name': 'search_extension',
                                       'arguments': '{"name":"Zack"}'}}]
        })
        agent['history'].append({
            'role': 'tool', 'tool_call_id': 'call_1',
            'content': search_result
        })

        # Turn 2: LLM confirms with user
        agent['history'].append({
            'role': 'assistant', 'content': 'Do you mean Zack Jong?'
        })
        agent['history'].append({'role': 'user', 'content': 'Yes'})

        # Turn 3: LLM calls dial_extension
        agent['history'].append({
            'role': 'assistant', 'content': None,
            'tool_calls': [{'id': 'call_2', 'type': 'function',
                           'function': {'name': 'dial_extension',
                                       'arguments': '{"extension":"8703","name":"Zack Jong"}'}}]
        })

        # Verify history has the full flow (6 entries: user, search call, tool result, confirm, yes, dial call)
        assert len(agent['history']) == 6
        assert agent['history'][0]['role'] == 'user'
        assert agent['history'][1]['tool_calls'][0]['function']['name'] == 'search_extension'
        assert 'Zack Jong' in agent['history'][2]['content']
        assert agent['history'][3]['content'] == 'Do you mean Zack Jong?'
        assert agent['history'][5]['tool_calls'][0]['function']['name'] == 'dial_extension'
