"""Entry points for launching the orchestrator as FastAPI or FastMCP."""

from __future__ import annotations

import argparse
import asyncio
import logging
from contextlib import asynccontextmanager
from typing import Optional

import uvicorn
from fastapi import FastAPI
from fastmcp import FastMCP

from .config import Settings, settings
from .docker_manager import SessionManager
from .routes import get_router

logger = logging.getLogger(__name__)


def create_app(app_settings: Optional[Settings] = None) -> FastAPI:
    """Create and configure the FastAPI application."""

    app_settings = app_settings or settings
    manager = SessionManager(app_settings)

    @asynccontextmanager
    async def lifespan(_: FastAPI):
        await manager.start()
        try:
            yield
        finally:
            await manager.stop()

    app = FastAPI(
        title="Embedding Atlas Orchestrator",
        version="0.1.0",
        description=(
            "Session orchestration API that launches short-lived embedding-atlas containers on demand."
        ),
        docs_url="/docs",
        redoc_url=None,
        openapi_url="/openapi.json",
        lifespan=lifespan,
    )

    @app.get("/", tags=["meta"], summary="Service metadata")
    async def root() -> dict[str, str]:
        return {"message": "Embedding Atlas session manager is running. Visit /docs for the Swagger UI."}

    app.include_router(get_router(manager))
    app.state.session_manager = manager
    return app


_app = create_app()
app = _app
_mcp_server = FastMCP.from_fastapi(_app, name="embedding-atlas-session-manager")
mcp_server = _mcp_server


def get_mcp_server() -> FastMCP:
    return mcp_server


def run_api() -> None:
    """Launch the FastAPI server via uvicorn."""

    uvicorn.run(
        app,
        host=settings.api_host,
        port=settings.api_port,
    )


async def _run_mcp_stdio_async() -> None:
    server = get_mcp_server()
    await server.run_stdio_async()


def run_mcp_stdio() -> None:
    """Launch the MCP server over stdio (experimental)."""

    asyncio.run(_run_mcp_stdio_async())


def main() -> None:
    """CLI entry point allowing API or MCP execution modes."""

    parser = argparse.ArgumentParser(description="Embedding Atlas orchestrator")
    parser.add_argument(
        "--mode",
        choices=["api", "mcp"],
        default="api",
        help="Select whether to launch the HTTP API or the MCP stdio server.",
    )
    parser.add_argument(
        "--host",
        default=settings.api_host,
        help="Override FastAPI bind host.",
    )
    parser.add_argument(
        "--port",
        type=int,
        default=settings.api_port,
        help="Override FastAPI bind port.",
    )
    args = parser.parse_args()

    if args.mode == "api":
        logger.info("Starting FastAPI server on %s:%s", args.host, args.port)
        uvicorn.run(app, host=args.host, port=args.port)
    else:
        logger.info("Starting FastMCP stdio server")
        run_mcp_stdio()


if __name__ == "__main__":
    main()
