"""FastAPI routes exposing the session management API."""

from __future__ import annotations

from fastapi import APIRouter, Depends, HTTPException, status

from .docker_manager import (
    DatasetDownloadError,
    PortUnavailableError,
    SessionExistsError,
    SessionManager,
    SessionNotFoundError,
)
from .models import (
    SessionCloseResponse,
    SessionCreateRequest,
    SessionListResponse,
    SessionRecord,
    SessionResponse,
)


def get_router(manager: SessionManager) -> APIRouter:
    router = APIRouter(prefix="/sessions", tags=["sessions"])

    async def get_manager() -> SessionManager:
        return manager

    @router.post("/", response_model=SessionResponse, status_code=status.HTTP_201_CREATED)
    async def create_session(
        payload: SessionCreateRequest,
        manager: SessionManager = Depends(get_manager),
    ) -> SessionResponse:
        try:
            record = await manager.create_session(payload)
        except SessionExistsError as exc:
            raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail=str(exc)) from exc
        except DatasetDownloadError as exc:
            raise HTTPException(status_code=status.HTTP_502_BAD_GATEWAY, detail=str(exc)) from exc
        except PortUnavailableError as exc:
            raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail=str(exc)) from exc
        endpoint = f"http://{record.host}:{record.port}"
        return SessionResponse(
            session_id=record.session_id,
            container_name=record.container_name,
            endpoint=endpoint,
            port=record.port,
            host=record.host,
            expires_at=record.expires_at,
        )

    @router.delete("/{session_id}", response_model=SessionCloseResponse)
    async def close_session(
        session_id: str,
        manager: SessionManager = Depends(get_manager),
    ) -> SessionCloseResponse:
        try:
            await manager.close_session(session_id)
        except SessionNotFoundError as exc:
            raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(exc)) from exc
        return SessionCloseResponse(session_id=session_id, removed=True)

    @router.get("/", response_model=SessionListResponse)
    async def list_sessions(manager: SessionManager = Depends(get_manager)) -> SessionListResponse:
        sessions = await manager.list_sessions()
        return SessionListResponse(sessions=list(sessions))

    return router


__all__ = ["get_router"]
