from __future__ import annotations

from collections.abc import Mapping
from ipaddress import ip_address
import os

from fastapi import Request

WRITE_METHODS = {"POST", "PUT", "PATCH", "DELETE"}
WRITE_MODES = {"disabled", "local_only", "test"}


def is_local_request(request: Request) -> bool:
    client_host = request.client.host if request.client else ""
    if client_host == "testclient":
        return True
    try:
        return ip_address(client_host).is_loopback
    except ValueError:
        return False


def resolve_write_mode(
    write_mode: str | None = None,
    environ: Mapping[str, str] | None = None,
) -> str:
    env = environ or os.environ
    candidate = (write_mode or env.get("JARVIS_FINANCE_WRITE_MODE", "disabled")).strip().lower()
    return candidate if candidate in WRITE_MODES else "disabled"


def is_write_request_allowed(request: Request, write_mode: str) -> bool:
    client_host = request.client.host if request.client else ""
    if write_mode == "test":
        return client_host == "testclient"
    if write_mode != "local_only":
        return False
    return is_local_request(request)
