"""
Point d'entrée unique pour le DNS interne (résoudre les pairs par nom, ex:
`alice.meshamoto`, plutôt que par IP virtuelle `25.x.x.x`) — masque la différence
entre Windows et Linux derrière une API commune :

    update_entries({display_name: virtual_ip, ...})
    clear_entries()

Le reste du projet n'a jamais besoin de savoir sur quel OS il tourne, ni où se trouve
le fichier hosts (voir wireguard_manager.py / firewall_manager.py pour le même pattern).
"""

from __future__ import annotations

import logging
import sys

from hosts_file_common import (
    build_cleared_hosts_content,
    build_hostnames,
    build_updated_hosts_content,
)

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

if sys.platform == "win32":
    import hosts_file_backend_windows as _backend
elif sys.platform.startswith("linux"):
    import hosts_file_backend_linux as _backend
else:
    raise RuntimeError(
        f"Plateforme non supportée : {sys.platform}. "
        "Seuls Windows et Linux sont pris en charge par ce client."
    )


def _apply_via_helper(hostnames: dict[str, str]) -> bool:
    """
    Tente l'écriture par le composant privilégié (Linux uniquement), qui reçoit les
    ENTRÉES et non le contenu du fichier. Retourne False si indisponible — l'appelant
    retombe alors sur le chemin historique.
    """
    apply_entries = getattr(_backend, "apply_hosts_entries", None)
    return bool(apply_entries and apply_entries(hostnames))


def update_entries(name_to_ip: dict[str, str]) -> None:
    """Écrit/remplace le bloc Meshamoto du fichier hosts avec les pairs fournis."""
    existing = _backend.read_hosts_content()
    new_content = build_updated_hosts_content(existing, name_to_ip)
    if new_content == existing:
        logger.debug("DNS interne déjà à jour : écriture privilégiée évitée.")
        return
    if not _apply_via_helper(build_hostnames(name_to_ip)):
        _backend.apply_hosts_content(new_content)
    logger.info("DNS interne mis à jour (%d pair(s))", len(name_to_ip))


def clear_entries() -> None:
    """Retire le bloc Meshamoto du fichier hosts, laisse le reste inchangé."""
    existing = _backend.read_hosts_content()
    new_content = build_cleared_hosts_content(existing)
    if new_content == existing:
        logger.debug("Aucun bloc Meshamoto dans le fichier hosts : rien à retirer.")
        return
    if not _apply_via_helper({}):
        _backend.apply_hosts_content(new_content)
    logger.info("DNS interne désactivé (bloc retiré du fichier hosts)")
