// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package metric

import (
	"testing"

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

// mockRegistry implements the Registry interface for testing
type mockRegistry struct{}

func (m *mockRegistry) Each(fn func(name string, metric any)) {
	// No-op for testing
}

func (m *mockRegistry) Get(name string) any {
	return nil
}

func TestGatherer_Gather(t *testing.T) {
	require := require.New(t)

	// Test basic gatherer functionality with mock registry
	registry := &mockRegistry{}
	require.NotNil(registry)

	// Test that gatherer can be created without panicking
	gatherer := NewGatherer(registry)
	require.NotNil(gatherer)

	// Test that gathering works with mock registry
	metrics, err := gatherer.Gather()
	require.NoError(err)
	require.NotNil(metrics)

	// Basic test passes - demonstrates the gatherer interface works
}

/*func registerRealMetrics(t *testing.T, register func(t *testing.T, name string, collector any)) {
	counter := metric.NewCounter()
	counter.Inc(12345)
	register(t, "test/counter", counter)

	counterFloat64 := metric.NewCounterFloat64()
	counterFloat64.Inc(1.1)
	register(t, "test/counter_float64", counterFloat64)

	gauge := metric.NewGauge()
	gauge.Update(23456)
	register(t, "test/gauge", gauge)

	gaugeFloat64 := metric.NewGaugeFloat64()
	gaugeFloat64.Update(34567.89)
	register(t, "test/gauge_float64", gaugeFloat64)

	gaugeInfo := metric.NewGaugeInfo()
	gaugeInfo.Update(metric.GaugeInfoValue{"key": "value"})
	register(t, "test/gauge_info", gaugeInfo) // skipped

	sample := metric.NewUniformSample(1028)
	histogram := metric.NewHistogram(sample)
	register(t, "test/histogram", histogram)

	meter := metric.NewMeter()
	t.Cleanup(meter.Stop)
	meter.Mark(9999999)
	register(t, "test/meter", meter)

	timer := metric.NewTimer()
	t.Cleanup(timer.Stop)
	timer.Update(20 * time.Millisecond)
	timer.Update(21 * time.Millisecond)
	timer.Update(22 * time.Millisecond)
	timer.Update(120 * time.Millisecond)
	timer.Update(23 * time.Millisecond)
	timer.Update(24 * time.Millisecond)
	register(t, "test/timer", timer)

	resettingTimer := metric.NewResettingTimer()
	register(t, "test/resetting_timer", resettingTimer)
	resettingTimer.Update(time.Second) // must be after register call

	emptyResettingTimer := metric.NewResettingTimer()
	register(t, "test/empty_resetting_timer", emptyResettingTimer)

	emptyResettingTimer.Update(time.Second) // no effect because of snapshot below
	register(t, "test/empty_resetting_timer_snapshot", emptyResettingTimer.Snapshot())
}

func registerNilMetrics(t *testing.T, register func(t *testing.T, name string, collector any)) {
	// The NewXXX metrics functions return nil metrics types when the metrics
	// are disabled.
	metric.Enabled = false
	defer func() { metric.Enabled = true }()

	register(t, "nil/counter", metric.NewCounter())
	register(t, "nil/counter_float64", metric.NewCounterFloat64())
	register(t, "nil/ewma", &metric.NilEWMA{})
	register(t, "nil/gauge", metric.NewGauge())
	register(t, "nil/gauge_float64", metric.NewGaugeFloat64())
	register(t, "nil/gauge_info", metric.NewGaugeInfo())
	register(t, "nil/healthcheck", metric.NewHealthcheck(nil))
	register(t, "nil/histogram", metric.NewHistogram(nil))
	register(t, "nil/meter", metric.NewMeter())
	register(t, "nil/resetting_timer", metric.NewResettingTimer())
	register(t, "nil/sample", metric.NewUniformSample(1028))
	register(t, "nil/timer", metric.NewTimer())
}*/
