// Copyright 2015 The Vanadium 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 netstate

import (
	"errors"
	"net"
)

var (
	ErrNotAnIPProtocol = errors.New("requested protocol is not from the IP family")
)

// AddressChooser returns the address it prefers out of the set passed to it
// for the specified protocol. It should return an error if the requested protocol
// is not supported, but an empty slice of net.Addrs in the case for it fails to
// find any appropriate addresses rather than an error.
type AddressChooser func(protocol string, candidates []net.Addr) ([]net.Addr, error)

// PossibleAddresses returns the set of addresses that can be used to reach the
// specified host and that satisfy whatever policy is implemented by the supplied
// AddressChooser. It also returns an indication of whether the supplied host is
// unspecified or not. An unspecified host can be used over any network interface
// on the host. If the supplied address contains a port in then all of the
// returned addresses will also contain that port.
// The returned net.Addr's need have the exact same protocol as that passed
// in as a parameter, rather, the chooser should return net.Addr's that can
// be used for that protocol. Using tcp as a parameter for example will generally
// result in net.Addr's whose Network method returns "ip" or "ip6".
// If a nil chooser is supplied then it is assumed then LoopbackIPv4AddressChooser
// will be used.
// If the chooser fails to find any appropriate addresses then the protocol, addr
// parameters will be returned as net.Addr (and if possible as a netstate.Address).
//
// PossibleAddress currently only supports IP addresses.
func PossibleAddresses(protocol, addr string, chooser AddressChooser) ([]net.Addr, bool, error) {
	if !IsIPProtocol(protocol) {
		return nil, false, ErrNotAnIPProtocol
	}

	host, port, err := net.SplitHostPort(addr)
	if err != nil {
		host = addr
		port = ""
	}

	ip := net.ParseIP(host)
	if ip == nil {
		return nil, false, ErrFailedToParseIPAddr
	}

	var candidates []net.Addr
	unspecified := ip.IsUnspecified()
	if unspecified {
		all, err := GetAllAddresses()
		if err != nil {
			return nil, unspecified, err
		}
		all = all.Map(WithIPHost)
		candidates = all.AsNetAddrs()
	} else {
		ipaddr, err := AddressFromIP(ip)
		if err != nil {
			return nil, unspecified, err
		}
		return []net.Addr{WithIPHostAndPort(ipaddr, port)}, unspecified, nil
	}
	if chooser == nil {
		addrs, err := LoopbackIPv4AddressChooser(protocol, candidates)
		return addrs, unspecified, err
	}
	chosen, err := chooser(protocol, candidates)
	if err != nil {
		return nil, unspecified, err
	}
	if len(chosen) == 0 {
		netaddr := NewNetAddr(protocol, addr)
		if address, err := AddressFromAddr(netaddr); err != nil {
			return []net.Addr{netaddr}, unspecified, nil
		} else {
			return []net.Addr{address}, unspecified, nil
		}
	}
	return chosen, unspecified, nil
}

// LoopbackIPv4AddressChooser will return the loopback IPv4 address if it is found
// in the supplied candidates.
func LoopbackIPv4AddressChooser(protocol string, candidates []net.Addr) ([]net.Addr, error) {
	return ConvertToAddresses(candidates).Filter(IsLoopbackIP).Filter(IsUnicastIPv4).AsNetAddrs(), nil
}
