// Copyright 2011 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.

// Network interface identification for Windows

package net

import (
	"os"
	"syscall"
	"unsafe"
)

func bytePtrToString(p *uint8) string {
	a := (*[10000]uint8)(unsafe.Pointer(p))
	i := 0
	for a[i] != 0 {
		i++
	}
	return string(a[:i])
}

func getAdapterList() (*syscall.IpAdapterInfo, os.Error) {
	b := make([]byte, 1000)
	l := uint32(len(b))
	a := (*syscall.IpAdapterInfo)(unsafe.Pointer(&b[0]))
	e := syscall.GetAdaptersInfo(a, &l)
	if e == syscall.ERROR_BUFFER_OVERFLOW {
		b = make([]byte, l)
		a = (*syscall.IpAdapterInfo)(unsafe.Pointer(&b[0]))
		e = syscall.GetAdaptersInfo(a, &l)
	}
	if e != 0 {
		return nil, os.NewSyscallError("GetAdaptersInfo", e)
	}
	return a, nil
}

func getInterfaceList() ([]syscall.InterfaceInfo, os.Error) {
	s, e := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_UDP)
	if e != 0 {
		return nil, os.NewSyscallError("Socket", e)
	}
	defer syscall.Closesocket(s)

	ii := [20]syscall.InterfaceInfo{}
	ret := uint32(0)
	size := uint32(unsafe.Sizeof(ii))
	e = syscall.WSAIoctl(s, syscall.SIO_GET_INTERFACE_LIST, nil, 0, (*byte)(unsafe.Pointer(&ii[0])), size, &ret, nil, 0)
	if e != 0 {
		return nil, os.NewSyscallError("WSAIoctl", e)
	}
	c := ret / uint32(unsafe.Sizeof(ii[0]))
	return ii[:c-1], nil
}

// If the ifindex is zero, interfaceTable returns mappings of all
// network interfaces.  Otheriwse it returns a mapping of a specific
// interface.
func interfaceTable(ifindex int) ([]Interface, os.Error) {
	ai, e := getAdapterList()
	if e != nil {
		return nil, e
	}

	ii, e := getInterfaceList()
	if e != nil {
		return nil, e
	}

	var ift []Interface
	for ; ai != nil; ai = ai.Next {
		index := ai.Index
		if ifindex == 0 || ifindex == int(index) {
			var flags Flags

			row := syscall.MibIfRow{Index: index}
			e := syscall.GetIfEntry(&row)
			if e != 0 {
				return nil, os.NewSyscallError("GetIfEntry", e)
			}

			for _, ii := range ii {
				ip := (*syscall.RawSockaddrInet4)(unsafe.Pointer(&ii.Address)).Addr
				ipv4 := IPv4(ip[0], ip[1], ip[2], ip[3])
				ipl := &ai.IpAddressList
				for ipl != nil {
					ips := bytePtrToString(&ipl.IpAddress.String[0])
					if ipv4.Equal(parseIPv4(ips)) {
						break
					}
					ipl = ipl.Next
				}
				if ipl == nil {
					continue
				}
				if ii.Flags&syscall.IFF_UP != 0 {
					flags |= FlagUp
				}
				if ii.Flags&syscall.IFF_LOOPBACK != 0 {
					flags |= FlagLoopback
				}
				if ii.Flags&syscall.IFF_BROADCAST != 0 {
					flags |= FlagBroadcast
				}
				if ii.Flags&syscall.IFF_POINTTOPOINT != 0 {
					flags |= FlagPointToPoint
				}
				if ii.Flags&syscall.IFF_MULTICAST != 0 {
					flags |= FlagMulticast
				}
			}

			name := bytePtrToString(&ai.AdapterName[0])

			ifi := Interface{
				Index:        int(index),
				MTU:          int(row.Mtu),
				Name:         name,
				HardwareAddr: HardwareAddr(row.PhysAddr[:row.PhysAddrLen]),
				Flags:        flags}
			ift = append(ift, ifi)
		}
	}
	return ift, nil
}

// If the ifindex is zero, interfaceAddrTable returns addresses
// for all network interfaces.  Otherwise it returns addresses
// for a specific interface.
func interfaceAddrTable(ifindex int) ([]Addr, os.Error) {
	ai, e := getAdapterList()
	if e != nil {
		return nil, e
	}

	var ifat []Addr
	for ; ai != nil; ai = ai.Next {
		index := ai.Index
		if ifindex == 0 || ifindex == int(index) {
			ipl := &ai.IpAddressList
			for ; ipl != nil; ipl = ipl.Next {
				ifa := IPAddr{}
				ifa.IP = parseIPv4(bytePtrToString(&ipl.IpAddress.String[0]))
				ifat = append(ifat, ifa.toAddr())
			}
		}
	}
	return ifat, nil
}

// If the ifindex is zero, interfaceMulticastAddrTable returns
// addresses for all network interfaces.  Otherwise it returns
// addresses for a specific interface.
func interfaceMulticastAddrTable(ifindex int) ([]Addr, os.Error) {
	return nil, nil
}
