// +build darwin

package net

import (
	"errors"
	"fmt"
	"os/exec"
	"regexp"
	"strconv"
	"strings"
)

var (
	errNetstatHeader  = errors.New("Can't parse header of netstat output")
	netstatLinkRegexp = regexp.MustCompile(`^<Link#(\d+)>$`)
)

const endOfLine = "\n"

func parseNetstatLine(line string) (stat *IOCountersStat, linkID *uint, err error) {
	var (
		numericValue uint64
		columns      = strings.Fields(line)
	)

	if columns[0] == "Name" {
		err = errNetstatHeader
		return
	}

	// try to extract the numeric value from <Link#123>
	if subMatch := netstatLinkRegexp.FindStringSubmatch(columns[2]); len(subMatch) == 2 {
		numericValue, err = strconv.ParseUint(subMatch[1], 10, 64)
		if err != nil {
			return
		}
		linkIDUint := uint(numericValue)
		linkID = &linkIDUint
	}

	base := 1
	numberColumns := len(columns)
	// sometimes Address is ommitted
	if numberColumns < 12 {
		base = 0
	}
	if numberColumns < 11 || numberColumns > 13 {
		err = fmt.Errorf("Line %q do have an invalid number of columns %d", line, numberColumns)
		return
	}

	parsed := make([]uint64, 0, 7)
	vv := []string{
		columns[base+3], // Ipkts == PacketsRecv
		columns[base+4], // Ierrs == Errin
		columns[base+5], // Ibytes == BytesRecv
		columns[base+6], // Opkts == PacketsSent
		columns[base+7], // Oerrs == Errout
		columns[base+8], // Obytes == BytesSent
	}
	if len(columns) == 12 {
		vv = append(vv, columns[base+10])
	}

	for _, target := range vv {
		if target == "-" {
			parsed = append(parsed, 0)
			continue
		}

		if numericValue, err = strconv.ParseUint(target, 10, 64); err != nil {
			return
		}
		parsed = append(parsed, numericValue)
	}

	stat = &IOCountersStat{
		Name:        strings.Trim(columns[0], "*"), // remove the * that sometimes is on right on interface
		PacketsRecv: parsed[0],
		Errin:       parsed[1],
		BytesRecv:   parsed[2],
		PacketsSent: parsed[3],
		Errout:      parsed[4],
		BytesSent:   parsed[5],
	}
	if len(parsed) == 7 {
		stat.Dropout = parsed[6]
	}
	return
}

type netstatInterface struct {
	linkID *uint
	stat   *IOCountersStat
}

func parseNetstatOutput(output string) ([]netstatInterface, error) {
	var (
		err   error
		lines = strings.Split(strings.Trim(output, endOfLine), endOfLine)
	)

	// number of interfaces is number of lines less one for the header
	numberInterfaces := len(lines) - 1

	interfaces := make([]netstatInterface, numberInterfaces)
	// no output beside header
	if numberInterfaces == 0 {
		return interfaces, nil
	}

	for index := 0; index < numberInterfaces; index++ {
		nsIface := netstatInterface{}
		if nsIface.stat, nsIface.linkID, err = parseNetstatLine(lines[index+1]); err != nil {
			return nil, err
		}
		interfaces[index] = nsIface
	}
	return interfaces, nil
}

// map that hold the name of a network interface and the number of usage
type mapInterfaceNameUsage map[string]uint

func newMapInterfaceNameUsage(ifaces []netstatInterface) mapInterfaceNameUsage {
	output := make(mapInterfaceNameUsage)
	for index := range ifaces {
		if ifaces[index].linkID != nil {
			ifaceName := ifaces[index].stat.Name
			usage, ok := output[ifaceName]
			if ok {
				output[ifaceName] = usage + 1
			} else {
				output[ifaceName] = 1
			}
		}
	}
	return output
}

func (min mapInterfaceNameUsage) isTruncated() bool {
	for _, usage := range min {
		if usage > 1 {
			return true
		}
	}
	return false
}

