package systeminfo

import (
	"context"
	"runtime"
	"time"

	"kra/internal/biz/system"

	"github.com/shirou/gopsutil/v4/cpu"
	"github.com/shirou/gopsutil/v4/disk"
	"github.com/shirou/gopsutil/v4/mem"
)

type Provider struct{}

func NewProvider() *Provider { return &Provider{} }

func (*Provider) Collect(ctx context.Context, mountPoints []string) (*system.ServerInfo, error) {
	if ctx == nil {
		ctx = context.Background()
	}
	if err := ctx.Err(); err != nil {
		return nil, err
	}
	physicalCores, err := cpu.Counts(false)
	if err != nil {
		return nil, err
	}
	cpuPercent, err := cpu.PercentWithContext(ctx, 200*time.Millisecond, true)
	if err != nil {
		return nil, err
	}
	memory, err := mem.VirtualMemoryWithContext(ctx)
	if err != nil {
		return nil, err
	}
	diskInfo := make([]system.ServerDiskInfo, 0, len(mountPoints))
	for _, mountPoint := range mountPoints {
		if err = ctx.Err(); err != nil {
			return nil, err
		}
		usage, usageErr := disk.UsageWithContext(ctx, mountPoint)
		if usageErr != nil {
			return nil, usageErr
		}
		diskInfo = append(diskInfo, system.ServerDiskInfo{MountPoint: mountPoint, UsedMB: usage.Used / 1024 / 1024, UsedGB: usage.Used / 1024 / 1024 / 1024, TotalMB: usage.Total / 1024 / 1024, TotalGB: usage.Total / 1024 / 1024 / 1024, UsedPercent: int(usage.UsedPercent)})
	}
	return &system.ServerInfo{GOOS: runtime.GOOS, NumCPU: runtime.NumCPU(), Compiler: runtime.Compiler, GoVersion: runtime.Version(), NumGoroutine: runtime.NumGoroutine(), CPUs: cpuPercent, Cores: physicalCores, UsedMB: memory.Used / 1024 / 1024, TotalMB: memory.Total / 1024 / 1024, UsedPercent: int(memory.UsedPercent), Disk: diskInfo}, nil
}
