package cn.reghao.bnt.common.machine;

import cn.reghao.bnt.common.msg.event.EvtAgentHeartbeat;
import cn.reghao.bnt.common.msg.event.EvtAgentStart;
import cn.reghao.jutil.jdk.converter.ByteConverter;
import cn.reghao.jutil.jdk.machine.data.detail.*;
import cn.reghao.jutil.jdk.machine.id.MachineId;
import cn.reghao.jutil.jdk.machine.id.MachineIdLinux;
import cn.reghao.jutil.jdk.web.result.AppVersion;
import oshi.SystemInfo;
import oshi.hardware.HardwareAbstractionLayer;
import oshi.software.os.OperatingSystem;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author reghao
 * @date 2020-10-22 15:47:58
 */
public class Machine {
    public final static String ID;
    public final static String IPV4;
    static {
        MachineId machineId = new MachineIdLinux();
        ID = machineId.id();
        // TODO ip 发生变化时会引发数据不一致
        IPV4 = machineId.ipv4();
    }

    private final CPU cpu;
    private final Memory memory;
    private final Disk disk;
    private final Network network;
    private final OS os;

    public Machine() {
        ByteConverter byteConverter = new ByteConverter();
        SystemInfo si = new SystemInfo();
        HardwareAbstractionLayer hal = si.getHardware();
        OperatingSystem operatingSystem = si.getOperatingSystem();

        this.cpu = new CPU(si);
        this.memory = new Memory(si, byteConverter);
        this.disk = new Disk(si, byteConverter);
        this.network = new Network(si, byteConverter);
        this.os = new OS(si, byteConverter);
    }

    public EvtAgentStart detail() {
        EvtAgentStart machineDetail = new EvtAgentStart();
        machineDetail.setMachineId(Machine.ID);
        machineDetail.setAppVersion(AppVersion.getVersion());

        machineDetail.setOsDetail(os.detail());
        List<NetworkDetail> list = network.detail().stream()
                .peek(networkDetail -> {
                    networkDetail.setPubicIpv4("0.0.0.0");
                })
                .collect(Collectors.toList());
        machineDetail.setNetworkDetails(list);

        machineDetail.setCpuDetail(cpu.detail());
        machineDetail.setMemoryDetail(memory.detail());
        machineDetail.setDiskDetails(disk.detail());
        return machineDetail;
    }

    public EvtAgentHeartbeat stat() {
        EvtAgentHeartbeat machineStat = new EvtAgentHeartbeat();
        machineStat.setMachineId(Machine.ID);
        machineStat.setMemoryDetail(memory.detail());
        machineStat.setDiskDetails(disk.detail());
        return machineStat;
    }
}
