package metrics

import (
	"testing"

	"github.com/prometheus/client_golang/prometheus"
	dto "github.com/prometheus/client_model/go"
)

func TestObserveReconcileFailure(t *testing.T) {
	resourceName := "resource-1"
	controllerName := "Cluster"

	ReconcileFailedCounter.DeleteLabelValues(resourceName, controllerName)
	defer ReconcileFailedCounter.DeleteLabelValues(resourceName, controllerName)

	ObserveReconcileFailure(resourceName, controllerName)

	if got := counterValue(t, ReconcileFailedCounter.WithLabelValues(resourceName, controllerName)); got != 1 {
		t.Fatalf("expected reconcile failure counter to be 1, got %v", got)
	}
}

func TestObserveReconcileFailureDefaultsUnknownResource(t *testing.T) {
	ReconcileFailedCounter.DeleteLabelValues(UnknownReconcileResourceName, UnknownReconcileController)
	defer ReconcileFailedCounter.DeleteLabelValues(UnknownReconcileResourceName, UnknownReconcileController)

	ObserveReconcileFailure("", "")

	if got := counterValue(t, ReconcileFailedCounter.WithLabelValues(UnknownReconcileResourceName, UnknownReconcileController)); got != 1 {
		t.Fatalf("expected reconcile failure counter to be 1, got %v", got)
	}
}

func TestClearReconcileFailure(t *testing.T) {
	resourceName := "resource-2"
	controllerName := "Branch"

	ReconcileFailedCounter.DeleteLabelValues(resourceName, controllerName)
	ObserveReconcileFailure(resourceName, controllerName)

	ClearReconcileFailure(resourceName)

	if got := counterValue(t, ReconcileFailedCounter.WithLabelValues(resourceName, controllerName)); got != 0 {
		t.Fatalf("expected reconcile failure counter to be 0, got %v", got)
	}
}

func counterValue(t *testing.T, counter prometheus.Counter) float64 {
	t.Helper()

	metric := &dto.Metric{}
	if err := counter.Write(metric); err != nil {
		t.Fatalf("write metric: %v", err)
	}
	return metric.GetCounter().GetValue()
}
