package cn.reghao.autodop.common.machine;

import cn.reghao.jdkutil.text.TextFile;
import lombok.Data;

import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 内存
 *
 * @author reghao
 * @date 2019-10-25 13:21:25
 */
public class Memory {
    private final TextFile textFile;

    public Memory(TextFile textFile) {
        this.textFile = textFile;
    }

    public MemoryDetail detail() {
        Map<String, String> map = parseMemInfo();
        long total = Long.parseLong(map.get("MemTotal").split("kB")[0]);
        long free = Long.parseLong(map.get("MemFree").split("kB")[0]);
        long shared = Long.parseLong(map.get("Shmem").split("kB")[0]);
        long buffers = Long.parseLong(map.get("Buffers").split("kB")[0]);
        long cached = Long.parseLong(map.get("Cached").split("kB")[0]) +
                Long.parseLong(map.get("SReclaimable").split("kB")[0]);
        long buffCache = buffers + cached;
        long available = Long.parseLong(map.get("MemAvailable").split("kB")[0]);
        long used = total - free - buffCache;

        long swapTotal = Long.parseLong(map.get("SwapTotal").split("kB")[0]);
        long swapUnused = Long.parseLong(map.get("SwapFree").split("kB")[0]);
        long swapUsed = swapTotal - swapUnused;

        MemoryDetail memoryInfo = new MemoryDetail();
        memoryInfo.setTotal(total);
        memoryInfo.setUsed(used);
        memoryInfo.setFree(free);
        memoryInfo.setShared(shared);
        memoryInfo.setBuffCache(buffCache);
        memoryInfo.setAvailable(available);

        memoryInfo.setSwapTotal(total);
        memoryInfo.setSwapUsed(swapUsed);
        memoryInfo.setSwapFree(swapUnused);
        return memoryInfo;
    }

    private Map<String, String> parseMemInfo() {
        String info = textFile.readFile(LinuxProc.MEM_INFO);
        Map<String, String> map = new LinkedHashMap<>();
        for (String line : info.split(System.lineSeparator())) {
            String[] strs = line.replace("\t", "").split(":");
            map.put(strs[0], strs[1].replace(" ", ""));
        }
        return map;
    }

    @Data
    public static class MemoryDetail implements Serializable {
        private static final long serialVersionUID = 1L;

        // KiB
        private long total;
        private long used;
        private long free;
        private long shared;
        private long buffCache;
        private long available;
        private long swapTotal;
        private long swapUsed;
        private long swapFree;
    }
}
