"""
DNS interne — Linux : écrit le bloc Meshamoto dans /etc/hosts. Écriture via un
fichier temporaire + `cp` privilégié (même schéma que firewall_backend_linux.py pour
nftables) : plus sûr qu'une redirection shell, et évite de manipuler l'ownership/les
permissions du fichier temporaire lui-même (cp en root les fixe correctement).
"""

from __future__ import annotations

import logging
import tempfile
from pathlib import Path

import privileged_helper
from linux_privilege import run_privileged

logger = logging.getLogger("meshamoto-client.hosts.linux")

HOSTS_FILE_PATH = Path("/etc/hosts")


def read_hosts_content() -> str:
    return HOSTS_FILE_PATH.read_text(encoding="utf-8")


def apply_hosts_entries(hostnames: dict[str, str]) -> bool:
    """
    Applique le bloc DNS via le composant privilégié, en lui passant les ENTRÉES et non
    le contenu du fichier — il refuse par conception de recevoir un fichier tout fait,
    et revalide chaque nom d'hôte de son côté (un pseudo vient d'un autre pair, donc
    d'une source non fiable, et /etc/hosts est écrit en root).

    Retourne False si le composant est absent ou en échec : l'appelant retombe alors sur
    apply_hosts_content, le chemin historique.
    """
    if not privileged_helper.helper_available():
        return False
    args = ([privileged_helper.HELPER_PATH, "set-hosts"] if hostnames
            else [privileged_helper.HELPER_PATH, "clear-hosts"])
    for hostname, ip in sorted(hostnames.items()):
        args += ["--entry", f"{hostname}={ip}"]
    result = run_privileged(*args)
    if result.returncode == 0:
        return True
    logger.warning("Composant privilégié en échec sur le DNS, repli : %s", result.stderr.strip())
    return False


def apply_hosts_content(new_content: str) -> None:
    with tempfile.NamedTemporaryFile("w", suffix=".hosts", delete=False, encoding="utf-8") as f:
        f.write(new_content)
        temp_path = f.name

    try:
        result = run_privileged("cp", temp_path, str(HOSTS_FILE_PATH))
        if result.returncode != 0:
            raise RuntimeError(
                "Impossible de mettre à jour /etc/hosts. Vérifiez les privilèges root. "
                "Détail : " + result.stderr
            )
        logger.info("Fichier hosts mis à jour (%s)", HOSTS_FILE_PATH)
    finally:
        Path(temp_path).unlink(missing_ok=True)
