"""Server-level file-management elevation policy (stored in ``servers.extra_attrs``)."""

from __future__ import annotations

from enum import StrEnum

from server.domain.models import Server

FILES_ELEVATION_ATTR = "files_elevation"
VALID_FILES_ELEVATIONS = frozenset({"off", "auto_sudo", "always_sudo"})
DEFAULT_FILES_ELEVATION = "auto_sudo"
SUDOERS_DOC_PATH = "docs/deploy/nexus-files-sudoers.example"


class FilesElevation(StrEnum):
    OFF = "off"
    AUTO = "auto_sudo"
    ALWAYS = "always_sudo"


def normalize_files_elevation(value: object | None) -> FilesElevation:
    """Return elevation mode; unknown values fall back to AUTO."""
    if value is None or value == "":
        return FilesElevation.AUTO
    raw = str(value).strip().lower()
    if raw in VALID_FILES_ELEVATIONS:
        return FilesElevation(raw)
    return FilesElevation.AUTO


def get_files_elevation(server: Server) -> FilesElevation:
    attrs = server.extra_attrs if isinstance(server.extra_attrs, dict) else {}
    return normalize_files_elevation(attrs.get(FILES_ELEVATION_ATTR))


def merge_files_elevation_into_extra_attrs(
    extra_attrs: dict | None,
    files_elevation: str | None,
) -> dict | None:
    if files_elevation is None:
        return extra_attrs
    out = dict(extra_attrs or {})
    mode = normalize_files_elevation(files_elevation)
    out[FILES_ELEVATION_ATTR] = mode.value
    return out


def apply_files_elevation_payload(data: dict) -> None:
    """Pop ``files_elevation`` from API payload and merge into ``extra_attrs``."""
    fe = data.pop("files_elevation", None)
    if fe is not None:
        data["extra_attrs"] = merge_files_elevation_into_extra_attrs(
            data.get("extra_attrs"),
            fe,
        )
