package manet

import (
	

	ma 
)

// ResolveUnspecifiedAddress expands an unspecified ip addresses (/ip4/0.0.0.0, /ip6/::) to
// use the known local interfaces. If ifaceAddr is nil, we request interface addresses
// from the network stack. (this is so you can provide a cached value if resolving many addrs)
func ( ma.Multiaddr,  []ma.Multiaddr) ([]ma.Multiaddr, error) {
	// split address into its components
	,  := ma.SplitFirst()

	// if first component (ip) is not unspecified, use it as is.
	if !IsIPUnspecified(.Multiaddr()) {
		return []ma.Multiaddr{}, nil
	}

	 := .Protocols()[0].Code
	 := make([]ma.Multiaddr, 0, len())
	for ,  := range  {
		,  := ma.SplitFirst()
		// must match the first protocol to be resolve.
		if .Protocol().Code !=  {
			continue
		}

		 := 
		if  != nil {
			 = ma.Join(, )
		}
		 = append(, )
	}
	if len() < 1 {
		return nil, fmt.Errorf("failed to resolve: %s", )
	}
	return , nil
}

// ResolveUnspecifiedAddresses expands unspecified ip addresses (/ip4/0.0.0.0, /ip6/::) to
// use the known local interfaces.
func (,  []ma.Multiaddr) ([]ma.Multiaddr, error) {
	// todo optimize: only fetch these if we have a "any" addr.
	if len() < 1 {
		var  error
		,  = interfaceAddresses()
		if  != nil {
			return nil, 
		}
	}

	var  []ma.Multiaddr
	for ,  := range  {
		// unspecified?
		,  := ResolveUnspecifiedAddress(, )
		if  != nil {
			continue // optimistic. if we can't resolve anything, we'll know at the bottom.
		}
		 = append(, ...)
	}

	if len() < 1 {
		return nil, fmt.Errorf("failed to specify addrs: %s", )
	}
	return , nil
}

// interfaceAddresses returns a list of addresses associated with local machine
// Note: we do not return link local addresses. IP loopback is ok, because we
// may be connecting to other nodes in the same machine.
func interfaceAddresses() ([]ma.Multiaddr, error) {
	,  := InterfaceMultiaddrs()
	if  != nil {
		return nil, 
	}

	var  []ma.Multiaddr
	for ,  := range  {
		if IsIP6LinkLocal() {
			continue
		}
		 = append(, )
	}
	return , nil
}