#!/usr/bin/env python3
"""Tests for image editing tools (remove_background, upscale, edit, inpaint, resize)."""

import sys

import pytest

sys.path.insert(0, "../src")


@pytest.mark.asyncio
async def test_image_editing_tools_registered():
    """Test that all image editing tools are registered."""
    from fal_mcp_server.server import list_tools

    tools = await list_tools()
    tool_names = [t.name for t in tools]

    # All 5 image editing tools should be registered
    assert "remove_background" in tool_names
    assert "upscale_image" in tool_names
    assert "edit_image" in tool_names
    assert "inpaint_image" in tool_names
    assert "resize_image" in tool_names


@pytest.mark.asyncio
async def test_remove_background_tool_schema():
    """Test that remove_background tool has correct schema."""
    from fal_mcp_server.server import list_tools

    tools = await list_tools()
    tool = next(t for t in tools if t.name == "remove_background")

    assert tool is not None
    props = tool.inputSchema["properties"]

    # Check required parameters
    assert "image_url" in props
    assert props["image_url"]["type"] == "string"

    # Check optional parameters
    assert "model" in props
    assert props["model"]["default"] == "fal-ai/birefnet/v2"

    assert "output_format" in props
    assert props["output_format"]["default"] == "png"
    assert "png" in props["output_format"]["enum"]
    assert "webp" in props["output_format"]["enum"]

    # Only image_url is required
    assert tool.inputSchema["required"] == ["image_url"]


@pytest.mark.asyncio
async def test_upscale_image_tool_schema():
    """Test that upscale_image tool has correct schema."""
    from fal_mcp_server.server import list_tools

    tools = await list_tools()
    tool = next(t for t in tools if t.name == "upscale_image")

    assert tool is not None
    props = tool.inputSchema["properties"]

    # Check required parameters
    assert "image_url" in props
    assert props["image_url"]["type"] == "string"

    # Check optional parameters
    assert "scale" in props
    assert props["scale"]["default"] == 2
    assert props["scale"]["type"] == "integer"
    assert 2 in props["scale"]["enum"]
    assert 4 in props["scale"]["enum"]

    assert "model" in props
    assert props["model"]["default"] == "fal-ai/clarity-upscaler"

    # Only image_url is required
    assert tool.inputSchema["required"] == ["image_url"]


@pytest.mark.asyncio
async def test_edit_image_tool_schema():
    """Test that edit_image tool has correct schema."""
    from fal_mcp_server.server import list_tools

    tools = await list_tools()
    tool = next(t for t in tools if t.name == "edit_image")

    assert tool is not None
    props = tool.inputSchema["properties"]

    # Check required parameters
    assert "image_url" in props
    assert props["image_url"]["type"] == "string"

    assert "instruction" in props
    assert props["instruction"]["type"] == "string"

    # Check optional parameters
    assert "model" in props
    assert props["model"]["default"] == "fal-ai/flux-2/edit"

    assert "strength" in props
    assert props["strength"]["default"] == 0.75
    assert props["strength"]["minimum"] == 0.0
    assert props["strength"]["maximum"] == 1.0

    assert "seed" in props
    assert props["seed"]["type"] == "integer"

    # Both image_url and instruction are required
    assert "image_url" in tool.inputSchema["required"]
    assert "instruction" in tool.inputSchema["required"]


@pytest.mark.asyncio
async def test_inpaint_image_tool_schema():
    """Test that inpaint_image tool has correct schema."""
    from fal_mcp_server.server import list_tools

    tools = await list_tools()
    tool = next(t for t in tools if t.name == "inpaint_image")

    assert tool is not None
    props = tool.inputSchema["properties"]

    # Check required parameters
    assert "image_url" in props
    assert props["image_url"]["type"] == "string"

    assert "mask_url" in props
    assert props["mask_url"]["type"] == "string"

    assert "prompt" in props
    assert props["prompt"]["type"] == "string"

    # Check optional parameters
    assert "model" in props
    assert props["model"]["default"] == "fal-ai/flux-kontext-lora/inpaint"

    assert "negative_prompt" in props
    assert props["negative_prompt"]["type"] == "string"

    assert "seed" in props
    assert props["seed"]["type"] == "integer"

    # image_url, mask_url, and prompt are all required
    assert "image_url" in tool.inputSchema["required"]
    assert "mask_url" in tool.inputSchema["required"]
    assert "prompt" in tool.inputSchema["required"]


