"""
HWID генерация — привязка лицензии к железу.
SHA256(disk_serial|cpu_id|TELEPUSH)
"""
import hashlib
import subprocess
import platform


def _run_cmd(cmd):
    try:
        kwargs = {"capture_output": True, "text": True, "timeout": 5}
        if platform.system() == "Windows":
            kwargs["creationflags"] = 0x08000000
        r = subprocess.run(cmd, **kwargs)
        lines = [l.strip() for l in r.stdout.strip().splitlines() if l.strip()]
        return lines[-1] if len(lines) > 1 else lines[0] if lines else ""
    except Exception:
        return ""


def _get_disk_serial():
    if platform.system() != "Windows":
        return "linux-disk"
    # Try PowerShell first (works on Win11 without wmic)
    val = _run_cmd([
        "powershell", "-NoProfile", "-Command",
        "(Get-CimInstance Win32_DiskDrive | Select-Object -First 1).SerialNumber"
    ])
    if val and val != "SerialNumber" and len(val) > 3:
        return val
    # Fallback to wmic
    val = _run_cmd(["wmic", "diskdrive", "get", "serialnumber"])
    if val and val.lower() != "serialnumber":
        return val
    return "unknown-disk"


def _get_cpu_id():
    if platform.system() != "Windows":
        return "linux-cpu"
    # Try PowerShell first
    val = _run_cmd([
        "powershell", "-NoProfile", "-Command",
        "(Get-CimInstance Win32_Processor | Select-Object -First 1).ProcessorId"
    ])
    if val and val != "ProcessorId" and len(val) > 3:
        return val
    # Fallback to wmic
    val = _run_cmd(["wmic", "cpu", "get", "processorid"])
    if val and val.lower() != "processorid":
        return val
    return "unknown-cpu"


def _get_machine_guid():
    """Windows MachineGuid — стабильный ID, не меняется при перезагрузке."""
    if platform.system() != "Windows":
        return "linux-guid"
    val = _run_cmd([
        "powershell", "-NoProfile", "-Command",
        "(Get-ItemProperty 'HKLM:\\SOFTWARE\\Microsoft\\Cryptography' -Name MachineGuid).MachineGuid"
    ])
    if val and len(val) > 10 and val != "MachineGuid":
        return val
    # Fallback: reg query
    val = _run_cmd(["reg", "query", "HKLM\\SOFTWARE\\Microsoft\\Cryptography", "/v", "MachineGuid"])
    if val and "REG_SZ" in val:
        return val.split("REG_SZ")[-1].strip()
    return "unknown-guid"


def generate_hwid() -> str:
    """Генерирует стабильный HWID. Приоритет: MachineGuid > disk+cpu."""
    # MachineGuid — самый стабильный на Windows (включая VPS)
    guid = _get_machine_guid()
    if guid and guid not in ("unknown-guid", "linux-guid"):
        raw = f"{guid}|TELEPUSH"
        return hashlib.sha256(raw.encode()).hexdigest()[:32]

    # Fallback: disk + cpu
    disk = _get_disk_serial()
    cpu = _get_cpu_id()
    raw = f"{disk}|{cpu}|TELEPUSH"
    return hashlib.sha256(raw.encode()).hexdigest()[:32]
