package manet

import (
	
	
	

	ma 
)

// FromNetAddrFunc is a generic function which converts a net.Addr to Multiaddress
type FromNetAddrFunc func(a net.Addr) (ma.Multiaddr, error)

// ToNetAddrFunc is a generic function which converts a Multiaddress to net.Addr
type ToNetAddrFunc func(ma ma.Multiaddr) (net.Addr, error)

var defaultCodecs = NewCodecMap()

func init() {
	RegisterFromNetAddr(parseTCPNetAddr, "tcp", "tcp4", "tcp6")
	RegisterFromNetAddr(parseUDPNetAddr, "udp", "udp4", "udp6")
	RegisterFromNetAddr(parseIPNetAddr, "ip", "ip4", "ip6")
	RegisterFromNetAddr(parseIPPlusNetAddr, "ip+net")
	RegisterFromNetAddr(parseUnixNetAddr, "unix")

	RegisterToNetAddr(parseBasicNetMaddr, "tcp", "udp", "ip6", "ip4", "unix")
}

// CodecMap holds a map of NetCodecs indexed by their Protocol ID
// along with parsers for the addresses they use.
// It is used to keep a list of supported network address codecs (protocols
// which addresses can be converted to and from multiaddresses).
type CodecMap struct {
	addrParsers  map[string]FromNetAddrFunc
	maddrParsers map[string]ToNetAddrFunc
	lk           sync.Mutex
}

// NewCodecMap initializes and returns a CodecMap object.
func () *CodecMap {
	return &CodecMap{
		addrParsers:  make(map[string]FromNetAddrFunc),
		maddrParsers: make(map[string]ToNetAddrFunc),
	}
}

// RegisterFromNetAddr registers a conversion from net.Addr instances to multiaddrs.
func ( FromNetAddrFunc,  ...string) {
	defaultCodecs.RegisterFromNetAddr(, ...)
}

// RegisterToNetAddr registers a conversion from multiaddrs to net.Addr instances.
func ( ToNetAddrFunc,  ...string) {
	defaultCodecs.RegisterToNetAddr(, ...)
}

// RegisterFromNetAddr registers a conversion from net.Addr instances to multiaddrs
func ( *CodecMap) ( FromNetAddrFunc,  ...string) {
	.lk.Lock()
	defer .lk.Unlock()

	for ,  := range  {
		.addrParsers[] = 
	}
}

// RegisterToNetAddr registers a conversion from multiaddrs to net.Addr instances
func ( *CodecMap) ( ToNetAddrFunc,  ...string) {
	.lk.Lock()
	defer .lk.Unlock()

	for ,  := range  {
		.maddrParsers[] = 
	}
}

func ( *CodecMap) ( string) (FromNetAddrFunc, error) {
	.lk.Lock()
	defer .lk.Unlock()

	,  := .addrParsers[]
	if ! {
		return nil, fmt.Errorf("unknown network %v", )
	}
	return , nil
}

func ( *CodecMap) ( string) (ToNetAddrFunc, error) {
	.lk.Lock()
	defer .lk.Unlock()
	,  := .maddrParsers[]
	if ! {
		return nil, fmt.Errorf("network not supported: %s", )
	}

	return , nil
}