"""Tests for unified interface tools.

Generated by GRIMLOCK MCP Factory
"""

import json

import httpx
import pytest
import respx

from videogen_mcp.tools.generate_video import generate_video
from videogen_mcp.tools.get_video_status import get_video_status
from videogen_mcp.tools.download_video import download_video


class TestGenerateVideo:
    """Test cases for generate_video unified tool."""

    @pytest.mark.asyncio
    async def test_generate_video_routes_to_heygen(
        self,
        mock_env,
        mock_httpx_client,
        sample_avatars_response,
        sample_voices_response,
        sample_video_generate_response,
    ):
        """Should route to HeyGen for presenter prompts."""
        mock_httpx_client.get("https://api.heygen.com/v2/avatars").mock(
            return_value=httpx.Response(200, json=sample_avatars_response)
        )
        mock_httpx_client.get("https://api.heygen.com/v2/voices").mock(
            return_value=httpx.Response(200, json=sample_voices_response)
        )
        mock_httpx_client.post("https://api.heygen.com/v2/video/generate").mock(
            return_value=httpx.Response(200, json=sample_video_generate_response)
        )

        result = await generate_video({
            "prompt": "A presenter speaking about our new product features",
        })
        data = json.loads(result[0].text)

        assert data["success"] is True
        assert data["service"] == "heygen"
        assert "routing_reason" in data

    @pytest.mark.asyncio
    async def test_generate_video_routes_to_veo(
        self, mock_env, mock_httpx_client, sample_veo_generate_response
    ):
        """Should route to Veo for cinematic prompts."""
        mock_httpx_client.post(
            "https://generativelanguage.googleapis.com/v1beta/models/veo-3.1-generate-preview:predictLongRunning"
        ).mock(
            return_value=httpx.Response(200, json=sample_veo_generate_response)
        )

        result = await generate_video({
            "prompt": "Cinematic aerial drone footage over mountain peaks",
        })
        data = json.loads(result[0].text)

        assert data["success"] is True
        assert data["service"] == "veo"

    @pytest.mark.asyncio
    async def test_generate_video_with_heygen_hint(
        self,
        mock_env,
        mock_httpx_client,
        sample_avatars_response,
        sample_voices_response,
        sample_video_generate_response,
    ):
        """Should respect heygen service hint."""
        mock_httpx_client.get("https://api.heygen.com/v2/avatars").mock(
            return_value=httpx.Response(200, json=sample_avatars_response)
        )
        mock_httpx_client.get("https://api.heygen.com/v2/voices").mock(
            return_value=httpx.Response(200, json=sample_voices_response)
        )
        mock_httpx_client.post("https://api.heygen.com/v2/video/generate").mock(
            return_value=httpx.Response(200, json=sample_video_generate_response)
        )

        result = await generate_video({
            "prompt": "Create a video about technology",
            "service_hint": "heygen",
        })
        data = json.loads(result[0].text)

        assert data["success"] is True
        assert data["service"] == "heygen"

    @pytest.mark.asyncio
    async def test_generate_video_with_veo_hint(
        self, mock_env, mock_httpx_client, sample_veo_generate_response
    ):
        """Should respect veo service hint."""
        mock_httpx_client.post(
            "https://generativelanguage.googleapis.com/v1beta/models/veo-3.1-generate-preview:predictLongRunning"
        ).mock(
            return_value=httpx.Response(200, json=sample_veo_generate_response)
        )

        result = await generate_video({
            "prompt": "A tutorial about cooking",
            "service_hint": "veo",
        })
        data = json.loads(result[0].text)

        assert data["success"] is True
        assert data["service"] == "veo"

    @pytest.mark.asyncio
    async def test_generate_video_with_aspect_ratio(
        self, mock_env, mock_httpx_client, sample_veo_generate_response
    ):
        """Should pass aspect ratio to service."""
        mock_httpx_client.post(
            "https://generativelanguage.googleapis.com/v1beta/models/veo-3.1-generate-preview:predictLongRunning"
        ).mock(
            return_value=httpx.Response(200, json=sample_veo_generate_response)
        )

        result = await generate_video({
            "prompt": "Abstract art animation",
            "aspect_ratio": "9:16",
        })
        data = json.loads(result[0].text)

        assert data["success"] is True


