package cluster

import (
	"net"

	"github.com/vishvananda/netlink"
)

func (c *Cluster) resolveSystemAddr() (net.IP, error) {
	// Use the system's only device IP address, or fail if there are
	// multiple addresses to choose from.
	interfaces, err := netlink.LinkList()
	if err != nil {
		return nil, err
	}

	var (
		systemAddr      net.IP
		systemInterface string
		deviceFound     bool
	)

	for _, intf := range interfaces {
		// Skip non device or inactive interfaces
		if intf.Type() != "device" || intf.Attrs().Flags&net.FlagUp == 0 {
			continue
		}

		addrs, err := netlink.AddrList(intf, netlink.FAMILY_ALL)
		if err != nil {
			continue
		}

		var interfaceAddr4, interfaceAddr6 net.IP

		for _, addr := range addrs {
			ipAddr := addr.IPNet.IP

			// Skip loopback and link-local addresses
			if !ipAddr.IsGlobalUnicast() {
				continue
			}

			// At least one non-loopback device is found and it is administratively up
			deviceFound = true

			if ipAddr.To4() != nil {
				if interfaceAddr4 != nil {
					return nil, errMultipleIPs(intf.Attrs().Name, intf.Attrs().Name, interfaceAddr4, ipAddr)
				}
				interfaceAddr4 = ipAddr
			} else {
				if interfaceAddr6 != nil {
					return nil, errMultipleIPs(intf.Attrs().Name, intf.Attrs().Name, interfaceAddr6, ipAddr)
				}
				interfaceAddr6 = ipAddr
			}
		}

		// In the case that this interface has exactly one IPv4 address
		// and exactly one IPv6 address, favor IPv4 over IPv6.
		if interfaceAddr4 != nil {
			if systemAddr != nil {
				return nil, errMultipleIPs(systemInterface, intf.Attrs().Name, systemAddr, interfaceAddr4)
			}
			systemAddr = interfaceAddr4
			systemInterface = intf.Attrs().Name
		} else if interfaceAddr6 != nil {
			if systemAddr != nil {
				return nil, errMultipleIPs(systemInterface, intf.Attrs().Name, systemAddr, interfaceAddr6)
			}
			systemAddr = interfaceAddr6
			systemInterface = intf.Attrs().Name
		}
	}

	if systemAddr == nil {
		if !deviceFound {
			// If no non-loopback device type interface is found,
			// fall back to the regular auto-detection mechanism.
			// This is to cover the case where docker is running
			// inside a container (eths are in fact veths).
			return c.resolveSystemAddrViaSubnetCheck()
		}
		return nil, errNoIP
	}

	return systemAddr, nil
}
