"""
Tests for Job Orchestrator Tool
"""

import pytest
import os
import sys

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

from services.router.tool_manager import ToolManager, ToolResult


class TestJobOrchestratorTool:
    """Test job orchestrator tool functionality"""

    @pytest.mark.asyncio
    async def test_list_tasks_returns_allowed_tasks(self):
        """Test that list_tasks returns only allowed tasks"""
        tool_mgr = ToolManager({})
        
        result = await tool_mgr._job_orchestrator_tool({
            "action": "list_tasks",
            "params": {},
            "agent_id": "sofiia"
        })
        
        assert result.success is True
        assert "tasks" in result.result
        assert result.result["count"] >= 0

    @pytest.mark.asyncio
    async def test_list_tasks_filter_by_tag(self):
        """Test filtering tasks by tag"""
        tool_mgr = ToolManager({})
        
        result = await tool_mgr._job_orchestrator_tool({
            "action": "list_tasks",
            "params": {
                "filter": {"tag": "smoke"}
            },
            "agent_id": "sofiia"
        })
        
        assert result.success is True
        for task in result.result["tasks"]:
            assert "smoke" in task.get("tags", [])

    @pytest.mark.asyncio
    async def test_list_tasks_filter_by_service(self):
        """Test filtering tasks by service"""
        tool_mgr = ToolManager({})
        
        result = await tool_mgr._job_orchestrator_tool({
            "action": "list_tasks",
            "params": {
                "filter": {"service": "gateway"}
            },
            "agent_id": "sofiia"
        })
        
        assert result.success is True
        for task in result.result["tasks"]:
            service = task.get("id", "")
            assert "gateway" in service or "smoke" in service

    @pytest.mark.asyncio
    async def test_start_task_requires_task_id(self):
        """Test that start_task requires task_id"""
        tool_mgr = ToolManager({})
        
        result = await tool_mgr._job_orchestrator_tool({
            "action": "start_task",
            "params": {},
            "agent_id": "sofiia"
        })
        
        assert result.success is False
        assert "task_id" in result.error.lower()

    @pytest.mark.asyncio
    async def test_start_task_unknown_task(self):
        """Test starting unknown task returns error"""
        tool_mgr = ToolManager({})
        
        result = await tool_mgr._job_orchestrator_tool({
            "action": "start_task",
            "params": {
                "task_id": "nonexistent_task"
            },
            "agent_id": "sofiia"
        })
        
        assert result.success is False
        assert "not found" in result.error.lower()

    @pytest.mark.asyncio
    async def test_start_task_dry_run(self):
        """Test dry run returns execution plan without running"""
        tool_mgr = ToolManager({})
        
        result = await tool_mgr._job_orchestrator_tool({
            "action": "start_task",
            "params": {
                "task_id": "smoke_gateway",
                "dry_run": True
            },
            "agent_id": "sofiia"
        })
        
        assert result.success is True
        assert "execution_plan" in result.result
        assert result.result["job"]["status"] == "dry_run"
        assert result.result["message"] == "Dry run - no execution performed"

    @pytest.mark.asyncio
    async def test_start_task_with_inputs_validation(self):
        """Test input schema validation"""
        tool_mgr = ToolManager({})
        
        result = await tool_mgr._job_orchestrator_tool({
            "action": "start_task",
            "params": {
                "task_id": "drift_check_node1",
                "inputs": {
                    "mode": "quick"
                }
            },
            "agent_id": "sofiia"
        })
        
        assert result.success is True

    @pytest.mark.asyncio
    async def test_start_task_invalid_input(self):
        """Test that invalid inputs are rejected"""
        tool_mgr = ToolManager({})
        
        result = await tool_mgr._job_orchestrator_tool({
            "action": "start_task",
            "params": {
                "task_id": "drift_check_node1",
                "inputs": {
                    "mode": "invalid_mode"
                }
            },
            "agent_id": "sofiia"
        })
        
        assert result.success is False
        assert "validation" in result.error.lower() or "invalid" in result.error.lower()

    @pytest.mark.asyncio
    async def test_start_task_missing_required_input(self):
        """Test that missing required inputs are rejected"""
        tool_mgr = ToolManager({})
        
        result = await tool_mgr._job_orchestrator_tool({
            "action": "start_task",
            "params": {
                "task_id": "drift_check_node1",
                "inputs": {}
            },
            "agent_id": "sofiia"
        })
        
        assert result.success is False
        assert "missing" in result.error.lower() or "required" in result.error.lower()

    @pytest.mark.asyncio
    async def test_get_job_requires_job_id(self):
        """Test that get_job requires job_id"""
        tool_mgr = ToolManager({})
        
        result = await tool_mgr._job_orchestrator_tool({
            "action": "get_job",
            "params": {},
            "agent_id": "sofiia"
        })
        
        assert result.success is False
        assert "job_id" in result.error.lower()

    @pytest.mark.asyncio
    async def test_cancel_job_requires_job_id(self):
        """Test that cancel_job requires job_id"""
        tool_mgr = ToolManager({})
        
        result = await tool_mgr._job_orchestrator_tool({
            "action": "cancel_job",
            "params": {},
            "agent_id": "sofiia"
        })
        
        assert result.success is False
        assert "job_id" in result.error.lower()

    @pytest.mark.asyncio
    async def test_cancel_job_allowed_for_admin(self):
        """Test that admin can cancel jobs"""
        tool_mgr = ToolManager({})
        
        result = await tool_mgr._job_orchestrator_tool({
            "action": "cancel_job",
            "params": {
                "job_id": "job-abc123",
                "reason": "Testing cancellation"
            },
            "agent_id": "sofiia"
        })
        
        assert result.success is True
        assert result.result["status"] == "canceled"
        assert result.result["canceled_by"] == "sofiia"

    @pytest.mark.asyncio
    async def test_cancel_job_denied_for_non_admin(self):
        """Test that non-admin cannot cancel jobs"""
        tool_mgr = ToolManager({})
        
        result = await tool_mgr._job_orchestrator_tool({
            "action": "cancel_job",
            "params": {
                "job_id": "job-abc123",
                "reason": "Testing"
            },
            "agent_id": "guest"
        })
        
        assert result.success is False
        assert "only" in result.error.lower() or "admin" in result.error.lower()

    @pytest.mark.asyncio
    async def test_unknown_action_returns_error(self):
        """Test that unknown action returns error"""
        tool_mgr = ToolManager({})
        
        result = await tool_mgr._job_orchestrator_tool({
            "action": "unknown_action",
            "params": {},
            "agent_id": "sofiia"
        })
        
        assert result.success is False
        assert "unknown action" in result.error.lower()

    @pytest.mark.asyncio
    async def test_task_has_required_fields(self):
        """Test that tasks have required fields"""
        tool_mgr = ToolManager({})
        
        result = await tool_mgr._job_orchestrator_tool({
            "action": "list_tasks",
            "params": {},
            "agent_id": "sofiia"
        })
        
        assert result.success is True
        for task in result.result["tasks"]:
            assert "id" in task
            assert "title" in task
            assert "tags" in task

    @pytest.mark.asyncio
    async def test_start_task_returns_job_record(self):
        """Test that start_task returns job record"""
        tool_mgr = ToolManager({})
        
        result = await tool_mgr._job_orchestrator_tool({
            "action": "start_task",
            "params": {
                "task_id": "smoke_gateway",
                "dry_run": True
            },
            "agent_id": "sofiia"
        })
        
        assert result.success is True
        assert "job" in result.result
        job = result.result["job"]
        assert "id" in job
        assert "task_id" in job
        assert "status" in job
        assert "created_at" in job

    @pytest.mark.asyncio
    async def test_idempotency_key_supported(self):
        """Test that idempotency_key is supported"""
        tool_mgr = ToolManager({})
        
        result = await tool_mgr._job_orchestrator_tool({
            "action": "start_task",
            "params": {
                "task_id": "smoke_gateway",
                "idempotency_key": "unique-key-123"
            },
            "agent_id": "sofiia"
        })
        
        assert result.success is True
        assert result.result["job"]["idempotency_key"] == "unique-key-123"