class TestGetVideoStatus:
    """Test cases for get_video_status tool."""

    @pytest.mark.asyncio
    async def test_get_heygen_status_processing(
        self, mock_env, mock_httpx_client, sample_video_status_pending_response
    ):
        """Should get HeyGen video status (processing)."""
        mock_httpx_client.get(
            "https://api.heygen.com/v1/video_status.get"
        ).mock(
            return_value=httpx.Response(200, json=sample_video_status_pending_response)
        )

        result = await get_video_status({
            "job_id": "heygen-video-abc123def456",
            "service": "heygen",
        })
        data = json.loads(result[0].text)

        assert data["success"] is True
        assert data["status"] == "processing"
        assert data["progress_percent"] == 45

    @pytest.mark.asyncio
    async def test_get_heygen_status_completed(
        self, mock_env, mock_httpx_client, sample_video_status_complete_response
    ):
        """Should get HeyGen video status (completed)."""
        mock_httpx_client.get(
            "https://api.heygen.com/v1/video_status.get"
        ).mock(
            return_value=httpx.Response(200, json=sample_video_status_complete_response)
        )

        result = await get_video_status({
            "job_id": "heygen-video-abc123def456",
            "service": "heygen",
        })
        data = json.loads(result[0].text)

        assert data["success"] is True
        assert data["status"] == "completed"
        assert "video_url" in data

    @pytest.mark.asyncio
    async def test_get_veo_status_processing(
        self, mock_env, mock_httpx_client, sample_veo_status_processing_response
    ):
        """Should get Veo operation status (processing)."""
        mock_httpx_client.get(
            "https://generativelanguage.googleapis.com/v1beta/operations/veo-generate-abc123xyz789"
        ).mock(
            return_value=httpx.Response(200, json=sample_veo_status_processing_response)
        )

        result = await get_video_status({
            "job_id": "operations/veo-generate-abc123xyz789",
            "service": "veo",
        })
        data = json.loads(result[0].text)

        assert data["success"] is True
        assert data["status"] == "processing"
        assert data["progress_percent"] == 50

    @pytest.mark.asyncio
    async def test_get_veo_status_completed(
        self, mock_env, mock_httpx_client, sample_veo_status_complete_response
    ):
        """Should get Veo operation status (completed)."""
        mock_httpx_client.get(
            "https://generativelanguage.googleapis.com/v1beta/operations/veo-generate-abc123xyz789"
        ).mock(
            return_value=httpx.Response(200, json=sample_veo_status_complete_response)
        )

        result = await get_video_status({
            "job_id": "operations/veo-generate-abc123xyz789",
            "service": "veo",
        })
        data = json.loads(result[0].text)

        assert data["success"] is True
        assert data["status"] == "completed"
        assert "video_url" in data

    @pytest.mark.asyncio
    async def test_get_veo_status_failed(
        self, mock_env, mock_httpx_client, sample_veo_status_failed_response
    ):
        """Should get Veo operation status (failed)."""
        mock_httpx_client.get(
            "https://generativelanguage.googleapis.com/v1beta/operations/veo-generate-abc123xyz789"
        ).mock(
            return_value=httpx.Response(200, json=sample_veo_status_failed_response)
        )

        result = await get_video_status({
            "job_id": "operations/veo-generate-abc123xyz789",
            "service": "veo",
        })
        data = json.loads(result[0].text)

        assert data["success"] is True
        assert data["status"] == "failed"
        assert "error_message" in data

    @pytest.mark.asyncio
    async def test_get_video_status_invalid_service(self, mock_env):
        """Should reject invalid service."""
        result = await get_video_status({
            "job_id": "some-id",
            "service": "youtube",
        })
        data = json.loads(result[0].text)

        assert data["error"] is True
        assert data["code"] == "INVALID_SERVICE"

    @pytest.mark.asyncio
    async def test_get_video_status_job_not_found(self, mock_env, mock_httpx_client):
        """Should handle job not found."""
        mock_httpx_client.get(
            "https://api.heygen.com/v1/video_status.get"
        ).mock(
            return_value=httpx.Response(404, json={"error": "Video not found"})
        )

        result = await get_video_status({
            "job_id": "invalid-job-id",
            "service": "heygen",
        })
        data = json.loads(result[0].text)

        assert data["error"] is True
        assert data["code"] == "JOB_NOT_FOUND"


