"""بصمة العتاد وكشف الأجهزة الافتراضية — تربط النسخة بالجهاز الفعلي.

تُقرأ معرّفات المضيف عبر مسارات مُركّبة read-only في حاوية الوكيل:
  /host/machine-id      ← /etc/machine-id
  /host/dmi/*           ← /sys/class/dmi/id  (product_uuid, board_serial, sys_vendor…)
  /proc/cpuinfo         ← متاح للحاوية ويعكس معالج المضيف (علم hypervisor)

سقف معروف (ponytail): من يملك root على العتاد يستطيع تركيب مسارات مزيّفة.
الحماية الحقيقية سحابية (البوابة ترفض بصمة غير معتمدة) + كون الجهاز appliance نملكه.
"""

import hashlib

VM_MARKERS = [
    "vmware", "virtualbox", "innotek", "qemu", "kvm", "xen", "bochs",
    "parallels", "hyper-v", "microsoft corporation", "virtual machine",
    "google", "amazon ec2", "openstack", "bhyve", "utm", "apple virtualization",
]


def _read(path: str, limit: int = 256) -> str:
    try:
        with open(path, encoding="utf-8", errors="ignore") as f:
            return f.read(limit).strip()
    except OSError:
        return ""


def _cpu() -> tuple[str, int, bool]:
    """(اسم المعالج، عدد الأنوية المنطقية، هل علم hypervisor موجود)."""
    model, count, hyper = "", 0, False
    for line in _read("/proc/cpuinfo", 65536).splitlines():
        if line.startswith("model name") and not model:
            model = line.split(":", 1)[-1].strip()
        elif line.startswith("processor"):
            count += 1
        elif line.startswith("flags") and "hypervisor" in line:
            hyper = True
    return model, count, hyper


def _hw(env_key: str, *paths: str) -> str:
    """قيمة العتاد: من env (يمرّرها install.sh) أولاً، ثم من مسار مُركّب (نمط dev)."""
    import os
    v = os.environ.get(env_key)
    if v:
        return v.strip()
    for p in paths:
        v = _read(p)
        if v:
            return v
    return ""


def collect() -> dict:
    """يجمع معرّفات العتاد + كشف VM. يُرجع dict يشمل fingerprint و hardware_info و is_vm.

    المصدر: env (VEEDON_HW_*) يكتبها install.sh من مضيف الجهاز — أدق وأأمن من تركيب
    /sys في الحاوية؛ وإلا يقرأ من مسارات /host/* المركّبة (بيئة dev).
    """
    machine_id = _hw("VEEDON_HW_MACHINE_ID", "/host/machine-id", "/etc/machine-id")
    product_uuid = _hw("VEEDON_HW_UUID", "/host/dmi/product_uuid")
    board_serial = _hw("VEEDON_HW_SERIAL", "/host/dmi/board_serial")
    product_serial = _hw("VEEDON_HW_PRODUCT_SERIAL", "/host/dmi/product_serial")
    sys_vendor = _hw("VEEDON_HW_VENDOR", "/host/dmi/sys_vendor")
    product_name = _hw("VEEDON_HW_MODEL", "/host/dmi/product_name")
    cpu_model, cpu_count, cpu_hyper = _cpu()

    # البصمة: معرّفات مستقرة لا تتغير بإعادة التثبيت على نفس اللوحة
    seed = "|".join([machine_id, product_uuid, board_serial, product_serial,
                     cpu_model, str(cpu_count)])
    fingerprint = hashlib.sha256(seed.encode()).hexdigest()

    vendor_blob = f"{sys_vendor} {product_name}".lower()
    is_vm = cpu_hyper or any(m in vendor_blob for m in VM_MARKERS)

    hardware_info = {
        "manufacturer": sys_vendor,
        "model": product_name,
        "cpu": cpu_model,
        "cpu_cores": cpu_count,
        "product_uuid": product_uuid[:18] + "…" if product_uuid else "",
        "board_serial": board_serial,
        "hostname": _read("/host/hostname") or _read("/etc/hostname"),
        "vm_detected": is_vm,
        "vm_reason": "hypervisor-flag" if cpu_hyper else (
            next((m for m in VM_MARKERS if m in vendor_blob), "") if is_vm else ""),
    }
    return {"fingerprint": fingerprint, "hardware_info": hardware_info, "is_vm": is_vm}


if __name__ == "__main__":  # self-check: بصمة ثابتة + كشف علم hypervisor
    import json
    a, b = collect(), collect()
    assert a["fingerprint"] == b["fingerprint"], "fingerprint must be stable"
    assert len(a["fingerprint"]) == 64
    assert isinstance(a["is_vm"], bool)
    print(json.dumps(a, ensure_ascii=False, indent=2))
