package host_info

import (
	"agent-wdd/log"
	"agent-wdd/utils"
	"os"
	"os/exec"
	"strconv"
	"strings"
)

func (mem *Memory) Gather() {
	// 获取内存总大小
	data, err := os.ReadFile("/proc/meminfo")
	if err != nil {
		mem.Size = "0B"
		mem.Type = ""
		mem.Speed = 0
		return
	}
	lines := strings.Split(string(data), "\n")
	//var totalKB uint64
	for _, line := range lines {
		if strings.HasPrefix(line, "MemTotal:") {
			fields := strings.Fields(line)
			if len(fields) >= 3 {
				kb, err := strconv.ParseUint(fields[1], 10, 64)
				if err != nil {
					mem.Size = "0B"
				} else {
					mem.Size = utils.HumanSize(kb * 1024)
				}
				break
			}
		}
	}
	// 获取Type和Speed
	mem.Type, mem.Speed = getMemoryTypeAndSpeed()
}

func getMemoryTypeAndSpeed() (string, int) {
	cmd := exec.Command("dmidecode", "-t", "memory")
	output, err := cmd.CombinedOutput()
	if err != nil {
		return "", 0
	}
	var memType string
	var speed int
	lines := strings.Split(string(output), "\n")
	for _, line := range lines {
		trimmed := strings.TrimSpace(line)
		if strings.HasPrefix(trimmed, "Type:") {
			parts := strings.SplitN(trimmed, ":", 2)
			if len(parts) == 2 {
				memType = strings.TrimSpace(parts[1])
				// 可能dmidecode返回的类型中有更多细节，例如"DDR4"或其他
				// 例如，如果类型是"Unknown"，可能需要处理
				if memType == "Unknown" || memType == "Other" {
					memType = ""
				}
			}
		} else if strings.HasPrefix(trimmed, "Speed:") {
			parts := strings.SplitN(trimmed, ":", 2)
			if len(parts) == 2 {
				speedStr := strings.TrimSpace(parts[1])
				// 可能的格式如 "2667 MHz" 或 "Unknown"
				if speedStr == "Unknown" {
					continue
				}
				speedStr = strings.TrimSuffix(speedStr, " MHz")
				s, err := strconv.Atoi(speedStr)
				if err == nil {
					speed = s
				}
			}
		}
	}
	return memType, speed
}

func (mem *Memory) SaveConfig() {
	log.Info("Saving INFO => MEM !")

	ConfigCache.Agent.Mem = *mem
	SaveConfig()
}

func (swap *Swap) Gather() {

	log.Info("Gathering INFO => SWAP !")

	const swapsFile = "/proc/swaps"
	data, err := os.ReadFile(swapsFile)
	if err != nil {
		swap.Open = false
		swap.Size = "0B"
		return
	}

	lines := strings.Split(strings.TrimSpace(string(data)), "\n")
	if len(lines) < 2 { // 空文件或只有标题行
		swap.Open = false
		swap.Size = "0B"
		return
	}

	var totalKB uint64
	for _, line := range lines[1:] {
		line = strings.TrimSpace(line)
		if line == "" {
			continue
		}

		fields := strings.Fields(line)
		if len(fields) < 3 {
			continue
		}

		sizeKB, err := strconv.ParseUint(fields[2], 10, 64)
		if err != nil {
			continue
		}
		totalKB += sizeKB
	}

	if totalKB == 0 {
		swap.Open = false
		swap.Size = "0B"
	} else {
		swap.Open = true
		swap.Size = utils.HumanSize(totalKB * 1024)
	}
}

func (swap *Swap) SaveConfig() {
	log.Info("Saving INFO => SWAP !")

	ConfigCache.Agent.Swap = *swap
	SaveConfig()
}
