"""
Tests for Observability Tool
"""

import pytest
import os
import sys
from unittest.mock import AsyncMock, patch

sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))

from services.router.tool_manager import ToolManager, ToolResult


class TestObservabilityToolMetrics:
    """Test metrics query functionality"""
    
    @pytest.mark.asyncio
    async def test_metrics_query_valid_promql(self):
        """Test that valid PromQL queries work"""
        tool_mgr = ToolManager({})
        
        with patch.object(tool_mgr.http_client, 'get') as mock_get:
            mock_response = AsyncMock()
            mock_response.status_code = 200
            mock_response.json.return_value = {
                "status": "success",
                "data": {
                    "result": [
                        {"metric": {"service": "gateway"}, "value": [1234567890, "0.5"]}
                    ]
                }
            }
            mock_get.return_value = mock_response
            
            result = await tool_mgr._observability_tool({
                "action": "metrics_query",
                "params": {
                    "query": "rate(http_requests_total[5m])",
                    "datasource": "prometheus"
                }
            })
        
        assert result.success is True
    
    @pytest.mark.asyncio
    async def test_metrics_query_invalid_promql_blocked(self):
        """Test that invalid PromQL is blocked"""
        tool_mgr = ToolManager({})
        
        result = await tool_mgr._observability_tool({
            "action": "metrics_query",
            "params": {
                "query": "group(*) by (service)",  # Not in allowlist
                "datasource": "prometheus"
            }
        })
        
        assert result.success is False
        assert "allowed" in result.error.lower()


class TestObservabilityToolLogs:
    """Test log query functionality"""
    
    @pytest.mark.asyncio
    async def test_logs_query_time_limit(self):
        """Test that time window limit is enforced"""
        tool_mgr = ToolManager({})
        
        # Try to query with 48h window (exceeds 24h limit)
        result = await tool_mgr._observability_tool({
            "action": "logs_query",
            "params": {
                "query": "{service=\"gateway\"}",
                "time_range": {
                    "from": "2024-01-01T00:00:00Z",
                    "to": "2024-01-03T00:00:00Z"
                }
            }
        })
        
        assert result.success is False
        assert "limit" in result.error.lower()


class TestObservabilityToolTraces:
    """Test trace functionality"""
    
    @pytest.mark.asyncio
    async def test_traces_query_by_id(self):
        """Test getting trace by ID"""
        tool_mgr = ToolManager({})
        
        with patch.object(tool_mgr.http_client, 'get') as mock_get:
            mock_response = AsyncMock()
            mock_response.status_code = 200
            mock_response.json.return_value = {"batches": []}
            mock_get.return_value = mock_response
            
            result = await tool_mgr._observability_tool({
                "action": "traces_query",
                "params": {
                    "trace_id": "abc123"
                }
            })
        
        assert result.success is True


class TestObservabilityToolServiceOverview:
    """Test service overview"""
    
    @pytest.mark.asyncio
    async def test_service_overview_default_time(self):
        """Test service overview with default time range"""
        tool_mgr = ToolManager({})
        
        with patch.object(tool_mgr.http_client, 'get') as mock_get:
            mock_response = AsyncMock()
            mock_response.status_code = 200
            mock_response.json.return_value = {
                "status": "success",
                "data": {
                    "result": [
                        {"value": [1234567890, "0.1"]}
                    ]
                }
            }
            mock_get.return_value = mock_response
            
            result = await tool_mgr._observability_tool({
                "action": "service_overview",
                "params": {
                    "service": "gateway"
                }
            })
        
        assert result.success is True
        assert "metrics" in result.result


class TestObservabilityToolSecurity:
    """Test security features"""
    
    @pytest.mark.asyncio
    async def test_query_timeout(self):
        """Test that queries have timeout"""
        tool_mgr = ToolManager({})
        
        # The tool should have timeout protection
        result = await tool_mgr._observability_tool({
            "action": "metrics_query",
            "params": {
                "query": "rate(http_requests_total[5m])"
            }
        })
        
        # Should either succeed or fail gracefully
        assert result is not None


if __name__ == "__main__":
    pytest.main([__file__, "-v"])
