// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package net

import (
	"internal/syscall/unix"
	"syscall"
	"unsafe"
)

type rawSockaddrDatalink struct {
	Len    uint8
	Family uint8
	Index  uint16
	Type   uint8
	Nlen   uint8
	Alen   uint8
	Slen   uint8
	Data   [120]byte
}

type ifreq struct {
	Name [16]uint8
	Ifru [16]byte
}

const _KINFO_RT_IFLIST = (0x1 << 8) | 3 | (1 << 30)

const _RTAX_NETMASK = 2
const _RTAX_IFA = 5
const _RTAX_MAX = 8

const _SIOCGIFMTU = -0x3fd796aa

func getIfList() ([]byte, error) {
	needed, err := syscall.Getkerninfo(_KINFO_RT_IFLIST, 0, 0, 0)
	if err != nil {
		return nil, err
	}
	tab := make([]byte, needed)
	_, err = syscall.Getkerninfo(_KINFO_RT_IFLIST, uintptr(unsafe.Pointer(&tab[0])), uintptr(unsafe.Pointer(&needed)), 0)
	if err != nil {
		return nil, err
	}
	return tab[:needed], nil
}

// If the ifindex is zero, interfaceTable returns mappings of all
// network interfaces. Otherwise it returns a mapping of a specific
// interface.
func interfaceTable(ifindex int) ([]Interface, error) {
	tab, err := getIfList()
	if err != nil {
		return nil, err
	}

	var ift []Interface
	for len(tab) > 0 {
		ifm := (*syscall.IfMsgHdr)(unsafe.Pointer(&tab[0]))
		if ifm.Msglen == 0 {
			break
		}
		if ifm.Type == syscall.RTM_IFINFO {
			if ifindex == 0 || ifindex == int(ifm.Index) {
				sdl := (*rawSockaddrDatalink)(unsafe.Pointer(&tab[unsafe.Sizeof(syscall.IfMsgHdr)]))

				ifi := &Interface{Index: int(ifm.Index), Flags: linkFlags(ifm.Flags)}
				ifi.Name = string(sdl.Data[:sdl.Nlen])
				ifi.HardwareAddr = sdl.Data[sdl.Nlen : sdl.Nlen+sdl.Alen]

				// Retrieve MTU
				ifr := &ifreq{}
				copy(ifr.Name[:], ifi.Name)
				sock, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, 0)
				if err != nil {
					return nil, err
				}
				err = unix.Ioctl(sock, _SIOCGIFMTU, uintptr(unsafe.Pointer(ifr)))
				if err != nil {
					return nil, err
				}
				ifi.MTU = int(ifr.Ifru[0])<<24 | int(ifr.Ifru[1])<<16 | int(ifr.Ifru[2])<<8 | int(ifr.Ifru[3])

				ift = append(ift, *ifi)
				if ifindex == int(ifm.Index) {
					break
				}
			}
		}
		tab = tab[ifm.Msglen:]
	}

	return ift, nil
}

func linkFlags(rawFlags int32) Flags {
	var f Flags
	if rawFlags&syscall.IFF_UP != 0 {
		f |= FlagUp
	}
	if rawFlags&syscall.IFF_BROADCAST != 0 {
		f |= FlagBroadcast
	}
	if rawFlags&syscall.IFF_LOOPBACK != 0 {
		f |= FlagLoopback
	}
	if rawFlags&syscall.IFF_POINTOPOINT != 0 {
		f |= FlagPointToPoint
	}
	if rawFlags&syscall.IFF_MULTICAST != 0 {
		f |= FlagMulticast
	}
	return f
}

// If the ifi is nil, interfaceAddrTable returns addresses for all
// network interfaces. Otherwise it returns addresses for a specific
// interface.
func interfaceAddrTable(ifi *Interface) ([]Addr, error) {
	tab, err := getIfList()
	if err != nil {
		return nil, err
	}

	var ifat []Addr
	for len(tab) > 0 {
		ifm := (*syscall.IfMsgHdr)(unsafe.Pointer(&tab[0]))
		if ifm.Msglen == 0 {
			break
		}
		if ifm.Type == syscall.RTM_NEWADDR {
			if ifi == nil || ifi.Index == int(ifm.Index) {
				mask := ifm.Addrs
				off := uint(unsafe.Sizeof(syscall.IfMsgHdr))

				var iprsa, nmrsa *syscall.RawSockaddr
				for i := uint(0); i < _RTAX_MAX; i++ {
					if mask&(1<<i) == 0 {
						continue
					}
					rsa := (*syscall.RawSockaddr)(unsafe.Pointer(&tab[off]))
					if i == _RTAX_NETMASK {
						nmrsa = rsa
					}
					if i == _RTAX_IFA {
						iprsa = rsa
					}
					off += (uint(rsa.Len) + 3) &^ 3
				}
				if iprsa != nil && nmrsa != nil {
					var mask IPMask
					var ip IP

					switch iprsa.Family {
					case syscall.AF_INET:
						ipsa := (*syscall.RawSockaddrInet4)(unsafe.Pointer(iprsa))
						nmsa := (*syscall.RawSockaddrInet4)(unsafe.Pointer(nmrsa))
						ip = IPv4(ipsa.Addr[0], ipsa.Addr[1], ipsa.Addr[2], ipsa.Addr[3])
						mask = IPv4Mask(nmsa.Addr[0], nmsa.Addr[1], nmsa.Addr[2], nmsa.Addr[3])
					case syscall.AF_INET6:
						ipsa := (*syscall.RawSockaddrInet6)(unsafe.Pointer(iprsa))
						nmsa := (*syscall.RawSockaddrInet6)(unsafe.Pointer(nmrsa))
						ip = make(IP, IPv6len)
						copy(ip, ipsa.Addr[:])
						mask = make(IPMask, IPv6len)
						copy(mask, nmsa.Addr[:])
					}
					ifa := &IPNet{IP: ip, Mask: mask}
					ifat = append(ifat, ifa)
				}
			}
		}
		tab = tab[ifm.Msglen:]
	}

	return ifat, nil
}

// interfaceMulticastAddrTable returns addresses for a specific
// interface.
func interfaceMulticastAddrTable(ifi *Interface) ([]Addr, error) {
	return nil, nil
}
