package com.qmth.boot.tools.device;

import com.qmth.boot.tools.device.entity.*;
import com.qmth.boot.tools.models.ByteArray;
import org.apache.commons.lang3.StringUtils;
import oshi.SystemInfo;
import oshi.hardware.HWDiskStore;
import oshi.hardware.HardwareAbstractionLayer;
import oshi.hardware.NetworkIF;

import java.util.ArrayList;
import java.util.List;

/**
 * 设备信息描述对象
 */
public class DeviceInfo {

    private static DeviceInfo current;

    private Computer computer;

    private Baseboard baseboard;

    private DiskStore diskStore;

    private Processor processor;

    private NetworkInterface networkInterface;

    public DeviceInfo() {
        computer = new Computer();
        baseboard = new Baseboard();
        processor = new Processor();
        diskStore = new DiskStore();
        networkInterface = new NetworkInterface();
    }

    /**
     * 获取当前设备信息
     *
     * @return
     */
    public static DeviceInfo current() {
        if (current == null) {
            current = new DeviceInfo();
            HardwareAbstractionLayer hardware = new SystemInfo().getHardware();
            //computer
            current.computer.setManufacturer(hardware.getComputerSystem().getManufacturer());
            current.computer.setModel(hardware.getComputerSystem().getModel());
            current.computer.setSerialNumber(hardware.getComputerSystem().getSerialNumber());
            //baseboard
            current.baseboard.setManufacturer(hardware.getComputerSystem().getBaseboard().getManufacturer());
            current.baseboard.setModel(hardware.getComputerSystem().getBaseboard().getModel());
            current.baseboard.setVersion(hardware.getComputerSystem().getBaseboard().getVersion());
            current.baseboard.setSerialNumber(hardware.getComputerSystem().getBaseboard().getSerialNumber());
            //processor
            current.processor.setIdentifier(hardware.getProcessor().getProcessorIdentifier().getIdentifier());
            current.processor.setId(hardware.getProcessor().getProcessorIdentifier().getProcessorID());
            current.processor.setPhysicalCount(hardware.getProcessor().getPhysicalProcessorCount());
            //diskstore
            current.diskStore.setSerials(
                    hardware.getDiskStores().stream().map(HWDiskStore::getSerial).distinct().sorted()
                            .toArray(String[]::new));
            //networkinterface
            current.networkInterface.setMacAddress(
                    hardware.getNetworkIFs().stream().map(NetworkIF::getMacaddr).filter(addr -> addr.length() == 17)
                            .distinct().sorted().toArray(String[]::new));
        }
        return current;
    }

    /**
     * 构造设备唯一标识，格式为长度32的字符串
     *
     * @return
     */
    public String uuid() {
        List<String> list = new ArrayList<>();
        list.add("computer.serialNumber=" + StringUtils.trimToEmpty(computer.getSerialNumber()));
        list.add("baseboard.serialNumber=" + StringUtils.trimToEmpty(baseboard.getSerialNumber()));
        list.add("processor.id=" + StringUtils.trimToEmpty(processor.getId()));
        //list.add("diskStore.serials=" + StringUtils.trimToEmpty(StringUtils.join(diskStore.getSerials(), ",")));
        list.add("networkInterface.macAddress=" + StringUtils
                .trimToEmpty(StringUtils.join(networkInterface.getMacAddress(), ",")));
        return ByteArray.md5(StringUtils.join(list, "\n")).toHexString();
    }

    public Computer getComputer() {
        return computer;
    }

    public Baseboard getBaseboard() {
        return baseboard;
    }

    public DiskStore getDiskStore() {
        return diskStore;
    }

    public Processor getProcessor() {
        return processor;
    }

    public NetworkInterface getNetworkInterface() {
        return networkInterface;
    }
}
