"""Standalone FastAPI server for Memory System API."""
from __future__ import annotations

import logging

from fastapi import FastAPI, Request, Response
from fastapi.middleware.cors import CORSMiddleware

from .api import router
from .config import Config, load_config, set_config


request_logger = logging.getLogger("memory_system_api.requests")

app = FastAPI(title="Memory System API", version="0.1.0")
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)


@app.middleware("http")
async def log_request_and_response(request: Request, call_next):
    request_body = await request.body()
    request_logger.info(
        "request %s %s body=%s",
        request.method,
        _path_with_query(request),
        _body_for_log(request_body),
    )

    async def receive():
        return {"type": "http.request", "body": request_body, "more_body": False}

    response = await call_next(Request(request.scope, receive))
    response_body = b""
    async for chunk in response.body_iterator:
        response_body += chunk

    request_logger.info(
        "response %s %s status=%s body=%s",
        request.method,
        _path_with_query(request),
        response.status_code,
        _body_for_log(response_body),
    )
    return Response(
        content=response_body,
        status_code=response.status_code,
        headers=dict(response.headers),
        media_type=response.media_type,
        background=response.background,
    )


app.include_router(router)


def create_app(config: Config | None = None) -> FastAPI:
    if config:
        set_config(config)
    return app


def _path_with_query(request: Request) -> str:
    query = request.url.query
    return f"{request.url.path}?{query}" if query else request.url.path


def _body_for_log(body: bytes) -> str:
    if not body:
        return ""
    return body.decode("utf-8", errors="replace")


def main() -> None:
    import argparse
    import uvicorn

    parser = argparse.ArgumentParser(description="Memory System API")
    parser.add_argument("--config", default="config.yaml", help="Config file path")
    parser.add_argument("--host", default=None, help="Bind host")
    parser.add_argument("--port", type=int, default=None, help="Bind port")
    args = parser.parse_args()

    config = load_config(args.config)
    if args.host:
        config.server.host = args.host
    if args.port:
        config.server.port = args.port
    set_config(config)
    logging.basicConfig(level=config.logging.level.upper(), format=config.logging.format)

    uvicorn.run(app, host=config.server.host, port=config.server.port, log_level=config.logging.level.lower())


if __name__ == "__main__":
    main()
