//go:build windows

package proc

import (
	"fmt"
	"time"

	"golang.org/x/sys/windows"
)

func processByPIDNative(pid int) (ProcessInfo, bool) {
	if pid <= 0 || uint64(pid) > uint64(^uint32(0)) {
		return ProcessInfo{}, false
	}
	handle, err := windows.OpenProcess(windows.PROCESS_QUERY_LIMITED_INFORMATION, false, uint32(pid))
	if err != nil {
		return ProcessInfo{}, false
	}
	defer windows.CloseHandle(handle)

	startedAt, err := ProcessStartedAt(handle)
	if err != nil {
		return ProcessInfo{}, false
	}
	return ProcessInfo{PID: pid, StartedAt: startedAt}, true
}

// ProcessStartedAt returns the native creation time for an already-open
// process handle so callers can inspect multiple identity fields atomically
// with respect to PID reuse.
func ProcessStartedAt(handle windows.Handle) (time.Time, error) {
	var createdAt, exitedAt, kernelTime, userTime windows.Filetime
	if err := windows.GetProcessTimes(handle, &createdAt, &exitedAt, &kernelTime, &userTime); err != nil {
		return time.Time{}, fmt.Errorf("get process times: %w", err)
	}
	startedAt := filetimeToTime(createdAt)
	if startedAt.IsZero() {
		return time.Time{}, fmt.Errorf("process creation time is zero")
	}
	return startedAt, nil
}

func filetimeToTime(filetime windows.Filetime) time.Time {
	return time.Unix(0, filetime.Nanoseconds()).UTC()
}
