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

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

var (
	cpuLineRE  = regexp.MustCompile(`cpu(\d+) (\d+) (\d+) (\d+) (\d+) (\d+) (\d+) (\d+) (\d+) (\d+)`)
	procLineRE = regexp.MustCompile(`(\d+) (\d+) (\d+)`)
)

// Schedstat contains scheduler statistics from /proc/schedstat
//
// See
// https://www.kernel.org/doc/Documentation/scheduler/sched-stats.txt
// for a detailed description of what these numbers mean.
//
// Note the current kernel documentation claims some of the time units are in
// jiffies when they are actually in nanoseconds since 2.6.23 with the
// introduction of CFS. A fix to the documentation is pending. See
// https://lore.kernel.org/patchwork/project/lkml/list/?series=403473
type Schedstat struct {
	CPUs []*SchedstatCPU
}

// SchedstatCPU contains the values from one "cpu<N>" line
type SchedstatCPU struct {
	CPUNum string

	RunningNanoseconds uint64
	WaitingNanoseconds uint64
	RunTimeslices      uint64
}

// ProcSchedstat contains the values from /proc/<pid>/schedstat
type ProcSchedstat struct {
	RunningNanoseconds uint64
	WaitingNanoseconds uint64
	RunTimeslices      uint64
}

// Schedstat reads data from /proc/schedstat
func (fs FS) Schedstat() (*Schedstat, error) {
	file, err := os.Open(fs.proc.Path("schedstat"))
	if err != nil {
		return nil, err
	}
	defer file.Close()

	stats := &Schedstat{}
	scanner := bufio.NewScanner(file)

	for scanner.Scan() {
		match := cpuLineRE.FindStringSubmatch(scanner.Text())
		if match != nil {
			cpu := &SchedstatCPU{}
			cpu.CPUNum = match[1]

			cpu.RunningNanoseconds, err = strconv.ParseUint(match[8], 10, 64)
			if err != nil {
				continue
			}

			cpu.WaitingNanoseconds, err = strconv.ParseUint(match[9], 10, 64)
			if err != nil {
				continue
			}

			cpu.RunTimeslices, err = strconv.ParseUint(match[10], 10, 64)
			if err != nil {
				continue
			}

			stats.CPUs = append(stats.CPUs, cpu)
		}
	}

	return stats, nil
}

func parseProcSchedstat(contents string) (ProcSchedstat, error) {
	var (
		stats ProcSchedstat
		err   error
	)
	match := procLineRE.FindStringSubmatch(contents)

	if match != nil {
		stats.RunningNanoseconds, err = strconv.ParseUint(match[1], 10, 64)
		if err != nil {
			return stats, err
		}

		stats.WaitingNanoseconds, err = strconv.ParseUint(match[2], 10, 64)
		if err != nil {
			return stats, err
		}

		stats.RunTimeslices, err = strconv.ParseUint(match[3], 10, 64)
		return stats, err
	}

	return stats, errors.New("could not parse schedstat")
}
