"""
Valeurs proposées à quelqu'un qui crée son réseau : un nom dérivé de la machine,
et un mot de passe **généré**.

Existe parce que le parcours « héberger » déroulé en entier le 2026-07-31 laissait
les deux champs VIDES : l'utilisateur devait inventer un nom et un mot de passe
avant d'avoir compris ce qu'il fabriquait, juste après avoir cliqué sur un bouton
qui promettait « rien à configurer ailleurs ».

**Le mot de passe est généré, jamais un défaut connu comme `meshamoto`.** Ce
serveur est fait pour être exposé sur Internet (points 42 et 44), et un mot de
passe publiquement connu y serait une porte ouverte : la limitation de tentatives
ne compte que les ÉCHECS, donc un mot de passe correct connu de tous ne déclenche
rien ; et le mode isolation comme les ACL sont des réglages locaux appliqués *aux
pairs du réseau*, sans effet sur un intrus qui a légitimement rejoint. La
combinaison réellement dangereuse est « nom par défaut + mot de passe par
défaut » : les deux inconnues disparaissent d'un coup.
Le coût d'usage d'un mot de passe fort est de toute façon **nul**, puisque le code
d'invitation le transporte (point 52). L'affaiblir n'achèterait rien.

Logique pure, sans Qt ni réseau : testable directement.
"""

from __future__ import annotations

import re
import secrets
import unicodedata

# Alphabet sans caractères confondables (ni i/l/1, ni o/0). Ce mot de passe est
# affiché à l'écran et parfois recopié à la main — quand quelqu'un le dicte ou le
# transmet hors du code d'invitation. Un `l` pris pour un `1` produirait un échec
# d'authentification incompréhensible, et le compteur de tentatives ratées se
# remplirait pour une faute de lecture.
_ALPHABET = "abcdefghjkmnpqrstuvwxyz23456789"

# 4 groupes de 4 = 16 caractères sur 31 symboles, soit ~79 bits. Les tirets ne
# comptent pas dans l'entropie : ils ne servent qu'à rendre la lecture possible.
_GROUPES = 4
_TAILLE_GROUPE = 4

# Le serveur impose 3 à 64 caractères (CreateNetworkRequest) : un nom tronqué au
# mauvais endroit ferait échouer la création avec une erreur de validation que
# l'utilisateur ne pourrait pas relier à son nom de machine.
_NOM_MAX = 64
_NOM_MIN = 3
_NOM_DE_REPLI = "reseau-meshamoto"
_SUFFIXE = "-meshamoto"


def generer_mot_de_passe() -> str:
    """Mot de passe aléatoire lisible, de la forme `k7fp-x2mq-9rvt-b4ws`."""
    groupes = [
        "".join(secrets.choice(_ALPHABET) for _ in range(_TAILLE_GROUPE))
        for _ in range(_GROUPES)
    ]
    return "-".join(groupes)


def nom_reseau_par_defaut(nom_machine: str) -> str:
    """
    Nom dérivé du nom de la machine, ex. `master-pc-meshamoto`.

    Volontairement en ASCII minuscule sans espace : ce nom est la clé de
    recherche côté serveur, et il reste **saisissable à la main** par quelqu'un
    qui n'utilise pas le code d'invitation. Un accent ou une espace tiendraient
    parfaitement dans la base, mais transformeraient la transmission orale ou par
    message en source d'erreurs muettes (« réseau introuvable »).
    """
    base = unicodedata.normalize("NFKD", nom_machine or "")
    base = base.encode("ascii", "ignore").decode("ascii").lower()
    # Un nom de machine peut contenir un domaine (`pc.local`) ou des soulignés :
    # tout ce qui n'est pas alphanumérique devient un tiret unique.
    base = re.sub(r"[^a-z0-9]+", "-", base).strip("-")
    if not base:
        return _NOM_DE_REPLI

    # On tronque la BASE, pas le résultat : couper après coup mangerait le
    # suffixe et produirait des noms comme `machine-tres-longue-mesha`, dont on
    # ne peut plus dire s'ils viennent de Meshamoto.
    base = base[: _NOM_MAX - len(_SUFFIXE)].strip("-")
    if not base:
        return _NOM_DE_REPLI

    nom = f"{base}{_SUFFIXE}"
    return nom if len(nom) >= _NOM_MIN else _NOM_DE_REPLI
