import re
from pathlib import Path

from fastapi import APIRouter, FastAPI
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.responses import Response

MIME_TYPES = {
    ".wasm": "application/wasm",
    ".json": "application/json",
    ".js": "text/javascript",
}


class COOPCOEPMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request, call_next):
        response = await call_next(request)
        response.headers["Cross-Origin-Opener-Policy"] = "same-origin"
        response.headers["Cross-Origin-Embedder-Policy"] = "require-corp"
        return response


def _resolve_db_dir() -> Path:
    return Path("node_modules/@n6k.io/db").resolve()


worker_router = APIRouter()
_build_dir = Path("build").resolve()


@worker_router.get("/workers/{filename}")
async def serve_worker(filename: str):
    file = _build_dir / filename
    if not file.is_file():
        return Response("not found", status_code=404)
    return Response(content=file.read_text(), media_type="text/javascript")


def register_duckdb(app: FastAPI) -> None:
    app.add_middleware(COOPCOEPMiddleware)

    db_dir = _resolve_db_dir()
    wasm_dir = db_dir / "wasm"

    @app.get("/v{version}/{platform}/{filename}")
    async def serve_wasm_extension(version: str, platform: str, filename: str):
        platform = re.sub(r"wasm_(eh|threads)", "wasm_mvp", platform)
        file = wasm_dir / f"v{version}" / platform / filename
        if not file.is_file():
            available = next(wasm_dir.iterdir(), None)
            if available:
                file = available / platform / filename
        if not file.is_file():
            return Response("not found", status_code=404)
        suffix = file.suffix
        media_type = MIME_TYPES.get(suffix, "application/octet-stream")
        return Response(content=file.read_bytes(), media_type=media_type)

    app.include_router(worker_router, prefix=app.state.asset_prefix)
