//go:build linux

package metrics

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

// GetStaticInfo reads host-level static system information.
// Reads from /proc and /etc (which reflect the host in Docker containers).
func GetStaticInfo() StaticSystemInfo {
	info := StaticSystemInfo{}

	// Hostname — try host mount first, fall back to os.Hostname()
	if data, err := os.ReadFile("/host/etc/hostname"); err == nil {
		info.Hostname = strings.TrimSpace(string(data))
	} else {
		info.Hostname, _ = os.Hostname()
	}

	// OS — try host mount first, fall back to container's
	info.OS = readOSRelease("/host/etc/os-release")
	if info.OS == "" {
		info.OS = readOSRelease("/etc/os-release")
	}

	// Kernel version
	if data, err := os.ReadFile("/proc/sys/kernel/osrelease"); err == nil {
		info.Kernel = strings.TrimSpace(string(data))
	}

	// Architecture
	if data, err := os.ReadFile("/proc/sys/kernel/arch"); err == nil {
		info.Architecture = strings.TrimSpace(string(data))
	}
	if info.Architecture == "" {
		// Fallback: use uname -m equivalent from /proc/cpuinfo or runtime
		info.Architecture = runtime.GOARCH
		// Try to get the actual host arch
		if data, err := os.ReadFile("/proc/version"); err == nil {
			v := string(data)
			if strings.Contains(v, "x86_64") {
				info.Architecture = "x86_64"
			} else if strings.Contains(v, "aarch64") {
				info.Architecture = "aarch64"
			}
		}
	}

	// CPU model and cores
	info.CPUModel, info.CPUCores = readCPUInfo()
	if info.CPUCores == 0 {
		info.CPUCores = runtime.NumCPU()
	}

	// Uptime
	if data, err := os.ReadFile("/proc/uptime"); err == nil {
		var uptimeSec float64
		if _, err := fmt.Sscanf(string(data), "%f", &uptimeSec); err == nil {
			info.UptimeSeconds = int64(uptimeSec)
			info.BootTime = time.Now().Add(-time.Duration(info.UptimeSeconds) * time.Second)
		}
	}

	return info
}

// readOSRelease reads PRETTY_NAME from an os-release file.
func readOSRelease(path string) string {
	f, err := os.Open(path)
	if err != nil {
		return ""
	}
	defer f.Close()

	scanner := bufio.NewScanner(f)
	for scanner.Scan() {
		line := scanner.Text()
		if strings.HasPrefix(line, "PRETTY_NAME=") {
			val := strings.TrimPrefix(line, "PRETTY_NAME=")
			val = strings.Trim(val, `"`)
			return val
		}
	}
	return ""
}

// readCPUInfo reads the CPU model name and number of cores from /proc/cpuinfo.
func readCPUInfo() (model string, cores int) {
	f, err := os.Open("/proc/cpuinfo")
	if err != nil {
		return "", 0
	}
	defer f.Close()

	scanner := bufio.NewScanner(f)
	for scanner.Scan() {
		line := scanner.Text()
		if strings.HasPrefix(line, "model name") {
			if idx := strings.Index(line, ":"); idx >= 0 {
				model = strings.TrimSpace(line[idx+1:])
			}
		}
		if strings.HasPrefix(line, "processor") {
			cores++
		}
	}
	return model, cores
}
