package system

import (
	"os"
	"strconv"
	"strings"
)

type MemoryInfo struct {
	TotalBytes     uint64 `json:"total_bytes" example:"16384000000"`
	AvailableBytes uint64 `json:"available_bytes" example:"8192000000" doc:"Memory available for new allocations without swapping"`
	UsedBytes      uint64 `json:"used_bytes" example:"8192000000" doc:"total - available"`
	SwapTotalBytes uint64 `json:"swap_total_bytes" example:"8589934592"`
	SwapFreeBytes  uint64 `json:"swap_free_bytes" example:"8589934592"`
}

func memInfo() MemoryInfo {
	data, _ := os.ReadFile("/proc/meminfo")
	return parseMeminfo(data)
}

func parseMeminfo(data []byte) MemoryInfo {
	kv := map[string]uint64{}
	for line := range strings.SplitSeq(string(data), "\n") {
		k, v, ok := strings.Cut(line, ":")
		if !ok {
			continue
		}
		fields := strings.Fields(v)
		if len(fields) == 0 {
			continue
		}
		if n, err := strconv.ParseUint(fields[0], 10, 64); err == nil {
			kv[k] = n * 1024
		}
	}
	return MemoryInfo{
		TotalBytes:     kv["MemTotal"],
		AvailableBytes: kv["MemAvailable"],
		UsedBytes:      kv["MemTotal"] - kv["MemAvailable"],
		SwapTotalBytes: kv["SwapTotal"],
		SwapFreeBytes:  kv["SwapFree"],
	}
}
