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

// +build !windows

package procfs

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"regexp"
	"strings"

	"github.com/prometheus/procfs/internal/util"
)

// Zoneinfo holds info parsed from /proc/zoneinfo.
type Zoneinfo struct {
	Node                       string
	Zone                       string
	NrFreePages                *int64
	Min                        *int64
	Low                        *int64
	High                       *int64
	Scanned                    *int64
	Spanned                    *int64
	Present                    *int64
	Managed                    *int64
	NrActiveAnon               *int64
	NrInactiveAnon             *int64
	NrIsolatedAnon             *int64
	NrAnonPages                *int64
	NrAnonTransparentHugepages *int64
	NrActiveFile               *int64
	NrInactiveFile             *int64
	NrIsolatedFile             *int64
	NrFilePages                *int64
	NrSlabReclaimable          *int64
	NrSlabUnreclaimable        *int64
	NrMlockStack               *int64
	NrKernelStack              *int64
	NrMapped                   *int64
	NrDirty                    *int64
	NrWriteback                *int64
	NrUnevictable              *int64
	NrShmem                    *int64
	NrDirtied                  *int64
	NrWritten                  *int64
	NumaHit                    *int64
	NumaMiss                   *int64
	NumaForeign                *int64
	NumaInterleave             *int64
	NumaLocal                  *int64
	NumaOther                  *int64
	Protection                 []*int64
}

var nodeZoneRE = regexp.MustCompile(`(\d+), zone\s+(\w+)`)

// Zoneinfo parses an zoneinfo-file (/proc/zoneinfo) and returns a slice of
// structs containing the relevant info.  More information available here:
// https://www.kernel.org/doc/Documentation/sysctl/vm.txt
func (fs FS) Zoneinfo() ([]Zoneinfo, error) {
	data, err := ioutil.ReadFile(fs.proc.Path("zoneinfo"))
	if err != nil {
		return nil, fmt.Errorf("error reading zoneinfo %q: %w", fs.proc.Path("zoneinfo"), err)
	}
	zoneinfo, err := parseZoneinfo(data)
	if err != nil {
		return nil, fmt.Errorf("error parsing zoneinfo %q: %w", fs.proc.Path("zoneinfo"), err)
	}
	return zoneinfo, nil
}

func parseZoneinfo(zoneinfoData []byte) ([]Zoneinfo, error) {

	zoneinfo := []Zoneinfo{}

	zoneinfoBlocks := bytes.Split(zoneinfoData, []byte("\nNode"))
	for _, block := range zoneinfoBlocks {
		var zoneinfoElement Zoneinfo
		lines := strings.Split(string(block), "\n")
		for _, line := range lines {

			if nodeZone := nodeZoneRE.FindStringSubmatch(line); nodeZone != nil {
				zoneinfoElement.Node = nodeZone[1]
				zoneinfoElement.Zone = nodeZone[2]
				continue
			}
			if strings.HasPrefix(strings.TrimSpace(line), "per-node stats") {
				zoneinfoElement.Zone = ""
				continue
			}
			parts := strings.Fields(strings.TrimSpace(line))
			if len(parts) < 2 {
				continue
			}
			vp := util.NewValueParser(parts[1])
			switch parts[0] {
			case "nr_free_pages":
				zoneinfoElement.NrFreePages = vp.PInt64()
			case "min":
				zoneinfoElement.Min = vp.PInt64()
			case "low":
				zoneinfoElement.Low = vp.PInt64()
			case "high":
				zoneinfoElement.High = vp.PInt64()
			case "scanned":
				zoneinfoElement.Scanned = vp.PInt64()
			case "spanned":
				zoneinfoElement.Spanned = vp.PInt64()
			case "present":
				zoneinfoElement.Present = vp.PInt64()
			case "managed":
				zoneinfoElement.Managed = vp.PInt64()
			case "nr_active_anon":
				zoneinfoElement.NrActiveAnon = vp.PInt64()
			case "nr_inactive_anon":
				zoneinfoElement.NrInactiveAnon = vp.PInt64()
			case "nr_isolated_anon":
				zoneinfoElement.NrIsolatedAnon = vp.PInt64()
			case "nr_anon_pages":
				zoneinfoElement.NrAnonPages = vp.PInt64()
			case "nr_anon_transparent_hugepages":
				zoneinfoElement.NrAnonTransparentHugepages = vp.PInt64()
			case "nr_active_file":
				zoneinfoElement.NrActiveFile = vp.PInt64()
			case "nr_inactive_file":
				zoneinfoElement.NrInactiveFile = vp.PInt64()
			case "nr_isolated_file":
				zoneinfoElement.NrIsolatedFile = vp.PInt64()
			case "nr_file_pages":
				zoneinfoElement.NrFilePages = vp.PInt64()
			case "nr_slab_reclaimable":
				zoneinfoElement.NrSlabReclaimable = vp.PInt64()
			case "nr_slab_unreclaimable":
				zoneinfoElement.NrSlabUnreclaimable = vp.PInt64()
			case "nr_mlock_stack":
				zoneinfoElement.NrMlockStack = vp.PInt64()
			case "nr_kernel_stack":
				zoneinfoElement.NrKernelStack = vp.PInt64()
			case "nr_mapped":
				zoneinfoElement.NrMapped = vp.PInt64()
			case "nr_dirty":
				zoneinfoElement.NrDirty = vp.PInt64()
			case "nr_writeback":
				zoneinfoElement.NrWriteback = vp.PInt64()
			case "nr_unevictable":
				zoneinfoElement.NrUnevictable = vp.PInt64()
			case "nr_shmem":
				zoneinfoElement.NrShmem = vp.PInt64()
			case "nr_dirtied":
				zoneinfoElement.NrDirtied = vp.PInt64()
			case "nr_written":
				zoneinfoElement.NrWritten = vp.PInt64()
			case "numa_hit":
				zoneinfoElement.NumaHit = vp.PInt64()
			case "numa_miss":
				zoneinfoElement.NumaMiss = vp.PInt64()
			case "numa_foreign":
				zoneinfoElement.NumaForeign = vp.PInt64()
			case "numa_interleave":
				zoneinfoElement.NumaInterleave = vp.PInt64()
			case "numa_local":
				zoneinfoElement.NumaLocal = vp.PInt64()
			case "numa_other":
				zoneinfoElement.NumaOther = vp.PInt64()
			case "protection:":
				protectionParts := strings.Split(line, ":")
				protectionValues := strings.Replace(protectionParts[1], "(", "", 1)
				protectionValues = strings.Replace(protectionValues, ")", "", 1)
				protectionValues = strings.TrimSpace(protectionValues)
				protectionStringMap := strings.Split(protectionValues, ", ")
				val, err := util.ParsePInt64s(protectionStringMap)
				if err == nil {
					zoneinfoElement.Protection = val
				}
			}

		}

		zoneinfo = append(zoneinfo, zoneinfoElement)
	}
	return zoneinfo, nil
}
