package addrs

// Map represents a mapping whose keys are address types that implement
// UniqueKeyer.
//
// Since not all address types are comparable in the Go language sense, this
// type cannot work with the typical Go map access syntax, and so instead has
// a method-based syntax. Use this type only for situations where the key
// type isn't guaranteed to always be a valid key for a standard Go map.
type Map[K UniqueKeyer, V any] struct {
	// Elems is the internal data structure of the map.
	//
	// This is exported to allow for comparisons during tests and other similar
	// careful read operations, but callers MUST NOT modify this map directly.
	// Use only the methods of Map to modify the contents of this structure,
	// to ensure that it remains correct and consistent.
	Elems map[UniqueKey]MapElem[K, V]
}

type MapElem[K UniqueKeyer, V any] struct {
	Key   K
	Value V
}

func MakeMap[K UniqueKeyer, V any](initialElems ...MapElem[K, V]) Map[K, V] {
	inner := make(map[UniqueKey]MapElem[K, V], len(initialElems))
	ret := Map[K, V]{inner}
	for _, elem := range initialElems {
		ret.Put(elem.Key, elem.Value)
	}
	return ret
}

func MakeMapElem[K UniqueKeyer, V any](key K, value V) MapElem[K, V] {
	return MapElem[K, V]{key, value}
}

// Put inserts a new element into the map, or replaces an existing element
// which has an equivalent key.
func (m Map[K, V]) Put(key K, value V) {
	realKey := key.UniqueKey()
	m.Elems[realKey] = MapElem[K, V]{key, value}
}

// PutElement is like Put but takes the key and value from the given MapElement
// structure instead of as individual arguments.
func (m Map[K, V]) PutElement(elem MapElem[K, V]) {
	m.Put(elem.Key, elem.Value)
}

// Remove deletes the element with the given key from the map, or does nothing
// if there is no such element.
func (m Map[K, V]) Remove(key K) {
	realKey := key.UniqueKey()
	delete(m.Elems, realKey)
}

// Get returns the value of the element with the given key, or the zero value
// of V if there is no such element.
func (m Map[K, V]) Get(key K) V {
	realKey := key.UniqueKey()
	return m.Elems[realKey].Value
}

// GetOk is like Get but additionally returns a flag for whether there was an
// element with the given key present in the map.
func (m Map[K, V]) GetOk(key K) (V, bool) {
	realKey := key.UniqueKey()
	elem, ok := m.Elems[realKey]
	return elem.Value, ok
}

// Has returns true if and only if there is an element in the map which has the
// given key.
func (m Map[K, V]) Has(key K) bool {
	realKey := key.UniqueKey()
	_, ok := m.Elems[realKey]
	return ok
}

// Len returns the number of elements in the map.
func (m Map[K, V]) Len() int {
	return len(m.Elems)
}

// Elements returns a slice containing a snapshot of the current elements of
// the map, in an unpredictable order.
func (m Map[K, V]) Elements() []MapElem[K, V] {
	if len(m.Elems) == 0 {
		return nil
	}
	ret := make([]MapElem[K, V], 0, len(m.Elems))
	for _, elem := range m.Elems {
		ret = append(ret, elem)
	}
	return ret
}

// Keys returns a Set[K] containing a snapshot of the current keys of elements
// of the map.
func (m Map[K, V]) Keys() Set[K] {
	if len(m.Elems) == 0 {
		return nil
	}
	ret := make(Set[K], len(m.Elems))

	// We mess with the internals of Set here, rather than going through its
	// public interface, because that means we can avoid re-calling UniqueKey
	// on all of the elements when we know that our own Put method would have
	// already done the same thing.
	for realKey, elem := range m.Elems {
		ret[realKey] = elem.Key
	}
	return ret
}

// Values returns a slice containing a snapshot of the current values of
// elements of the map, in an unpredictable order.
func (m Map[K, V]) Values() []V {
	if len(m.Elems) == 0 {
		return nil
	}
	ret := make([]V, 0, len(m.Elems))
	for _, elem := range m.Elems {
		ret = append(ret, elem.Value)
	}
	return ret
}
