package net

import (
	
	
	

	
)

var invoke common.Invoker = common.Invoke{}

type IOCountersStat struct {
	Name        string `json:"name"`        // interface name
	BytesSent   uint64 `json:"bytesSent"`   // number of bytes sent
	BytesRecv   uint64 `json:"bytesRecv"`   // number of bytes received
	PacketsSent uint64 `json:"packetsSent"` // number of packets sent
	PacketsRecv uint64 `json:"packetsRecv"` // number of packets received
	Errin       uint64 `json:"errin"`       // total number of errors while receiving
	Errout      uint64 `json:"errout"`      // total number of errors while sending
	Dropin      uint64 `json:"dropin"`      // total number of incoming packets which were dropped
	Dropout     uint64 `json:"dropout"`     // total number of outgoing packets which were dropped (always 0 on OSX and BSD)
	Fifoin      uint64 `json:"fifoin"`      // total number of FIFO buffers errors while receiving
	Fifoout     uint64 `json:"fifoout"`     // total number of FIFO buffers errors while sending
}

// Addr is implemented compatibility to psutil
type Addr struct {
	IP   string `json:"ip"`
	Port uint32 `json:"port"`
}

type ConnectionStat struct {
	Fd     uint32  `json:"fd"`
	Family uint32  `json:"family"`
	Type   uint32  `json:"type"`
	Laddr  Addr    `json:"localaddr"`
	Raddr  Addr    `json:"remoteaddr"`
	Status string  `json:"status"`
	Uids   []int32 `json:"uids"`
	Pid    int32   `json:"pid"`
}

// System wide stats about different network protocols
type ProtoCountersStat struct {
	Protocol string           `json:"protocol"`
	Stats    map[string]int64 `json:"stats"`
}

// NetInterfaceAddr is designed for represent interface addresses
type InterfaceAddr struct {
	Addr string `json:"addr"`
}

// InterfaceAddrList is a list of InterfaceAddr
type InterfaceAddrList []InterfaceAddr

type InterfaceStat struct {
	Index        int               `json:"index"`
	MTU          int               `json:"mtu"`          // maximum transmission unit
	Name         string            `json:"name"`         // e.g., "en0", "lo0", "eth0.100"
	HardwareAddr string            `json:"hardwareAddr"` // IEEE MAC-48, EUI-48 and EUI-64 form
	Flags        []string          `json:"flags"`        // e.g., FlagUp, FlagLoopback, FlagMulticast
	Addrs        InterfaceAddrList `json:"addrs"`
}

// InterfaceStatList is a list of InterfaceStat
type InterfaceStatList []InterfaceStat

type FilterStat struct {
	ConnTrackCount int64 `json:"connTrackCount"`
	ConnTrackMax   int64 `json:"connTrackMax"`
}

// ConntrackStat has conntrack summary info
type ConntrackStat struct {
	Entries       uint32 `json:"entries"`       // Number of entries in the conntrack table
	Searched      uint32 `json:"searched"`      // Number of conntrack table lookups performed
	Found         uint32 `json:"found"`         // Number of searched entries which were successful
	New           uint32 `json:"new"`           // Number of entries added which were not expected before
	Invalid       uint32 `json:"invalid"`       // Number of packets seen which can not be tracked
	Ignore        uint32 `json:"ignore"`        // Packets seen which are already connected to an entry
	Delete        uint32 `json:"delete"`        // Number of entries which were removed
	DeleteList    uint32 `json:"deleteList"`    // Number of entries which were put to dying list
	Insert        uint32 `json:"insert"`        // Number of entries inserted into the list
	InsertFailed  uint32 `json:"insertFailed"`  // # insertion attempted but failed (same entry exists)
	Drop          uint32 `json:"drop"`          // Number of packets dropped due to conntrack failure.
	EarlyDrop     uint32 `json:"earlyDrop"`     // Dropped entries to make room for new ones, if maxsize reached
	IcmpError     uint32 `json:"icmpError"`     // Subset of invalid. Packets that can't be tracked d/t error
	ExpectNew     uint32 `json:"expectNew"`     // Entries added after an expectation was already present
	ExpectCreate  uint32 `json:"expectCreate"`  // Expectations added
	ExpectDelete  uint32 `json:"expectDelete"`  // Expectations deleted
	SearchRestart uint32 `json:"searchRestart"` // Conntrack table lookups restarted due to hashtable resizes
}

