"""External-entry auth helpers for MCP adapter."""
from __future__ import annotations

import os

import httpx

from security.auth.api_keys import ResolvedAPIKey


def _normbase_base_url() -> str:
    return os.getenv("NORMBASE_BASE_URL", "http://localhost:8001").rstrip("/")


async def resolve_agent_api_key(provided_api_key: str) -> ResolvedAPIKey | None:
    """Resolve per-agent API key via runtime-safe introspection endpoint."""
    if not provided_api_key:
        return None
    headers = {"X-API-Key": provided_api_key}
    try:
        async with httpx.AsyncClient(timeout=20.0) as client:
            resp = await client.get(
                f"{_normbase_base_url()}/api/v1/keys/introspect",
                headers=headers,
            )
            if resp.status_code >= 400:
                return None
            data = resp.json()
            return ResolvedAPIKey(
                key_id=str(data.get("key_id", "")),
                agent_id=str(data.get("agent_id", "")),
                scopes=list(data.get("scopes", ["*"])),
                is_active=bool(data.get("is_active", True)),
                expires_at=data.get("expires_at"),
            )
    except Exception:
        return None


def effective_caller_api_key(provided_api_key: str | None) -> str:
    """Resolve effective caller key with tool-arg precedence."""
    return (provided_api_key or "").strip() or os.getenv(
        "AIF_MCP_CALLER_API_KEY", ""
    ).strip()


async def authenticate_mcp_caller(provided_api_key: str | None) -> ResolvedAPIKey:
    """
    Authenticate MCP caller using per-agent keys only.

    Order:
    1) Tool arg `caller_api_key`
    2) Env fallback `AIF_MCP_CALLER_API_KEY`
    3) Resolve via Normbase `/api/v1/keys/resolve`
    """
    # Precedence keeps explicit tool params in control while supporting
    # client environments that cannot inject tool arguments automatically.
    effective_api_key = effective_caller_api_key(provided_api_key)
    if not effective_api_key:
        raise PermissionError("Unauthorized: missing MCP caller API key.")

    resolved = await resolve_agent_api_key(effective_api_key)
    if resolved and resolved.agent_id:
        return resolved

    raise PermissionError("Unauthorized: invalid MCP API key.")

