//go:build windows

package handlers

import (
	"syscall"
	"unsafe"
)

type memoryStatusEx struct {
	dwLength                uint32
	dwMemoryLoad            uint32
	ullTotalPhys            uint64
	ullAvailPhys            uint64
	ullTotalPageFile        uint64
	ullAvailPageFile        uint64
	ullTotalVirtual         uint64
	ullAvailVirtual         uint64
	ullAvailExtendedVirtual uint64
}

func getSysMemMb() (total, free int64) {
	kernel32 := syscall.NewLazyDLL("kernel32.dll")
	proc := kernel32.NewProc("GlobalMemoryStatusEx")
	var ms memoryStatusEx
	ms.dwLength = uint32(unsafe.Sizeof(ms))
	ret, _, _ := proc.Call(uintptr(unsafe.Pointer(&ms)))
	if ret == 0 {
		return 0, 0
	}
	return int64(ms.ullTotalPhys / 1024 / 1024), int64(ms.ullAvailPhys / 1024 / 1024)
}

func getOSRelease() string {
	k, err := syscall.UTF16PtrFromString(`SOFTWARE\Microsoft\Windows NT\CurrentVersion`)
	if err != nil {
		return "Windows"
	}
	var handle syscall.Handle
	if err := syscall.RegOpenKeyEx(syscall.HKEY_LOCAL_MACHINE, k, 0, syscall.KEY_READ, &handle); err != nil {
		return "Windows"
	}
	defer syscall.RegCloseKey(handle)

	readStr := func(name string) string {
		namePtr, _ := syscall.UTF16PtrFromString(name)
		var typ uint32
		var buf [256]uint16
		n := uint32(len(buf) * 2)
		if err := syscall.RegQueryValueEx(handle, namePtr, nil, &typ, (*byte)(unsafe.Pointer(&buf[0])), &n); err != nil {
			return ""
		}
		return syscall.UTF16ToString(buf[:])
	}

	productName := readStr("ProductName")
	displayVersion := readStr("DisplayVersion")
	if displayVersion == "" {
		displayVersion = readStr("ReleaseId")
	}
	if productName == "" {
		return "Windows"
	}
	if displayVersion != "" {
		return productName + " " + displayVersion
	}
	return productName
}
