// Copyright 2022 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 (
	
	
	
	
	
	

	
)

// ProcSnmp models the content of /proc/<pid>/net/snmp.
type ProcSnmp struct {
	// The process ID.
	PID int
	Ip
	Icmp
	IcmpMsg
	Tcp
	Udp
	UdpLite
}

type Ip struct { // nolint:revive
	Forwarding      *float64
	DefaultTTL      *float64
	InReceives      *float64
	InHdrErrors     *float64
	InAddrErrors    *float64
	ForwDatagrams   *float64
	InUnknownProtos *float64
	InDiscards      *float64
	InDelivers      *float64
	OutRequests     *float64
	OutDiscards     *float64
	OutNoRoutes     *float64
	ReasmTimeout    *float64
	ReasmReqds      *float64
	ReasmOKs        *float64
	ReasmFails      *float64
	FragOKs         *float64
	FragFails       *float64
	FragCreates     *float64
}

type Icmp struct { // nolint:revive
	InMsgs           *float64
	InErrors         *float64
	InCsumErrors     *float64
	InDestUnreachs   *float64
	InTimeExcds      *float64
	InParmProbs      *float64
	InSrcQuenchs     *float64
	InRedirects      *float64
	InEchos          *float64
	InEchoReps       *float64
	InTimestamps     *float64
	InTimestampReps  *float64
	InAddrMasks      *float64
	InAddrMaskReps   *float64
	OutMsgs          *float64
	OutErrors        *float64
	OutDestUnreachs  *float64
	OutTimeExcds     *float64
	OutParmProbs     *float64
	OutSrcQuenchs    *float64
	OutRedirects     *float64
	OutEchos         *float64
	OutEchoReps      *float64
	OutTimestamps    *float64
	OutTimestampReps *float64
	OutAddrMasks     *float64
	OutAddrMaskReps  *float64
}

type IcmpMsg struct {
	InType3  *float64
	OutType3 *float64
}

type Tcp struct { // nolint:revive
	RtoAlgorithm *float64
	RtoMin       *float64
	RtoMax       *float64
	MaxConn      *float64
	ActiveOpens  *float64
	PassiveOpens *float64
	AttemptFails *float64
	EstabResets  *float64
	CurrEstab    *float64
	InSegs       *float64
	OutSegs      *float64
	RetransSegs  *float64
	InErrs       *float64
	OutRsts      *float64
	InCsumErrors *float64
}

type Udp struct { // nolint:revive
	InDatagrams  *float64
	NoPorts      *float64
	InErrors     *float64
	OutDatagrams *float64
	RcvbufErrors *float64
	SndbufErrors *float64
	InCsumErrors *float64
	IgnoredMulti *float64
}

type UdpLite struct { // nolint:revive
	InDatagrams  *float64
	NoPorts      *float64
	InErrors     *float64
	OutDatagrams *float64
	RcvbufErrors *float64
	SndbufErrors *float64
	InCsumErrors *float64
	IgnoredMulti *float64
}

func ( Proc) () (ProcSnmp, error) {
	 := .path("net/snmp")
	,  := util.ReadFileNoStat()
	if  != nil {
		return ProcSnmp{PID: .PID}, 
	}
	,  := parseSnmp(bytes.NewReader(), )
	.PID = .PID
	return , 
}

