package metrics

import (
	"strings"
	"testing"

	"github.com/prometheus/client_golang/prometheus"
	"github.com/stretchr/testify/require"
)

func TestDescribeAll(t *testing.T) {
	const (
		namespace = "my_ns"
		subsystem = "mysub"
	)
	mustRegister(newCounter(prometheus.CounterOpts{
		Namespace: namespace,
		Subsystem: subsystem,
		Name:      "my_counter",
	}))

	labels := []string{"label1", "label2"}
	mustRegister(newGaugeVec(prometheus.GaugeOpts{
		Namespace: namespace,
		Subsystem: subsystem,
		Name:      "my_gauge",
	}, labels))

	constLabels := prometheus.Labels{
		"const1": "abc",
		"const2": "xyz",
	}
	mustRegister(newCounter(prometheus.CounterOpts{
		Namespace:   namespace,
		Subsystem:   subsystem,
		Name:        "with_const_labels",
		ConstLabels: constLabels,
	}))

	descriptions, err := DescribeAll()
	require.NoError(t, err)

	seen := make(map[string]bool)
	for i := range descriptions {
		if !strings.HasPrefix(descriptions[i].Name, namespace) {
			continue
		}

		require.False(t, seen[descriptions[i].Name], "metric %s was seen twice", descriptions[i].Name)
		seen[descriptions[i].Name] = true

		switch descriptions[i].Name {
		case prometheus.BuildFQName(namespace, subsystem, "my_counter"):
			require.True(t, len(descriptions[i].VariableLabels) == 0)
		case prometheus.BuildFQName(namespace, subsystem, "my_gauge"):
			require.Equal(t, labels, descriptions[i].VariableLabels)
		case prometheus.BuildFQName(namespace, subsystem, "with_const_labels"):
			require.Equal(t, len(constLabels), len(descriptions[i].ConstantLabels))
			require.Equal(t, constLabels, descriptions[i].ConstantLabels)
		default:
			require.FailNow(t, "unexpected metric name: %s", descriptions[i].Name)
		}
	}
	require.Equal(t, 3, len(seen), "not all registered metrics were iterated over")
}