package yamlutil

import (
	"cmp"
	"slices"

	"gopkg.in/yaml.v3"
)

// OrderedMap is like a normal map, except that when it is marshaled to yaml it
// will do so with its keys in ascending order. This makes it useful when
// generating output which needs to be deterministic.
type OrderedMap[K comparable, V any] map[K]V

func (m OrderedMap[K, V]) MarshalYAML() (any, error) {
	type wrapped map[K]V

	var n yaml.Node
	if err := n.Encode(wrapped(m)); err != nil {
		return nil, err
	}

	pairs := make([][2]*yaml.Node, len(n.Content)/2)
	for i := range pairs {
		pairs[i][0] = n.Content[i*2]
		pairs[i][1] = n.Content[i*2+1]
	}

	slices.SortFunc(pairs, func(a, b [2]*yaml.Node) int {
		return cmp.Compare(a[0].Value, b[0].Value)
	})

	for i := range pairs {
		n.Content[i*2] = pairs[i][0]
		n.Content[i*2+1] = pairs[i][1]
	}

	return n, nil
}