@pytest.mark.asyncio
async def test_resize_image_tool_schema():
    """Test that resize_image tool has correct schema with social media presets."""
    from fal_mcp_server.server import list_tools

    tools = await list_tools()
    tool = next(t for t in tools if t.name == "resize_image")

    assert tool is not None
    props = tool.inputSchema["properties"]

    # Check required parameters
    assert "image_url" in props
    assert props["image_url"]["type"] == "string"

    assert "target_format" in props
    assert props["target_format"]["type"] == "string"

    # Check social media presets are in enum
    target_enum = props["target_format"]["enum"]
    assert "instagram_post" in target_enum
    assert "instagram_story" in target_enum
    assert "youtube_thumbnail" in target_enum
    assert "twitter_post" in target_enum
    assert "linkedin_post" in target_enum
    assert "facebook_post" in target_enum
    assert "pinterest_pin" in target_enum
    assert "tiktok" in target_enum
    assert "custom" in target_enum

    # Check resize modes
    assert "mode" in props
    assert props["mode"]["default"] == "extend"
    assert "extend" in props["mode"]["enum"]
    assert "crop" in props["mode"]["enum"]
    assert "letterbox" in props["mode"]["enum"]

    # Check custom dimension parameters
    assert "width" in props
    assert props["width"]["type"] == "integer"
    assert props["width"]["minimum"] == 64
    assert props["width"]["maximum"] == 4096

    assert "height" in props
    assert props["height"]["type"] == "integer"
    assert props["height"]["minimum"] == 64
    assert props["height"]["maximum"] == 4096

    # Check extend mode parameters
    assert "background_prompt" in props
    assert props["background_prompt"]["type"] == "string"

    # Check letterbox mode parameters
    assert "background_color" in props
    assert props["background_color"]["default"] == "#000000"

    # image_url and target_format are required
    assert "image_url" in tool.inputSchema["required"]
    assert "target_format" in tool.inputSchema["required"]


@pytest.mark.asyncio
async def test_social_media_formats_constant():
    """Test that SOCIAL_MEDIA_FORMATS constant has correct dimensions."""
    from fal_mcp_server.tools.image_editing_tools import SOCIAL_MEDIA_FORMATS

    # Check required formats exist
    assert "instagram_post" in SOCIAL_MEDIA_FORMATS
    assert "instagram_story" in SOCIAL_MEDIA_FORMATS
    assert "youtube_thumbnail" in SOCIAL_MEDIA_FORMATS
    assert "twitter_post" in SOCIAL_MEDIA_FORMATS
    assert "linkedin_post" in SOCIAL_MEDIA_FORMATS
    assert "tiktok" in SOCIAL_MEDIA_FORMATS

    # Check Instagram post is square (1:1)
    ig_post = SOCIAL_MEDIA_FORMATS["instagram_post"]
    assert ig_post["width"] == 1080
    assert ig_post["height"] == 1080
    assert ig_post["aspect"] == "1:1"

    # Check Instagram story is vertical (9:16)
    ig_story = SOCIAL_MEDIA_FORMATS["instagram_story"]
    assert ig_story["width"] == 1080
    assert ig_story["height"] == 1920
    assert ig_story["aspect"] == "9:16"

    # Check YouTube thumbnail is horizontal (16:9)
    yt_thumb = SOCIAL_MEDIA_FORMATS["youtube_thumbnail"]
    assert yt_thumb["width"] == 1280
    assert yt_thumb["height"] == 720
    assert yt_thumb["aspect"] == "16:9"


@pytest.mark.asyncio
async def test_image_editing_handlers_registered():
    """Test that all image editing handlers are registered in TOOL_HANDLERS."""
    from fal_mcp_server.server import TOOL_HANDLERS

    # All 5 image editing handlers should be registered
    assert "remove_background" in TOOL_HANDLERS
    assert "upscale_image" in TOOL_HANDLERS
    assert "edit_image" in TOOL_HANDLERS
    assert "inpaint_image" in TOOL_HANDLERS
    assert "resize_image" in TOOL_HANDLERS


def test_image_editing_tools_count():
    """Test that IMAGE_EDITING_TOOLS contains exactly 5 tools."""
    from fal_mcp_server.tools.image_editing_tools import IMAGE_EDITING_TOOLS

    assert len(IMAGE_EDITING_TOOLS) == 5

    tool_names = [t.name for t in IMAGE_EDITING_TOOLS]
    assert "remove_background" in tool_names
    assert "upscale_image" in tool_names
    assert "edit_image" in tool_names
    assert "inpaint_image" in tool_names
    assert "resize_image" in tool_names


def test_handlers_import():
    """Test that all image editing handlers can be imported."""
    from fal_mcp_server.handlers.image_editing_handlers import (
        handle_edit_image,
        handle_inpaint_image,
        handle_remove_background,
        handle_resize_image,
        handle_upscale_image,
    )

    # All handlers should be callable
    assert callable(handle_remove_background)
    assert callable(handle_upscale_image)
    assert callable(handle_edit_image)
    assert callable(handle_inpaint_image)
    assert callable(handle_resize_image)
