package cn.reghao.bnt.common.machine;

import cn.reghao.bnt.common.machine.model.NetworkCard;
import cn.reghao.jutil.jdk.converter.ByteConverter;
import cn.reghao.jutil.jdk.machine.data.MachineData;
import cn.reghao.jutil.jdk.machine.data.detail.NetworkDetail;
import cn.reghao.jutil.jdk.machine.data.stat.NetworkStat;
import oshi.SystemInfo;
import oshi.hardware.HardwareAbstractionLayer;
import oshi.software.os.OperatingSystem;

import java.net.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;

/**
 * @author reghao
 * @date 2021-10-16 18:45:39
 */
public class Network implements MachineData<List<NetworkDetail>, NetworkStat> {
    private final HardwareAbstractionLayer hal;
    private OperatingSystem os;
    private final ByteConverter byteConverter;

    public Network(SystemInfo si, ByteConverter byteConverter) {
        this.hal = si.getHardware();
        this.os = si.getOperatingSystem();
        this.byteConverter = byteConverter;
    }

    @Override
    public List<NetworkDetail> detail() {
        List<NetworkDetail> list = new ArrayList<>();
        try {
            Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
            // 遍历主机的网络接口
            while (interfaces.hasMoreElements()) {
                NetworkInterface iface = interfaces.nextElement();
                String ifaceName = iface.getName();
                // 过滤掉 localhost 和虚拟网卡
                if (ifaceName.startsWith("enp")
                        || ifaceName.startsWith("wlp")
                        || ifaceName.startsWith("eth")
                        || ifaceName.startsWith("wlan")
                        || ifaceName.startsWith("em")) {
                    String ifaceMac = macAddr(iface.getHardwareAddress());
                    NetworkDetail networkDetail = new NetworkDetail(ifaceName, ifaceMac);

                    Enumeration<InetAddress> inetAddrs = iface.getInetAddresses();
                    while (inetAddrs.hasMoreElements()) {
                        InetAddress address = inetAddrs.nextElement();
                        if (!address.isLoopbackAddress()) {
                            if (address instanceof Inet4Address) {
                                networkDetail.setIpv4(address.getHostAddress());
                            } else if (address instanceof Inet6Address) {
                                networkDetail.setIpv6(address.getHostAddress());
                            }
                        }
                    }

                    list.add(networkDetail);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }

    /**
     * 返回 52-54-00-bf-ab-2d 格式的 MAC 地址
     *
     * @param
     * @return
     * @date 2020-10-14 下午1:53
     */
    private static String macAddr(byte[] addr) {
        String[] hexadecimal = new String[addr.length];
        for (int i = 0; i < addr.length; i++) {
            hexadecimal[i] = String.format("%02x", addr[i]);
        }
        return String.join("-", hexadecimal);
    }

    @Override
    public NetworkStat stat() {
        return null;
    }

    public List<NetworkCard> getNetworkCards() {
        List<NetworkCard> list = new ArrayList<>();
        hal.getNetworkIFs().forEach(net -> {
            String iface = net.getName();
            String mac = net.getMacaddr();
            String ipv4 = Arrays.toString(net.getIPv4addr());
            String ipv6 = Arrays.toString(net.getIPv6addr());
            long mtu = net.getMTU();
            long speed = net.getSpeed();
            String speedStr = byteConverter.convert(speed);
            list.add(new NetworkCard(iface, mac, ipv4, ipv6, mtu, speed, speedStr));
        });

        return list;
    }
}
