"""Tests for tool building and schedule availability."""

import pytest
from unittest.mock import patch
from datetime import datetime, timezone, timedelta
from conftest import MockSession

from qwen_pipeline_server import PipelineSession, _is_tool_available


class TestBuildSearchExtensionTool:
    """Tests for PipelineSession._build_search_extension_tool()."""

    def test_with_extensions(self, sample_extensions):
        session = MockSession(extensions_directory=sample_extensions)
        tool = PipelineSession._build_search_extension_tool(session)
        assert tool is not None
        assert tool['function']['name'] == 'search_extension'
        params = tool['function']['parameters']['properties']
        assert 'name' in params
        assert 'department' in params

    def test_empty_extensions(self):
        session = MockSession(extensions_directory=[])
        tool = PipelineSession._build_search_extension_tool(session)
        assert tool is None

    def test_tool_type(self, sample_extensions):
        session = MockSession(extensions_directory=sample_extensions)
        tool = PipelineSession._build_search_extension_tool(session)
        assert tool['type'] == 'function'

    def test_description_mentions_dial(self, sample_extensions):
        session = MockSession(extensions_directory=sample_extensions)
        tool = PipelineSession._build_search_extension_tool(session)
        assert 'dial_extension' in tool['function']['description']


class TestIsToolAvailable:
    """Tests for _is_tool_available() schedule checking."""

    def test_no_schedule(self):
        tool = {'type': 'function', 'function': {'name': 'test'}}
        assert _is_tool_available(tool) is True

    def test_within_schedule(self):
        tool = {
            'type': 'function',
            'function': {'name': 'test'},
            'x_schedule': {
                'days': ['mon', 'tue', 'wed', 'thu', 'fri'],
                'start': '09:00',
                'end': '18:00',
                'timezone': 'Asia/Kuala_Lumpur'
            }
        }
        # Monday 10:00 MYT (UTC+8) = Monday 02:00 UTC
        mock_now = datetime(2024, 1, 15, 10, 0, 0,
                           tzinfo=timezone(timedelta(hours=8)))
        with patch('qwen_pipeline_server.datetime') as mock_dt:
            mock_dt.now.return_value = mock_now
            mock_dt.side_effect = lambda *a, **kw: datetime(*a, **kw)
            assert _is_tool_available(tool) is True

    def test_outside_hours(self):
        tool = {
            'type': 'function',
            'function': {'name': 'test'},
            'x_schedule': {
                'days': ['mon', 'tue', 'wed', 'thu', 'fri'],
                'start': '09:00',
                'end': '18:00',
                'timezone': 'Asia/Kuala_Lumpur'
            }
        }
        # Monday 20:00 MYT
        mock_now = datetime(2024, 1, 15, 20, 0, 0,
                           tzinfo=timezone(timedelta(hours=8)))
        with patch('qwen_pipeline_server.datetime') as mock_dt:
            mock_dt.now.return_value = mock_now
            mock_dt.side_effect = lambda *a, **kw: datetime(*a, **kw)
            assert _is_tool_available(tool) is False

    def test_wrong_day(self):
        tool = {
            'type': 'function',
            'function': {'name': 'test'},
            'x_schedule': {
                'days': ['mon', 'tue', 'wed', 'thu', 'fri'],
                'start': '09:00',
                'end': '18:00',
                'timezone': 'Asia/Kuala_Lumpur'
            }
        }
        # Saturday 10:00 MYT
        mock_now = datetime(2024, 1, 13, 10, 0, 0,
                           tzinfo=timezone(timedelta(hours=8)))
        with patch('qwen_pipeline_server.datetime') as mock_dt:
            mock_dt.now.return_value = mock_now
            mock_dt.side_effect = lambda *a, **kw: datetime(*a, **kw)
            assert _is_tool_available(tool) is False

    def test_empty_schedule(self):
        tool = {
            'type': 'function',
            'function': {'name': 'test'},
            'x_schedule': {}
        }
        assert _is_tool_available(tool) is True
