"""Standard I/O transport for MCP server."""

from __future__ import annotations

import asyncio
from typing import TYPE_CHECKING

from mcp.server.stdio import stdio_server

from ..errors import TransportError
from ..logging import get_logger
from .base import Transport

if TYPE_CHECKING:
    from mcp.server import Server

logger = get_logger(__name__)


class StdioTransport(Transport):
    """Standard I/O transport for local MCP connections.
    
    Uses stdin/stdout for communication with MCP clients. This is the default
    transport for local development and is supported by all MCP clients.
    """
    
    def __init__(self) -> None:
        """Initialize the stdio transport."""
        self._server_task: asyncio.Task | None = None
        self._stop_event: asyncio.Event | None = None
    
    async def start(self, server: Server) -> None:
        """Start the stdio transport.
        
        Args:
            server: The MCP server instance to serve
            
        Raises:
            TransportError: If the transport fails to start
        """
        try:
            logger.info("stdio_transport_starting")
            
            self._stop_event = asyncio.Event()
            
            async with stdio_server() as (read_stream, write_stream):
                init_options = server.create_initialization_options()
                
                self._server_task = asyncio.create_task(
                    server.run(
                        read_stream,
                        write_stream,
                        initialization_options=init_options,
                        raise_exceptions=False,
                    )
                )
                
                logger.info("stdio_transport_started")
                
                # Wait for stop signal
                await self._stop_event.wait()
                
                # Cancel server task
                if self._server_task and not self._server_task.done():
                    self._server_task.cancel()
                    try:
                        await self._server_task
                    except asyncio.CancelledError:
                        pass
                
                logger.info("stdio_transport_stopped")
                
        except Exception as exc:
            logger.error("stdio_transport_failed", error=str(exc))
            raise TransportError(
                f"Failed to start stdio transport: {exc}",
                transport_type="stdio"
            ) from exc
    
    async def stop(self) -> None:
        """Stop the stdio transport.
        
        Raises:
            TransportError: If the transport fails to stop cleanly
        """
        try:
            if self._stop_event:
                logger.info("stdio_transport_stopping")
                self._stop_event.set()
        except Exception as exc:
            logger.error("stdio_transport_stop_failed", error=str(exc))
            raise TransportError(
                f"Failed to stop stdio transport: {exc}",
                transport_type="stdio"
            ) from exc
    
    @property
    def transport_type(self) -> str:
        """Get the transport type identifier.
        
        Returns:
            "stdio"
        """
        return "stdio"

