"""Public agent endpoint proxy mounted on the primary API service.

This keeps `/api/v1/agent/*` available at `api.foundryops.io` even when edge
path routing to the dedicated `gremlin-agent-api` service is not configured.
"""

from __future__ import annotations

import logging
import os
from typing import Any

import httpx
from fastapi import APIRouter, Body, HTTPException
from fastapi.responses import JSONResponse, Response

router = APIRouter()
log = logging.getLogger(__name__)

_DEFAULT_AGENT_API_BASE = "https://gremlin-agent-api-5pkec6diha-uc.a.run.app"


def _agent_api_base() -> str:
    return (
        os.getenv("AGENT_PUBLIC_API_BASE")
        or os.getenv("GREMLIN_AGENT_API_URL")
        or _DEFAULT_AGENT_API_BASE
    ).rstrip("/")


def _local_agent_enabled() -> bool:
    return os.getenv("AGENT_PUBLIC_LOCAL_ENABLED", "1").strip().lower() not in {
        "0",
        "false",
        "no",
        "off",
    }


def _proxy_fallback_enabled() -> bool:
    return os.getenv("AGENT_PUBLIC_PROXY_FALLBACK_ENABLED", "1").strip().lower() not in {
        "0",
        "false",
        "no",
        "off",
    }


def _http_exception_response(exc: HTTPException) -> Response:
    detail = exc.detail
    if isinstance(detail, (dict, list)):
        return JSONResponse(status_code=exc.status_code, content=detail)
    return JSONResponse(status_code=exc.status_code, content={"detail": detail})


async def _try_local_agent_tiers() -> Response | None:
    if not _local_agent_enabled():
        return None

    try:
        from backend_admin.app.routers import agent_tiers as local_agent_tiers

        return JSONResponse(status_code=200, content=await local_agent_tiers.get_agent_tiers())
    except HTTPException as exc:
        if exc.status_code < 500 or not _proxy_fallback_enabled():
            return _http_exception_response(exc)
        log.warning("Local agent tiers unavailable; falling back to upstream proxy: %s", exc.detail)
    except Exception as exc:  # noqa: BLE001 - preserve legacy proxy as fallback
        if not _proxy_fallback_enabled():
            raise HTTPException(status_code=500, detail=f"Local agent tiers failed: {exc}") from exc
        log.warning("Local agent tiers failed; falling back to upstream proxy: %s", exc, exc_info=True)

    return None


async def _try_local_agent_license_keys() -> Response | None:
    if not _local_agent_enabled():
        return None

    try:
        from backend_admin.app.routers import license_signing as local_license_signing

        return JSONResponse(
            status_code=200,
            content=await local_license_signing.get_public_keys(),
        )
    except HTTPException as exc:
        if exc.status_code < 500 or not _proxy_fallback_enabled():
            return _http_exception_response(exc)
        log.warning("Local agent key endpoint unavailable; falling back to upstream proxy: %s", exc.detail)
    except Exception as exc:  # noqa: BLE001 - preserve legacy proxy as fallback
        if not _proxy_fallback_enabled():
            raise HTTPException(status_code=500, detail=f"Local agent key endpoint failed: {exc}") from exc
        log.warning("Local agent key endpoint failed; falling back to upstream proxy: %s", exc, exc_info=True)

    return None


async def _try_local_install_token_resolve(body: dict[str, Any]) -> Response | None:
    if not _local_agent_enabled():
        return None

    try:
        from backend_admin.app.routers import license_signing as local_license_signing

        payload = await local_license_signing.resolve_install_token(
            local_license_signing.ResolveTokenRequest(**body)
        )
        return JSONResponse(status_code=200, content=payload)
    except HTTPException as exc:
        if exc.status_code < 500 or not _proxy_fallback_enabled():
            return _http_exception_response(exc)
        log.warning("Local install-token resolver unavailable; falling back to upstream proxy: %s", exc.detail)
    except Exception as exc:  # noqa: BLE001 - preserve legacy proxy as fallback
        if not _proxy_fallback_enabled():
            raise HTTPException(status_code=500, detail=f"Local install-token resolver failed: {exc}") from exc
        log.warning("Local install-token resolver failed; falling back to upstream proxy: %s", exc, exc_info=True)

    return None


async def _forward_agent_request(
    method: str,
    path: str,
    payload: dict[str, Any] | None = None,
) -> Response:
    url = f"{_agent_api_base()}{path}"
    try:
        async with httpx.AsyncClient(timeout=20.0) as client:
            upstream = await client.request(method, url, json=payload)
    except httpx.RequestError as exc:
        raise HTTPException(status_code=502, detail=f"Agent API upstream unavailable: {exc}") from exc

    content_type = upstream.headers.get("content-type", "")
    if "application/json" in content_type.lower():
        try:
            data = upstream.json()
        except Exception:
            data = {"detail": upstream.text}
        return JSONResponse(status_code=upstream.status_code, content=data)

    media_type = content_type or None
    return Response(status_code=upstream.status_code, content=upstream.content, media_type=media_type)


@router.get("/api/v1/agent/tiers")
async def get_agent_tiers_proxy() -> Response:
    local_response = await _try_local_agent_tiers()
    if local_response is not None:
        return local_response
    return await _forward_agent_request("GET", "/api/v1/agent/tiers")


@router.get("/api/v1/agent/licenses/keys")
async def get_agent_license_keys_proxy() -> Response:
    local_response = await _try_local_agent_license_keys()
    if local_response is not None:
        return local_response
    return await _forward_agent_request("GET", "/api/v1/agent/licenses/keys")


@router.post("/api/v1/agent/licenses/resolve")
async def resolve_install_token_proxy(
    body: dict[str, Any] = Body(...),
) -> Response:
    local_response = await _try_local_install_token_resolve(body)
    if local_response is not None:
        return local_response
    return await _forward_agent_request(
        "POST",
        "/api/v1/agent/licenses/resolve",
        payload=body,
    )
