"""Maschinen-Fingerprint der lizenzierten Instanz.

Jede Bindungs-/Autorisierungsentscheidung des Protokolls laeuft ueber diesen
Wert -- nie ueber ``hostname`` oder ``license_id`` allein.

Aenderung gegenueber dem Vorgaenger (bewusst): der Hostname ist **nicht** mehr
Teil des Hashes. Im Vorgaengerprojekt war ``sha256(machine_id + ":" + hostname)``
im Einsatz, wodurch eine reine Umbenennung des Hosts den Fingerprint aenderte
und die Lizenz "already_bound_elsewhere" lief -- ein Support-Fall ohne
Sicherheitsgewinn. Jetzt zaehlt ausschliesslich die stabile Maschinenidentitaet
(``/etc/machine-id``, ergaenzt um die DMI-Produkt-UUID, falls lesbar).
"""

from __future__ import annotations

import hashlib
import socket
from pathlib import Path

_MACHINE_ID_PATHS = (Path("/etc/machine-id"), Path("/var/lib/dbus/machine-id"))
_DMI_UUID_PATH = Path("/sys/class/dmi/id/product_uuid")

FINGERPRINT_CONTEXT = b"tesm/machine-fingerprint/v2\x00"


def _read_first(paths: tuple[Path, ...]) -> str:
    for path in paths:
        try:
            value = path.read_text(encoding="utf-8", errors="strict").strip()
        except OSError:
            continue
        if value:
            return value
    return ""


def machine_identity() -> str:
    """Rohe, ungehashte Maschinenidentitaet -- nur fuer Diagnose/Tests."""
    machine_id = _read_first(_MACHINE_ID_PATHS)
    dmi_uuid = ""
    try:
        dmi_uuid = _DMI_UUID_PATH.read_text(encoding="utf-8").strip()
    except OSError:
        pass
    if machine_id or dmi_uuid:
        return f"{machine_id}|{dmi_uuid}"
    # Letzter Ausweg (Windows/Container ohne machine-id): Hostname. Produktivziel
    # ist Linux, dort greift dieser Zweig nicht.
    return f"hostname:{socket.gethostname()}"


def system_fingerprint() -> str:
    """SHA-256-Hex-Digest der Maschinenidentitaet, domaenengetrennt gehasht."""
    return hashlib.sha256(FINGERPRINT_CONTEXT + machine_identity().encode("utf-8")).hexdigest()
