import hashlib
import platform
import uuid

import wmi


class Hardware:
    machine_code = None

    @classmethod
    def _get_system_info(cls):
        """获取系统名称"""
        system_info = platform.uname()
        return system_info.node

    @classmethod
    def _get_cpu_info(cls):
        """获取CPU信息(弃用，耗时过长)"""
        c = wmi.WMI()
        info = ''
        for cpu in c.Win32_Processor():
            res = str(cpu.SerialNumber)
            info += res
        return info

    @classmethod
    def _get_board_info(cls):
        """获取主板信息"""
        c = wmi.WMI()
        info = ""
        for board in c.Win32_BaseBoard():
            res = str(board.SerialNumber)
            info += res
        return info

    @classmethod
    def _get_bios_info(cls):
        """获取BIOS信息"""
        c = wmi.WMI()
        info = ""
        for bios in c.Win32_BIOS():
            res = str(bios.SerialNumber)
            info += res
        return info

    @classmethod
    def _get_disk_info(cls):
        """获取硬盘信息"""
        c = wmi.WMI()
        info = ""
        for disk in c.Win32_DiskDrive():
            res = str(disk.SerialNumber)
            info += res
        return info

    @classmethod
    def _pwd_to_sha256(cls, password, salt: str):
        """哈希加密"""
        sha = hashlib.sha256()
        sha.update(password.encode('utf-8'))
        sha.update(salt.encode('gbk'))
        return sha.hexdigest()

    @classmethod
    def generate_machine_code(cls):
        """生成机器码"""
        if cls.machine_code:
            return True, cls.machine_code
        try:
            info_list = [cls._get_system_info(),
                         cls._get_board_info(),
                         cls._get_bios_info(),
                         cls._get_disk_info()
                         ]
        except Exception as e:
            print(e)
            return False, None

        combined_info = "-".join(info_list)
        code_temp = cls._pwd_to_sha256(combined_info, 'qingmagooki')
        code = code_temp[::2]
        cls.machine_code = code

        return True, code

    @classmethod
    def get_machine_code(cls):
        ok, code = cls.generate_machine_code()
        if not ok:
            return uuid.getnode()
        return code
