"""Entry point for the Cloudflare MCP Gateway."""

import asyncio
import logging
import signal
import sys
from typing import NoReturn

from .config import GatewaySettings, TransportMode
from .server import (
    connect_and_mount_services,
    initialize_gateway,
    mcp,
    shutdown_gateway,
)


def setup_logging(log_level: str) -> None:
    """Configure logging for the gateway.

    Logs are written to stderr to avoid interfering with stdio transport.

    Args:
        log_level: The logging level (debug, info, warning, error, critical).
    """
    level = getattr(logging, log_level.upper(), logging.INFO)

    # Configure root logger to stderr
    logging.basicConfig(
        level=level,
        format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
        stream=sys.stderr,
    )

    # Reduce noise from httpx and other libraries
    logging.getLogger("httpx").setLevel(logging.WARNING)
    logging.getLogger("httpcore").setLevel(logging.WARNING)


async def run_stdio() -> None:
    """Run the gateway with stdio transport."""
    logger = logging.getLogger(__name__)
    logger.info("Starting gateway with stdio transport")

    try:
        # FastMCP handles stdio communication
        await mcp.run_async()
    except Exception as e:
        logger.error(f"Stdio transport error: {e}")
        raise
    finally:
        await shutdown_gateway()


async def run_http(settings: GatewaySettings) -> None:
    """Run the gateway with streamable HTTP transport.

    Args:
        settings: Gateway configuration settings.
    """
    logger = logging.getLogger(__name__)
    logger.info(
        f"Starting gateway with streamable HTTP transport on "
        f"{settings.gateway_host}:{settings.gateway_port}"
    )

    # Set up signal handlers for graceful shutdown
    shutdown_event = asyncio.Event()

    def signal_handler(sig: int) -> None:
        logger.info(f"Received signal {sig}, initiating shutdown...")
        shutdown_event.set()

    loop = asyncio.get_event_loop()
    for sig in (signal.SIGINT, signal.SIGTERM):
        loop.add_signal_handler(sig, lambda s=sig: signal_handler(s))

    try:
        # Run the HTTP server using FastMCP's HTTP support
        # FastMCP uses Starlette/Uvicorn under the hood
        cors_origins = settings.get_cors_origins_list()

        # Create HTTP server task
        server_task = asyncio.create_task(
            mcp.run_http_async(
                host=settings.gateway_host,
                port=settings.gateway_port,
            )
        )

        # Wait for shutdown signal or server completion
        done, pending = await asyncio.wait(
            [server_task, asyncio.create_task(shutdown_event.wait())],
            return_when=asyncio.FIRST_COMPLETED,
        )

        # Cancel pending tasks
        for task in pending:
            task.cancel()
            try:
                await task
            except asyncio.CancelledError:
                pass

    except Exception as e:
        logger.error(f"HTTP transport error: {e}")
        raise
    finally:
        await shutdown_gateway()


async def async_main() -> None:
    """Async main entry point."""
    logger = logging.getLogger(__name__)

    try:
        # Load configuration
        settings = GatewaySettings()
        setup_logging(settings.log_level)

        logger.info("Initializing Cloudflare MCP Gateway")
        logger.info(f"Transport: {settings.transport.value}")
        logger.info(f"Enabled services: {settings.enabled_services}")

        # Initialize the gateway
        await initialize_gateway(settings)

        # Connect to upstream services and mount their tools
        await connect_and_mount_services()

        # Run with the configured transport
        if settings.transport == TransportMode.STDIO:
            await run_stdio()
        elif settings.transport == TransportMode.STREAMABLE_HTTP:
            await run_http(settings)
        else:
            raise ValueError(f"Unknown transport mode: {settings.transport}")

    except KeyboardInterrupt:
        logger.info("Received keyboard interrupt")
    except Exception as e:
        logger.error(f"Fatal error: {e}")
        sys.exit(1)


def main() -> NoReturn:
    """Main entry point for the CLI."""
    try:
        asyncio.run(async_main())
    except KeyboardInterrupt:
        pass
    sys.exit(0)


if __name__ == "__main__":
    main()
