"""FastAPI application — Kredo Drift hosted API."""

from __future__ import annotations

from contextlib import asynccontextmanager

from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse

from kredo_drift.server.config import get_settings
from kredo_drift.server.db.session import init_db, close_db
from kredo_drift.server.routes import register, baseline, test, score, attestation, keys, merkle, drift_api


@asynccontextmanager
async def lifespan(app: FastAPI):
    """Initialize and tear down server resources."""
    await init_db()
    yield
    await close_db()


def create_app() -> FastAPI:
    """Build and configure the FastAPI application."""
    settings = get_settings()

    app = FastAPI(
        title="Kredo Drift API",
        description="Hosted identity drift detection for AI agents",
        version="0.2.0",
        lifespan=lifespan,
    )

    # CORS
    app.add_middleware(
        CORSMiddleware,
        allow_origins=settings.cors_origins,
        allow_credentials=True,
        allow_methods=["GET", "POST"],
        allow_headers=["*"],
    )

    # Error handlers
    @app.exception_handler(ValueError)
    async def value_error_handler(request: Request, exc: ValueError):
        return JSONResponse(status_code=400, content={"error": str(exc)})

    @app.exception_handler(PermissionError)
    async def permission_error_handler(request: Request, exc: PermissionError):
        return JSONResponse(status_code=403, content={"error": str(exc)})

    @app.exception_handler(LookupError)
    async def not_found_handler(request: Request, exc: LookupError):
        return JSONResponse(status_code=404, content={"error": str(exc)})

    # Health check
    @app.get("/health")
    async def health():
        return {"status": "ok", "service": "kredo-drift"}

    # Routes
    app.include_router(register.router, prefix="/v1")
    app.include_router(baseline.router, prefix="/v1")
    app.include_router(test.router, prefix="/v1")
    app.include_router(score.router, prefix="/v1")
    app.include_router(attestation.router, prefix="/v1")
    app.include_router(keys.router, prefix="/v1")
    app.include_router(merkle.router, prefix="/v1")
    app.include_router(drift_api.router)

    return app


app = create_app()
