// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1

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.
//
// This implementation of Map is specific to our [UniqueKey] and [UniqueKeyer]
// convention here in package addrs, which predated Go supporting type
// parameters. For types outside of addrs consider using the generalized version
// in sibling package "collections". Perhaps one day we'll rework this
// addrs-specific implementation to use [collections.Map] instead.
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
}
