"""Shared dependency utilities — request parsing helpers used across all API routers."""
from __future__ import annotations

import ipaddress
import uuid
from typing import Optional

from fastapi import HTTPException, Request

_TRUSTED_PROXY_NETS = [
    ipaddress.ip_network("10.0.0.0/8"),
    ipaddress.ip_network("127.0.0.0/8"),
    ipaddress.ip_network("172.16.0.0/12"),
    ipaddress.ip_network("192.168.0.0/16"),
    ipaddress.ip_network("::1/128"),
]


def _is_trusted_proxy(host: str) -> bool:
    try:
        addr = ipaddress.ip_address(host)
        return any(addr in net for net in _TRUSTED_PROXY_NETS)
    except ValueError:
        return False


def get_client_ip(request: Request) -> Optional[str]:
    """Extract best-effort client IP from request for audit logging (D-11 — trusted-proxy CIDR check).

    Only honours X-Forwarded-For when the direct peer is a known trusted proxy
    (RFC-1918 / loopback). Untrusted direct peers always return their own address,
    preventing XFF spoofing by external callers.

    TRUST BOUNDARY: this value is used for forensic audit logging only —
    not for authentication or access control decisions.
    """
    direct_peer = request.client.host if request.client else None
    if direct_peer and _is_trusted_proxy(direct_peer):
        xff = request.headers.get("X-Forwarded-For")
        if xff:
            return xff.split(",")[0].strip()
    return direct_peer


def parse_uuid(value: str, detail: str = "Not found") -> uuid.UUID:
    """Parse *value* as a UUID, raising HTTP 404 with *detail* on failure.

    Use at API boundaries to convert path/body string IDs to UUID objects.
    Returns the parsed UUID so callers can use it directly without a try/except.
    """
    try:
        return uuid.UUID(value)
    except ValueError:
        raise HTTPException(status_code=404, detail=detail)
