// 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/poll"
	"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

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
	}

	sock, err := sysSocket(syscall.AF_INET, syscall.SOCK_DGRAM, 0)
	if err != nil {
		return nil, err
	}
	defer poll.CloseFunc(sock)

	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[syscall.SizeofIfMsghdr]))

				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)
				err = unix.Ioctl(sock, syscall.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(syscall.SizeofIfMsghdr)

				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
}