func (min mapInterfaceNameUsage) notTruncated() []string {
	output := make([]string, 0)
	for ifaceName, usage := range min {
		if usage == 1 {
			output = append(output, ifaceName)
		}
	}
	return output
}

// example of `netstat -ibdnW` output on yosemite
// Name  Mtu   Network       Address            Ipkts Ierrs     Ibytes    Opkts Oerrs     Obytes  Coll Drop
// lo0   16384 <Link#1>                        869107     0  169411755   869107     0  169411755     0   0
// lo0   16384 ::1/128     ::1                 869107     -  169411755   869107     -  169411755     -   -
// lo0   16384 127           127.0.0.1         869107     -  169411755   869107     -  169411755     -   -
func IOCounters(pernic bool) ([]IOCountersStat, error) {
	var (
		ret      []IOCountersStat
		retIndex int
	)

	netstat, err := exec.LookPath("/usr/sbin/netstat")
	if err != nil {
		return nil, err
	}

	// try to get all interface metrics, and hope there won't be any truncated
	out, err := invoke.Command(netstat, "-ibdnW")
	if err != nil {
		return nil, err
	}

	nsInterfaces, err := parseNetstatOutput(string(out))
	if err != nil {
		return nil, err
	}

	ifaceUsage := newMapInterfaceNameUsage(nsInterfaces)
	notTruncated := ifaceUsage.notTruncated()
	ret = make([]IOCountersStat, len(notTruncated))

	if !ifaceUsage.isTruncated() {
		// no truncated interface name, return stats of all interface with <Link#...>
		for index := range nsInterfaces {
			if nsInterfaces[index].linkID != nil {
				ret[retIndex] = *nsInterfaces[index].stat
				retIndex++
			}
		}
	} else {
		// duplicated interface, list all interfaces
		ifconfig, err := exec.LookPath("/sbin/ifconfig")
		if err != nil {
			return nil, err
		}
		if out, err = invoke.Command(ifconfig, "-l"); err != nil {
			return nil, err
		}
		interfaceNames := strings.Fields(strings.TrimRight(string(out), endOfLine))

		// for each of the interface name, run netstat if we don't have any stats yet
		for _, interfaceName := range interfaceNames {
			truncated := true
			for index := range nsInterfaces {
				if nsInterfaces[index].linkID != nil && nsInterfaces[index].stat.Name == interfaceName {
					// handle the non truncated name to avoid execute netstat for them again
					ret[retIndex] = *nsInterfaces[index].stat
					retIndex++
					truncated = false
					break
				}
			}
			if truncated {
				// run netstat with -I$ifacename
				if out, err = invoke.Command(netstat, "-ibdnWI"+interfaceName); err != nil {
					return nil, err
				}
				parsedIfaces, err := parseNetstatOutput(string(out))
				if err != nil {
					return nil, err
				}
				if len(parsedIfaces) == 0 {
					// interface had been removed since `ifconfig -l` had been executed
					continue
				}
				for index := range parsedIfaces {
					if parsedIfaces[index].linkID != nil {
						ret = append(ret, *parsedIfaces[index].stat)
						break
					}
				}
			}
		}
	}

	if pernic == false {
		return getIOCountersAll(ret)
	}
	return ret, nil
}

// NetIOCountersByFile is an method which is added just a compatibility for linux.
func IOCountersByFile(pernic bool, filename string) ([]IOCountersStat, error) {
	return IOCounters(pernic)
}

func FilterCounters() ([]FilterStat, error) {
	return nil, errors.New("NetFilterCounters not implemented for darwin")
}

// NetProtoCounters returns network statistics for the entire system
// If protocols is empty then all protocols are returned, otherwise
// just the protocols in the list are returned.
// Not Implemented for Darwin
func ProtoCounters(protocols []string) ([]ProtoCountersStat, error) {
	return nil, errors.New("NetProtoCounters not implemented for darwin")
}
