package swarm

import (
	

	manet 

	ma 
)

// ListenAddresses returns a list of addresses at which this swarm listens.
func ( *Swarm) () []ma.Multiaddr {
	.listeners.RLock()
	defer .listeners.RUnlock()
	return .listenAddressesNoLock()
}

func ( *Swarm) () []ma.Multiaddr {
	 := make([]ma.Multiaddr, 0, len(.listeners.m)+10) // A bit extra so we may avoid an extra allocation in the for loop below.
	for  := range .listeners.m {
		 = append(, .Multiaddr())
	}
	return 
}

const ifaceAddrsCacheDuration = 1 * time.Minute

// InterfaceListenAddresses returns a list of addresses at which this swarm
// listens. It expands "any interface" addresses (/ip4/0.0.0.0, /ip6/::) to
// use the known local interfaces.
func ( *Swarm) () ([]ma.Multiaddr, error) {
	.listeners.RLock() // RLock start

	 := .listeners.ifaceListenAddres
	 := time.Now().After(.listeners.cacheEOL)
	.listeners.RUnlock() // RLock end

	if ! {
		// Cache is valid, clone the slice
		return append([:0:0], ...), nil
	}

	// Cache is not valid
	// Perfrom double checked locking

	.listeners.Lock() // Lock start

	 = .listeners.ifaceListenAddres
	 = time.Now().After(.listeners.cacheEOL)
	if  {
		// Cache is still invalid
		 := .listenAddressesNoLock()
		if len() > 0 {
			// We're actually listening on addresses.
			var  error
			,  = manet.ResolveUnspecifiedAddresses(, nil)
			if  != nil {
				.listeners.Unlock() // Lock early exit
				return nil, 
			}
		} else {
			 = nil
		}

		.listeners.ifaceListenAddres = 
		.listeners.cacheEOL = time.Now().Add(ifaceAddrsCacheDuration)
	}

	.listeners.Unlock() // Lock end

	return append([:0:0], ...), nil
}