func ( uint32,  uint32,  uint32,  uint32,  uint32,  uint32,  uint32,  uint32,  uint32,  uint32,  uint32,  uint32,  uint32,  uint32,  uint32,  uint32,  uint32) *ConntrackStat {
	return &ConntrackStat{
		Entries:       ,
		Searched:      ,
		Found:         ,
		New:           ,
		Invalid:       ,
		Ignore:        ,
		Delete:        ,
		DeleteList:    ,
		Insert:        ,
		InsertFailed:  ,
		Drop:          ,
		EarlyDrop:     ,
		IcmpError:     ,
		ExpectNew:     ,
		ExpectCreate:  ,
		ExpectDelete:  ,
		SearchRestart: ,
	}
}

type ConntrackStatList struct {
	items []*ConntrackStat
}

func () *ConntrackStatList {
	return &ConntrackStatList{
		items: []*ConntrackStat{},
	}
}

func ( *ConntrackStatList) ( *ConntrackStat) {
	.items = append(.items, )
}

func ( *ConntrackStatList) () []ConntrackStat {
	 := make([]ConntrackStat, len(.items))
	for ,  := range .items {
		[] = *
	}
	return 
}

// Summary returns a single-element list with totals from all list items.
func ( *ConntrackStatList) () []ConntrackStat {
	 := NewConntrackStat(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
	for ,  := range .items {
		.Entries += .Entries
		.Searched += .Searched
		.Found += .Found
		.New += .New
		.Invalid += .Invalid
		.Ignore += .Ignore
		.Delete += .Delete
		.DeleteList += .DeleteList
		.Insert += .Insert
		.InsertFailed += .InsertFailed
		.Drop += .Drop
		.EarlyDrop += .EarlyDrop
		.IcmpError += .IcmpError
		.ExpectNew += .ExpectNew
		.ExpectCreate += .ExpectCreate
		.ExpectDelete += .ExpectDelete
		.SearchRestart += .SearchRestart
	}
	return []ConntrackStat{*}
}

func ( IOCountersStat) () string {
	,  := json.Marshal()
	return string()
}

func ( ConnectionStat) () string {
	,  := json.Marshal()
	return string()
}

func ( ProtoCountersStat) () string {
	,  := json.Marshal()
	return string()
}

func ( Addr) () string {
	,  := json.Marshal()
	return string()
}

func ( InterfaceStat) () string {
	,  := json.Marshal()
	return string()
}

func ( InterfaceStatList) () string {
	,  := json.Marshal()
	return string()
}

func ( InterfaceAddr) () string {
	,  := json.Marshal()
	return string()
}

func ( ConntrackStat) () string {
	,  := json.Marshal()
	return string()
}

func () (InterfaceStatList, error) {
	return InterfacesWithContext(context.Background())
}

func ( context.Context) (InterfaceStatList, error) {
	,  := net.Interfaces()
	if  != nil {
		return nil, 
	}
	 := make(InterfaceStatList, 0, len())
	for ,  := range  {

		var  []string
		if .Flags&net.FlagUp != 0 {
			 = append(, "up")
		}
		if .Flags&net.FlagBroadcast != 0 {
			 = append(, "broadcast")
		}
		if .Flags&net.FlagLoopback != 0 {
			 = append(, "loopback")
		}
		if .Flags&net.FlagPointToPoint != 0 {
			 = append(, "pointtopoint")
		}
		if .Flags&net.FlagMulticast != 0 {
			 = append(, "multicast")
		}

		 := InterfaceStat{
			Index:        .Index,
			Name:         .Name,
			MTU:          .MTU,
			HardwareAddr: .HardwareAddr.String(),
			Flags:        ,
		}
		,  := .Addrs()
		if  == nil {
			.Addrs = make(InterfaceAddrList, 0, len())
			for ,  := range  {
				.Addrs = append(.Addrs, InterfaceAddr{
					Addr: .String(),
				})
			}

		}
		 = append(, )
	}

	return , nil
}

func getIOCountersAll( []IOCountersStat) ([]IOCountersStat, error) {
	 := IOCountersStat{
		Name: "all",
	}
	for ,  := range  {
		.BytesRecv += .BytesRecv
		.PacketsRecv += .PacketsRecv
		.Errin += .Errin
		.Dropin += .Dropin
		.BytesSent += .BytesSent
		.PacketsSent += .PacketsSent
		.Errout += .Errout
		.Dropout += .Dropout
	}

	return []IOCountersStat{}, nil
}