// parseSnmp parses the metrics from proc/<pid>/net/snmp file
// and returns a map contains those metrics (e.g. {"Ip": {"Forwarding": 2}}).
func parseSnmp( io.Reader,  string) (ProcSnmp, error) {
	var (
		  = bufio.NewScanner()
		 = ProcSnmp{}
	)

	for .Scan() {
		 := strings.Split(.Text(), " ")
		.Scan()
		 := strings.Split(.Text(), " ")
		// Remove trailing :.
		 := strings.TrimSuffix([0], ":")
		if len() != len() {
			return , fmt.Errorf("%w: mismatch field count mismatch in %s: %s",
				ErrFileParse, , )
		}
		for  := 1;  < len(); ++ {
			,  := strconv.ParseFloat([], 64)
			if  != nil {
				return , 
			}
			 := []

			switch  {
			case "Ip":
				switch  {
				case "Forwarding":
					.Forwarding = &
				case "DefaultTTL":
					.DefaultTTL = &
				case "InReceives":
					.InReceives = &
				case "InHdrErrors":
					.InHdrErrors = &
				case "InAddrErrors":
					.InAddrErrors = &
				case "ForwDatagrams":
					.ForwDatagrams = &
				case "InUnknownProtos":
					.InUnknownProtos = &
				case "InDiscards":
					.InDiscards = &
				case "InDelivers":
					.InDelivers = &
				case "OutRequests":
					.OutRequests = &
				case "OutDiscards":
					.OutDiscards = &
				case "OutNoRoutes":
					.OutNoRoutes = &
				case "ReasmTimeout":
					.ReasmTimeout = &
				case "ReasmReqds":
					.ReasmReqds = &
				case "ReasmOKs":
					.ReasmOKs = &
				case "ReasmFails":
					.ReasmFails = &
				case "FragOKs":
					.FragOKs = &
				case "FragFails":
					.FragFails = &
				case "FragCreates":
					.FragCreates = &
				}
			case "Icmp":
				switch  {
				case "InMsgs":
					.InMsgs = &
				case "InErrors":
					.Icmp.InErrors = &
				case "InCsumErrors":
					.Icmp.InCsumErrors = &
				case "InDestUnreachs":
					.InDestUnreachs = &
				case "InTimeExcds":
					.InTimeExcds = &
				case "InParmProbs":
					.InParmProbs = &
				case "InSrcQuenchs":
					.InSrcQuenchs = &
				case "InRedirects":
					.InRedirects = &
				case "InEchos":
					.InEchos = &
				case "InEchoReps":
					.InEchoReps = &
				case "InTimestamps":
					.InTimestamps = &
				case "InTimestampReps":
					.InTimestampReps = &
				case "InAddrMasks":
					.InAddrMasks = &
				case "InAddrMaskReps":
					.InAddrMaskReps = &
				case "OutMsgs":
					.OutMsgs = &
				case "OutErrors":
					.OutErrors = &
				case "OutDestUnreachs":
					.OutDestUnreachs = &
				case "OutTimeExcds":
					.OutTimeExcds = &
				case "OutParmProbs":
					.OutParmProbs = &
				case "OutSrcQuenchs":
					.OutSrcQuenchs = &
				case "OutRedirects":
					.OutRedirects = &
				case "OutEchos":
					.OutEchos = &
				case "OutEchoReps":
					.OutEchoReps = &
				case "OutTimestamps":
					.OutTimestamps = &
				case "OutTimestampReps":
					.OutTimestampReps = &
				case "OutAddrMasks":
					.OutAddrMasks = &
				case "OutAddrMaskReps":
					.OutAddrMaskReps = &
				}
			case "IcmpMsg":
				switch  {
				case "InType3":
					.InType3 = &
				case "OutType3":
					.OutType3 = &
				}
			case "Tcp":
				switch  {
				case "RtoAlgorithm":
					.RtoAlgorithm = &
				case "RtoMin":
					.RtoMin = &
				case "RtoMax":
					.RtoMax = &
				case "MaxConn":
					.MaxConn = &
				case "ActiveOpens":
					.ActiveOpens = &
				case "PassiveOpens":
					.PassiveOpens = &
				case "AttemptFails":
					.AttemptFails = &
				case "EstabResets":
					.EstabResets = &
				case "CurrEstab":
					.CurrEstab = &
				case "InSegs":
					.InSegs = &
				case "OutSegs":
					.OutSegs = &
				case "RetransSegs":
					.RetransSegs = &
				case "InErrs":
					.InErrs = &
				case "OutRsts":
					.OutRsts = &
				case "InCsumErrors":
					.Tcp.InCsumErrors = &
				}
			case "Udp":
				switch  {
				case "InDatagrams":
					.Udp.InDatagrams = &
				case "NoPorts":
					.Udp.NoPorts = &
				case "InErrors":
					.Udp.InErrors = &
				case "OutDatagrams":
					.Udp.OutDatagrams = &
				case "RcvbufErrors":
					.Udp.RcvbufErrors = &
				case "SndbufErrors":
					.Udp.SndbufErrors = &
				case "InCsumErrors":
					.Udp.InCsumErrors = &
				case "IgnoredMulti":
					.Udp.IgnoredMulti = &
				}
			case "UdpLite":
				switch  {
				case "InDatagrams":
					.UdpLite.InDatagrams = &
				case "NoPorts":
					.UdpLite.NoPorts = &
				case "InErrors":
					.UdpLite.InErrors = &
				case "OutDatagrams":
					.UdpLite.OutDatagrams = &
				case "RcvbufErrors":
					.UdpLite.RcvbufErrors = &
				case "SndbufErrors":
					.UdpLite.SndbufErrors = &
				case "InCsumErrors":
					.UdpLite.InCsumErrors = &
				case "IgnoredMulti":
					.UdpLite.IgnoredMulti = &
				}
			}
		}
	}
	return , .Err()
}