package info

import (
	"bufio"
	"fmt"
	"os"
	"runtime"
	"strings"
)

// -------------------------- 编译注入的静态信息 --------------------------
var (
	Version   = "dev"     // 应用版本号
	BuildTime = "unknown" // 编译时间
	GitCommit = "unknown" // Git提交ID
	GitBranch = "unknown" // Git分支
)

// -------------------------- 固定常量 --------------------------
const (
	AppName          = "sunhpc"
	linuxProcVersion = "/proc/version"
	linuxProcCpuinfo = "/proc/cpuinfo"
)

// -------------------------- 系统信息结构体 --------------------------
// SystemInfo 封装所有系统相关信息（Linux专属）
type SystemInfo struct {
	OS            string // 操作系统
	Arch          string // 系统架构
	KernelVersion string // 内核版本
	CPUModel      string // CPU型号
	NumCPU        int    // CPU核心数
	MemTotal      string // 总内存
	Hostname      string // 主机名
	GoVersion     string // Go运行时版本
}

// -------------------------- 通用工具函数（无错误返回） --------------------------
// readFileFirstLine 读取文件第一行，失败返回空字符串
func readFileFirstLine(path string) string {
	file, err := os.Open(path)
	if err != nil {
		return ""
	}
	defer file.Close()

	scanner := bufio.NewScanner(file)
	if scanner.Scan() {
		return strings.TrimSpace(scanner.Text())
	}
	return ""
}

// -------------------------- 核心函数（无错误返回） --------------------------
// readCPUModel 读取CPU型号，失败返回 "unknown"
func readCPUModel() string {
	file, err := os.Open(linuxProcCpuinfo)
	if err != nil {
		return "unknown"
	}
	defer file.Close()

	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		line := strings.TrimSpace(scanner.Text())
		if strings.HasPrefix(line, "model name") {
			parts := strings.SplitN(line, ":", 2)
			if len(parts) == 2 {
				return strings.TrimSpace(parts[1])
			}
		}
	}
	return "unknown"
}

// readMemTotal 读取总内存，失败返回 "unknown"
func readMemTotal() string {
	file, err := os.Open("/proc/meminfo")
	if err != nil {
		return "unknown"
	}
	defer file.Close()

	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		line := strings.TrimSpace(scanner.Text())
		if strings.HasPrefix(line, "MemTotal") {
			parts := strings.Fields(line)
			if len(parts) >= 2 {
				memKB := strings.TrimSuffix(parts[1], "kB")
				var memTotalKB int
				fmt.Sscanf(memKB, "%d", &memTotalKB)
				memTotalMB := memTotalKB / 1024
				return fmt.Sprintf("%d MB", memTotalMB)
			}
		}
	}
	return "unknown"
}

// GetSystemInfo 获取Linux系统信息，无错误返回，异常字段用默认值填充
func GetSystemInfo() SystemInfo {
	// 初始化结构体，先填充基础默认值
	sysInfo := SystemInfo{
		OS:        runtime.GOOS,
		Arch:      runtime.GOARCH,
		NumCPU:    runtime.NumCPU(),
		GoVersion: runtime.Version(),
		// 以下字段先设为默认值，后续尝试覆盖
		KernelVersion: "unknown",
		CPUModel:      "unknown",
		MemTotal:      "unknown",
		Hostname:      "unknown",
	}

	// 1. 获取主机名（失败保留默认值）
	if hostname, err := os.Hostname(); err == nil {
		sysInfo.Hostname = hostname
	}

	// 2. 获取内核版本（失败保留默认值）
	procVersion := readFileFirstLine(linuxProcVersion)
	if procVersion != "" {
		versionParts := strings.Split(procVersion, " ")
		if len(versionParts) >= 3 {
			sysInfo.KernelVersion = versionParts[2]
		} else {
			sysInfo.KernelVersion = procVersion
		}
	}

	// 3. 获取CPU型号（失败已返回 "unknown"）
	sysInfo.CPUModel = readCPUModel()

	// 4. 获取总内存（失败已返回 "unknown"）
	sysInfo.MemTotal = readMemTotal()

	return sysInfo
}

// -------------------------- 辅助函数：打印所有信息 --------------------------
// PrintAllInfo 打印所有公共信息（调试用）
func PrintAllInfo() {
	fmt.Println("=== 应用公共信息 ===")
	fmt.Printf("应用名称  : %s\n", AppName)
	fmt.Printf("版本号    : %s\n", Version)
	fmt.Printf("编译时间  : %s\n", BuildTime)
	fmt.Printf("Git提交ID : %s\n", GitCommit)
	fmt.Printf("Git分支   : %s\n", GitBranch)

	fmt.Println("\n=== 系统信息 ===")
	sysInfo := GetSystemInfo()
	fmt.Printf("操作系统    : %s\n", sysInfo.OS)
	fmt.Printf("系统架构    : %s\n", sysInfo.Arch)
	fmt.Printf("内核版本    : %s\n", sysInfo.KernelVersion)
	fmt.Printf("CPU型号    : %s\n", sysInfo.CPUModel)
	fmt.Printf("CPU核心数  : %d\n", sysInfo.NumCPU)
	fmt.Printf("总内存      : %s\n", sysInfo.MemTotal)
	fmt.Printf("主机名      : %s\n", sysInfo.Hostname)
	fmt.Printf("Go版本      : %s\n", sysInfo.GoVersion)
}
