# license_manager.py
import os
import sys
import hashlib
import hmac

SECRET_KEY = "CIEN_BRAZOS_SECRET_KEY_2026"
LICENSE_FILENAME = "license.lic"

def get_machine_id() -> str:
    """
    Obtiene un identificador único del sistema de forma multiplataforma y robusta.
    """
    try:
        if sys.platform == "win32":
            import winreg
            try:
                key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\Microsoft\Cryptography")
                value, _ = winreg.QueryValueEx(key, "MachineGuid")
                return value.strip()
            except Exception:
                # Fallback de wmic en Windows si falla el registro
                import subprocess
                out = subprocess.check_output("wmic csproduct get uuid", shell=True)
                uuid_str = out.decode().split("\n")[1].strip()
                if uuid_str:
                    return uuid_str
        else:
            # Linux o macOS
            for path in ["/var/lib/dbus/machine-id", "/etc/machine-id"]:
                if os.path.exists(path):
                    with open(path, "r") as f:
                        return f.read().strip()
    except Exception:
        pass

    # Fallback definitivo usando la dirección MAC física
    try:
        import uuid
        return str(uuid.getnode())
    except Exception:
        return "UNKNOWN_HWID_FALLBACK"

def calculate_expected_license(machine_id: str) -> str:
    """
    Calcula la firma HMAC-SHA256 única para el Machine ID utilizando la clave secreta.
    """
    h = hmac.new(SECRET_KEY.encode('utf-8'), machine_id.strip().encode('utf-8'), hashlib.sha256)
    return h.hexdigest()

def verify_license(key: str, machine_id: str) -> bool:
    """
    Verifica si una clave de licencia ingresada coincide con la firma esperada del HWID.
    """
    if not key:
        return False
    expected = calculate_expected_license(machine_id)
    return key.strip() == expected

def get_license_path() -> str:
    """
    Obtiene la ruta absoluta para el archivo de licencia local.
    """
    base_dir = os.path.dirname(os.path.abspath(__file__))
    return os.path.join(base_dir, LICENSE_FILENAME)

def is_activated() -> bool:
    """
    Verifica si el sistema ya cuenta con una licencia válida para la máquina actual.
    """
    path = get_license_path()
    if not os.path.exists(path):
        return False
    try:
        with open(path, "r") as f:
            saved_key = f.read().strip()
        machine_id = get_machine_id()
        return verify_license(saved_key, machine_id)
    except Exception:
        return False

def save_license(key: str) -> bool:
    """
    Guarda de forma persistente la clave de licencia si es válida.
    """
    machine_id = get_machine_id()
    if verify_license(key, machine_id):
        try:
            path = get_license_path()
            with open(path, "w") as f:
                f.write(key.strip())
            return True
        except Exception:
            return False
    return False
