"""Integration tests for LoadFileAttachment tool."""

import os
import tempfile
from pathlib import Path

import pytest

from agency_swarm import Agent
from agency_swarm.tools.built_in import LoadFileAttachment


@pytest.fixture
def agent_with_file_loader():
    """Create an agent with LoadFileAttachment tool."""
    return Agent(
        name="FileLoaderAgent",
        description="Test agent with file loading capability",
        instructions="Load files when requested",
        tools=[LoadFileAttachment],
    )


@pytest.fixture
def temp_test_dir_with_files():
    """Create a temporary directory with test files."""
    with tempfile.TemporaryDirectory() as tmpdir:
        temp_path = Path(tmpdir)

        # Create a simple PNG image (1x1 red pixel)
        png_file = temp_path / "test.png"
        # PNG header + 1x1 red pixel
        png_data = (
            b"\x89PNG\r\n\x1a\n"  # PNG signature
            b"\x00\x00\x00\rIHDR\x00\x00\x00\x01\x00\x00\x00\x01"
            b"\x08\x02\x00\x00\x00\x90wS\xde"
            b"\x00\x00\x00\x0cIDATx\x9cc\xf8\xcf\xc0\x00\x00\x00\x03\x00\x01\x00\x00\x00\x00"
            b"\x00\x00\x00\x00IEND\xaeB`\x82"
        )
        png_file.write_bytes(png_data)

        # Create a JPEG file marker
        jpg_file = temp_path / "test.jpg"
        # Minimal valid JPEG
        jpg_data = b"\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x00\x00\x01\x00\x01\x00\x00\xff\xd9"
        jpg_file.write_bytes(jpg_data)

        # Create a PDF file marker
        pdf_file = temp_path / "test.pdf"
        pdf_file.write_text("%PDF-1.4\n%%EOF")

        yield temp_path


class TestLoadFileAttachmentBasics:
    """Test basic file loading functionality."""

    @pytest.mark.asyncio
    async def test_load_pdf_file(self, agent_with_file_loader, temp_test_dir_with_files):
        """Test loading a PDF file."""
        pdf_file = temp_test_dir_with_files / "test.pdf"

        tool = LoadFileAttachment(path=pdf_file)
        tool._caller_agent = agent_with_file_loader

        result = await tool.run()

        # Should return a ToolOutputFileContent object
        assert hasattr(result, "type")
        assert result.type == "file"

    @pytest.mark.asyncio
    async def test_load_png_image(self, agent_with_file_loader, temp_test_dir_with_files):
        """Test loading a PNG image file."""
        png_file = temp_test_dir_with_files / "test.png"

        tool = LoadFileAttachment(path=png_file)
        tool._caller_agent = agent_with_file_loader

        result = await tool.run()

        # Should return a ToolOutputImage object with image_url
        assert hasattr(result, "image_url") or hasattr(result, "file_id")
        assert hasattr(result, "detail")

    @pytest.mark.asyncio
    async def test_load_jpeg_image(self, agent_with_file_loader, temp_test_dir_with_files):
        """Test loading a JPEG image file."""
        jpg_file = temp_test_dir_with_files / "test.jpg"

        tool = LoadFileAttachment(path=jpg_file)
        tool._caller_agent = agent_with_file_loader

        result = await tool.run()

        # Should return a ToolOutputImage object with image_url
        assert hasattr(result, "image_url") or hasattr(result, "file_id")
        assert hasattr(result, "detail")


class TestLoadFileAttachmentPathResolution:
    """Test path resolution functionality."""

    @pytest.mark.asyncio
    async def test_absolute_path(self, agent_with_file_loader, temp_test_dir_with_files):
        """Test loading file with absolute path."""
        pdf_file = temp_test_dir_with_files / "test.pdf"

        tool = LoadFileAttachment(path=pdf_file)
        tool._caller_agent = agent_with_file_loader

        result = await tool.run()

        assert hasattr(result, "type")
        assert result.type == "file"

    @pytest.mark.asyncio
    async def test_relative_path(self, agent_with_file_loader, temp_test_dir_with_files):
        """Test loading file with relative path (from CWD)."""
        # Save current directory
        original_cwd = Path.cwd()

        try:
            # Change to temp directory
            os.chdir(temp_test_dir_with_files)

            # Use relative path
            tool = LoadFileAttachment(path=Path("test.pdf"))
            tool._caller_agent = agent_with_file_loader

            result = await tool.run()

            assert hasattr(result, "type")
            assert result.type == "file"
        finally:
            # Restore original directory
            os.chdir(original_cwd)


class TestLoadFileAttachmentErrorHandling:
    """Test error handling and helpful messages."""

    @pytest.mark.asyncio
    async def test_file_not_found_with_directory_listing(self, agent_with_file_loader, temp_test_dir_with_files):
        """Test that missing file shows available files in directory."""
        nonexistent_file = temp_test_dir_with_files / "does_not_exist.pdf"

        tool = LoadFileAttachment(path=nonexistent_file)
        tool._caller_agent = agent_with_file_loader

        result = await tool.run()

        # Should be a string with error message and file listing
        assert isinstance(result, str)
        assert "File not found" in result
        assert "Available files" in result
        # Should list the existing files
        assert "test.pdf" in result
        assert "test.png" in result

    @pytest.mark.asyncio
    async def test_file_not_found_empty_directory(self, agent_with_file_loader):
        """Test error message when directory is empty."""
        with tempfile.TemporaryDirectory() as tmpdir:
            temp_path = Path(tmpdir)
            nonexistent_file = temp_path / "missing.pdf"

            tool = LoadFileAttachment(path=nonexistent_file)
            tool._caller_agent = agent_with_file_loader

            result = await tool.run()

            assert isinstance(result, str)
            assert "File not found" in result
            assert "is empty" in result


class TestLoadFileAttachmentImageFormats:
    """Test various image format detection."""

    @pytest.mark.asyncio
    async def test_various_image_extensions(self, agent_with_file_loader):
        """Test that various image extensions are recognized."""
        with tempfile.TemporaryDirectory() as tmpdir:
            temp_path = Path(tmpdir)

            # Test different image extensions that have MIME type support
            image_extensions = [".gif", ".bmp"]

            for ext in image_extensions:
                # Create a dummy file
                image_file = temp_path / f"test{ext}"
                image_file.write_bytes(b"dummy image data")

                tool = LoadFileAttachment(path=image_file)
                tool._caller_agent = agent_with_file_loader

                result = await tool.run()

                # Should be treated as image and return ToolOutputImage
                assert hasattr(result, "image_url") or hasattr(result, "file_id"), (
                    f"Extension {ext} should return image"
                )
                assert hasattr(result, "detail")

    @pytest.mark.asyncio
    async def test_case_insensitive_extension(self, agent_with_file_loader):
        """Test that image detection is case-insensitive."""
        with tempfile.TemporaryDirectory() as tmpdir:
            temp_path = Path(tmpdir)

            # Create files with uppercase extensions
            png_upper = temp_path / "test.PNG"
            png_upper.write_bytes(b"dummy")

            jpg_upper = temp_path / "test.JPG"
            jpg_upper.write_bytes(b"dummy")

            for file_path in [png_upper, jpg_upper]:
                tool = LoadFileAttachment(path=file_path)
                tool._caller_agent = agent_with_file_loader

                result = await tool.run()

                # Should return ToolOutputImage
                assert hasattr(result, "image_url") or hasattr(result, "file_id")
                assert hasattr(result, "detail")
