// Copyright 2019 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package prometheus

import (
	"syscall"
	"unsafe"

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

func canCollectProcess() bool {
	return true
}

var (
	modpsapi    = syscall.NewLazyDLL("psapi.dll")
	modkernel32 = syscall.NewLazyDLL("kernel32.dll")

	procGetProcessMemoryInfo  = modpsapi.NewProc("GetProcessMemoryInfo")
	procGetProcessHandleCount = modkernel32.NewProc("GetProcessHandleCount")
)

type processMemoryCounters struct {
	// System interface description
	// https://docs.microsoft.com/en-us/windows/desktop/api/psapi/ns-psapi-process_memory_counters_ex

	// Refer to the Golang internal implementation
	// https://golang.org/src/internal/syscall/windows/psapi_windows.go
	_                          uint32
	PageFaultCount             uint32
	PeakWorkingSetSize         uintptr
	WorkingSetSize             uintptr
	QuotaPeakPagedPoolUsage    uintptr
	QuotaPagedPoolUsage        uintptr
	QuotaPeakNonPagedPoolUsage uintptr
	QuotaNonPagedPoolUsage     uintptr
	PagefileUsage              uintptr
	PeakPagefileUsage          uintptr
	PrivateUsage               uintptr
}

func getProcessMemoryInfo(handle windows.Handle) (processMemoryCounters, error) {
	mem := processMemoryCounters{}
	r1, _, err := procGetProcessMemoryInfo.Call(
		uintptr(handle),
		uintptr(unsafe.Pointer(&mem)),
		uintptr(unsafe.Sizeof(mem)),
	)
	if r1 != 1 {
		return mem, err
	} else {
		return mem, nil
	}
}

func getProcessHandleCount(handle windows.Handle) (uint32, error) {
	var count uint32
	r1, _, err := procGetProcessHandleCount.Call(
		uintptr(handle),
		uintptr(unsafe.Pointer(&count)),
	)
	if r1 != 1 {
		return 0, err
	} else {
		return count, nil
	}
}

func (c *processCollector) processCollect(ch chan<- Metric) {
	h, err := windows.GetCurrentProcess()
	if err != nil {
		c.reportError(ch, nil, err)
		return
	}

	var startTime, exitTime, kernelTime, userTime windows.Filetime
	err = windows.GetProcessTimes(h, &startTime, &exitTime, &kernelTime, &userTime)
	if err != nil {
		c.reportError(ch, nil, err)
		return
	}
	ch <- MustNewConstMetric(c.startTime, GaugeValue, float64(startTime.Nanoseconds()/1e9))
	ch <- MustNewConstMetric(c.cpuTotal, CounterValue, fileTimeToSeconds(kernelTime)+fileTimeToSeconds(userTime))

	mem, err := getProcessMemoryInfo(h)
	if err != nil {
		c.reportError(ch, nil, err)
		return
	}
	ch <- MustNewConstMetric(c.vsize, GaugeValue, float64(mem.PrivateUsage))
	ch <- MustNewConstMetric(c.rss, GaugeValue, float64(mem.WorkingSetSize))

	handles, err := getProcessHandleCount(h)
	if err != nil {
		c.reportError(ch, nil, err)
		return
	}
	ch <- MustNewConstMetric(c.openFDs, GaugeValue, float64(handles))
	ch <- MustNewConstMetric(c.maxFDs, GaugeValue, float64(16*1024*1024)) // Windows has a hard-coded max limit, not per-process.
}

func fileTimeToSeconds(ft windows.Filetime) float64 {
	return float64(uint64(ft.HighDateTime)<<32+uint64(ft.LowDateTime)) / 1e7
}
