"""GDS rendering utilities for MCP server.

This module provides utilities for rendering GDS files to PNG images,
enabling automatic image return when building cells.
"""

from __future__ import annotations

import base64
import logging
from pathlib import Path

from mcp.types import ImageContent

from .registry import ServerRegistry
from .utils import wait_for_gds_file

__all__ = ["render_gds_to_png", "render_built_cells", "HAS_KLAYOUT"]

logger = logging.getLogger(__name__)

try:
    import klayout.db as db
    import klayout.lay as lay

    HAS_KLAYOUT = True
except ImportError:
    HAS_KLAYOUT = False
    db = None  # type: ignore[assignment]
    lay = None  # type: ignore[assignment]


def render_gds_to_png(
    gds_path: Path,
    width: int = 800,
    height: int = 600,
) -> bytes | None:
    """Render GDS file to PNG image using klayout.

    Args:
        gds_path: Path to the GDS file to render
        width: Image width in pixels (default: 800)
        height: Image height in pixels (default: 600)

    Returns:
        PNG image as bytes, or None if klayout is not available or rendering fails
    """
    if not HAS_KLAYOUT:
        logger.debug("klayout not available, skipping GDS rendering")
        return None

    if not gds_path.exists():
        logger.warning("GDS file not found for rendering: %s", gds_path)
        return None

    try:
        layout = db.Layout()
        layout.read(str(gds_path))

        layout_view = lay.LayoutView()
        layout_view.load_layout(str(gds_path), True)

        layout_view.max_hier()

        layout_view.zoom_fit()

        pixel_buffer = layout_view.get_pixels(width, height)

        png_bytes = pixel_buffer.to_png_data()

        logger.debug("Rendered GDS to PNG: %s (%dx%d)", gds_path, width, height)
        return png_bytes

    except Exception as e:
        logger.warning("Failed to render GDS to PNG: %s - %s", gds_path, e)
        return None


async def render_built_cells(
    cell_names: list[str],
    project: str | None,
) -> list[ImageContent]:
    """Render built GDS cells to PNG images.

    Args:
        cell_names: List of cell names to render
        project: Optional project name for routing

    Returns:
        List of ImageContent for successfully rendered cells
    """
    images: list[ImageContent] = []

    if not cell_names:
        return images

    if not HAS_KLAYOUT:
        logger.debug("klayout not available, skipping cell rendering")
        return images

    registry = ServerRegistry()
    server_info = None

    if project:
        server_info = registry.get_server_by_project(project)
    if not server_info:
        servers = registry.list_servers()
        if servers:
            server_info = servers[0]

    if not server_info:
        logger.debug(
            "No server found in registry, cannot determine project path for GDS rendering"
        )
        return images

    project_path = Path(server_info.project_path)
    gds_dir = project_path / "build" / "gds"

    for cell_name in cell_names:
        gds_path = gds_dir / f"{cell_name}.gds"

        if await wait_for_gds_file(gds_path):
            png_bytes = render_gds_to_png(gds_path)
            if png_bytes:
                images.append(
                    ImageContent(
                        type="image",
                        data=base64.b64encode(png_bytes).decode("utf-8"),
                        mimeType="image/png",
                    )
                )
                logger.info("Added PNG image for cell: %s", cell_name)
            else:
                logger.debug("Failed to render GDS to PNG for cell: %s", cell_name)
        else:
            logger.debug("GDS file not found within timeout for cell: %s", cell_name)

    return images
