package cn.reghao.devops.common.machine;

import cn.reghao.jutil.jdk.machine.data.MachineData;
import cn.reghao.jutil.jdk.machine.data.detail.DiskDetail;
import cn.reghao.jutil.jdk.machine.data.stat.DiskStat;
import oshi.SystemInfo;
import oshi.software.os.OperatingSystem;

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

/**
 * @author reghao
 * @date 2019-10-25 13:21:25
 */
public class Disk implements MachineData<List<DiskDetail>, List<DiskStat>> {
    private final OperatingSystem os;

    public Disk(SystemInfo si) {
        this.os = si.getOperatingSystem();
        //this.os = new SystemInfo().getOperatingSystem();
    }

    @Override
    public List<DiskDetail> detail() {
        return os.getFileSystem().getFileStores().stream()
                .filter(osFileStore -> osFileStore.getVolume().startsWith("/dev/"))
                .map(osFileStore -> {
                    String vol = osFileStore.getVolume();
                    String mount = osFileStore.getMount();
                    String fsType = osFileStore.getType();

                    long total = osFileStore.getTotalSpace();
                    // non-root 用户可用的磁盘空间
                    long userAvail = osFileStore.getUsableSpace();
                    // root 用户可用的磁盘空间
                    long rootAvail = osFileStore.getFreeSpace();

                    long inodeTotal = osFileStore.getTotalInodes();
                    long inodeFree = osFileStore.getFreeInodes();

                    return new DiskDetail(vol, mount, fsType, total, userAvail, total-userAvail, inodeTotal, inodeFree);
                })
                .collect(Collectors.toList());
    }

    @Override
    public List<DiskStat> stat() {
        return null;
    }

    /**
     * 根据一个路径确定它所在的分区
     *
     * @param
     * @return
     * @date 2021-02-06 下午11:25
     */
    public DiskDetail diskDetail(String path) {
        List<DiskDetail> diskInfos = detail();
        // 根据挂载路径的长度降序
        diskInfos.sort((o1, o2) -> o2.getMountedOn().length() - o1.getMountedOn().length());

        List<DiskDetail> candidates = new ArrayList<>();
        for (DiskDetail diskInfo : diskInfos) {
            String mountedOn = diskInfo.getMountedOn();
            String[] array = path.split(mountedOn);
            if (array.length == 0) {
                return diskInfo;
            } else if (array.length == 2) {
                if (array[1].startsWith("/") || "/".equals(mountedOn)) {
                    candidates.add(diskInfo);
                }
            } else if (array.length > 2) {
                candidates.add(diskInfo);
            }
        }

        if (!candidates.isEmpty()) {
            // TODO 如果 candidates 大于 0 则判断准确的那个
            return candidates.get(0);
        } else {
            return null;
        }
    }
}