class TestDownloadVideo:
    """Test cases for download_video tool."""

    @pytest.mark.asyncio
    async def test_download_heygen_video(
        self, mock_env, mock_httpx_client, sample_video_status_complete_response
    ):
        """Should get download URL for HeyGen video."""
        mock_httpx_client.get(
            "https://api.heygen.com/v1/video_status.get"
        ).mock(
            return_value=httpx.Response(200, json=sample_video_status_complete_response)
        )

        result = await download_video({
            "job_id": "heygen-video-abc123def456",
            "service": "heygen",
        })
        data = json.loads(result[0].text)

        assert data["success"] is True
        assert data["video_url"] == "https://files.heygen.ai/video/abc123.mp4"
        assert "thumbnail_url" in data

    @pytest.mark.asyncio
    async def test_download_veo_video(
        self, mock_env, mock_httpx_client, sample_veo_status_complete_response
    ):
        """Should get download URL for Veo video."""
        mock_httpx_client.get(
            "https://generativelanguage.googleapis.com/v1beta/operations/veo-generate-abc123xyz789"
        ).mock(
            return_value=httpx.Response(200, json=sample_veo_status_complete_response)
        )

        result = await download_video({
            "job_id": "operations/veo-generate-abc123xyz789",
            "service": "veo",
        })
        data = json.loads(result[0].text)

        assert data["success"] is True
        assert "video_url" in data

    @pytest.mark.asyncio
    async def test_download_video_not_ready(
        self, mock_env, mock_httpx_client, sample_video_status_pending_response
    ):
        """Should handle video not ready."""
        mock_httpx_client.get(
            "https://api.heygen.com/v1/video_status.get"
        ).mock(
            return_value=httpx.Response(200, json=sample_video_status_pending_response)
        )

        result = await download_video({
            "job_id": "heygen-video-abc123def456",
            "service": "heygen",
        })
        data = json.loads(result[0].text)

        assert data["error"] is True
        assert data["code"] == "VIDEO_NOT_READY"
        assert "current_status" in data

    @pytest.mark.asyncio
    async def test_download_video_failed(
        self, mock_env, mock_httpx_client, sample_veo_status_failed_response
    ):
        """Should handle failed video generation."""
        mock_httpx_client.get(
            "https://generativelanguage.googleapis.com/v1beta/operations/veo-generate-abc123xyz789"
        ).mock(
            return_value=httpx.Response(200, json=sample_veo_status_failed_response)
        )

        result = await download_video({
            "job_id": "operations/veo-generate-abc123xyz789",
            "service": "veo",
        })
        data = json.loads(result[0].text)

        assert data["error"] is True
        assert data["code"] == "VIDEO_GENERATION_FAILED"

    @pytest.mark.asyncio
    async def test_download_video_invalid_service(self, mock_env):
        """Should reject invalid service."""
        result = await download_video({
            "job_id": "some-id",
            "service": "invalid",
        })
        data = json.loads(result[0].text)

        assert data["error"] is True
        assert data["code"] == "INVALID_SERVICE"
