# src/semantic_doc_search/server.py
#
# Migrated from Flask → FastAPI
# core.py is unchanged — only the HTTP layer is swapped.

import os
import logging
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
from .core import SemanticDocSearch

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# ── App ───────────────────────────────────────────────────────────────────────

app = FastAPI(
    title="O-Lang Semantic Doc Search Resolver",
    version="1.0.0",
    description="Semantic document search resolver for O-Lang workflows",
)

# ── Routes ────────────────────────────────────────────────────────────────────

@app.get("/health")
def health():
    return {
        "status":               "healthy",
        "resolver_name":        "semantic-doc-search",
        "version":              "1.0.0",
        "capabilities":         ["vector.search", "vector.insert"],
        "embedding_dimensions": 384,
        "ready":                True,
    }


@app.get("/manifest")
def manifest():
    return {
        "name":     "semantic-doc-search",
        "version":  "1.0.0",
        "protocol": "http",
        "resolvers": [
            {
                "name":        "vector.search",
                "description": "Search indexed documents using semantic similarity",
                "input":       ["query", "top_k", "doc_root", "POSTGRES_URL"],
                "output":      ["query", "text", "matches", "count"],
            },
            {
                "name":        "vector.insert",
                "description": "Ingest and embed documents from a directory",
                "input":       ["doc_root", "chunk_size", "overlap", "POSTGRES_URL"],
                "output":      ["inserted", "doc_root", "backend"],
            },
        ],
    }


@app.post("/resolve")
async def resolve(request: Request):
    data = None
    try:
        data = await request.json()

        action  = data.get("action")
        context = data.get("context", {})

        if not action:
            return JSONResponse(
                status_code=400,
                content={"error": {"message": "Missing 'action' field"}},
            )

        resolver = SemanticDocSearch(context)
        result   = resolver.handle_action(action)

        return {
            "result":        result,
            "request_id":    data.get("request_id", ""),
            "resolver_name": "semantic-doc-search",
        }

    except ValueError as e:
        return JSONResponse(
            status_code=422,
            content={
                "error":      {"message": str(e)},
                "request_id": data.get("request_id", "") if data else "",
            },
        )

    except Exception as e:
        logger.error(f"Resolver execution error: {e}")
        return JSONResponse(
            status_code=500,
            content={
                "error":      {"message": f"Resolver execution error: {str(e)}"},
                "request_id": data.get("request_id", "") if data else "",
            },
        )


# ── Entry point ───────────────────────────────────────────────────────────────

def main():
    import uvicorn

    host = os.getenv("RESOLVER_HOST", "0.0.0.0")
    port = int(os.getenv("RESOLVER_PORT", 8080))

    print(f"""
  ╔══════════════════════════════════════════════════╗
  ║  O-Lang Semantic Doc Search  →  running          ║
  ║  http://{host}:{port}                              ║
  ║  GET  /health     GET  /manifest                 ║
  ║  POST /resolve                                   ║
  ╚══════════════════════════════════════════════════╝
    """)

    uvicorn.run(
        "semantic_doc_search.server:app",
        host=host,
        port=port,
        reload=os.getenv("ENV", "production") == "development",
    )


if __name__ == "__main__":
    main()