// Copyright 2018 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 procfs

import (
	"bufio"
	"fmt"
	"os"
	"regexp"
	"strconv"
)

// ProcLimits represents the soft limits for each of the process's resource
// limits. For more information see getrlimit(2):
// http://man7.org/linux/man-pages/man2/getrlimit.2.html.
type ProcLimits struct {
	// CPU time limit in seconds.
	CPUTime uint64
	// Maximum size of files that the process may create.
	FileSize uint64
	// Maximum size of the process's data segment (initialized data,
	// uninitialized data, and heap).
	DataSize uint64
	// Maximum size of the process stack in bytes.
	StackSize uint64
	// Maximum size of a core file.
	CoreFileSize uint64
	// Limit of the process's resident set in pages.
	ResidentSet uint64
	// Maximum number of processes that can be created for the real user ID of
	// the calling process.
	Processes uint64
	// Value one greater than the maximum file descriptor number that can be
	// opened by this process.
	OpenFiles uint64
	// Maximum number of bytes of memory that may be locked into RAM.
	LockedMemory uint64
	// Maximum size of the process's virtual memory address space in bytes.
	AddressSpace uint64
	// Limit on the combined number of flock(2) locks and fcntl(2) leases that
	// this process may establish.
	FileLocks uint64
	// Limit of signals that may be queued for the real user ID of the calling
	// process.
	PendingSignals uint64
	// Limit on the number of bytes that can be allocated for POSIX message
	// queues for the real user ID of the calling process.
	MsqqueueSize uint64
	// Limit of the nice priority set using setpriority(2) or nice(2).
	NicePriority uint64
	// Limit of the real-time priority set using sched_setscheduler(2) or
	// sched_setparam(2).
	RealtimePriority uint64
	// Limit (in microseconds) on the amount of CPU time that a process
	// scheduled under a real-time scheduling policy may consume without making
	// a blocking system call.
	RealtimeTimeout uint64
}

const (
	limitsFields    = 4
	limitsUnlimited = "unlimited"
)

var (
	limitsMatch = regexp.MustCompile(`(Max \w+\s{0,1}?\w*\s{0,1}\w*)\s{2,}(\w+)\s+(\w+)`)
)

// NewLimits returns the current soft limits of the process.
//
// Deprecated: Use p.Limits() instead.
func (p Proc) NewLimits() (ProcLimits, error) {
	return p.Limits()
}

// Limits returns the current soft limits of the process.
func (p Proc) Limits() (ProcLimits, error) {
	f, err := os.Open(p.path("limits"))
	if err != nil {
		return ProcLimits{}, err
	}
	defer f.Close()

	var (
		l = ProcLimits{}
		s = bufio.NewScanner(f)
	)

	s.Scan() // Skip limits header

	for s.Scan() {
		//fields := limitsMatch.Split(s.Text(), limitsFields)
		fields := limitsMatch.FindStringSubmatch(s.Text())
		if len(fields) != limitsFields {
			return ProcLimits{}, fmt.Errorf("couldn't parse %q line %q", f.Name(), s.Text())
		}

		switch fields[1] {
		case "Max cpu time":
			l.CPUTime, err = parseUint(fields[2])
		case "Max file size":
			l.FileSize, err = parseUint(fields[2])
		case "Max data size":
			l.DataSize, err = parseUint(fields[2])
		case "Max stack size":
			l.StackSize, err = parseUint(fields[2])
		case "Max core file size":
			l.CoreFileSize, err = parseUint(fields[2])
		case "Max resident set":
			l.ResidentSet, err = parseUint(fields[2])
		case "Max processes":
			l.Processes, err = parseUint(fields[2])
		case "Max open files":
			l.OpenFiles, err = parseUint(fields[2])
		case "Max locked memory":
			l.LockedMemory, err = parseUint(fields[2])
		case "Max address space":
			l.AddressSpace, err = parseUint(fields[2])
		case "Max file locks":
			l.FileLocks, err = parseUint(fields[2])
		case "Max pending signals":
			l.PendingSignals, err = parseUint(fields[2])
		case "Max msgqueue size":
			l.MsqqueueSize, err = parseUint(fields[2])
		case "Max nice priority":
			l.NicePriority, err = parseUint(fields[2])
		case "Max realtime priority":
			l.RealtimePriority, err = parseUint(fields[2])
		case "Max realtime timeout":
			l.RealtimeTimeout, err = parseUint(fields[2])
		}
		if err != nil {
			return ProcLimits{}, err
		}
	}

	return l, s.Err()
}

func parseUint(s string) (uint64, error) {
	if s == limitsUnlimited {
		return 18446744073709551615, nil
	}
	i, err := strconv.ParseUint(s, 10, 64)
	if err != nil {
		return 0, fmt.Errorf("couldn't parse value %q: %w", s, err)
	}
	return i, nil
}
