package dashboard

import (
	"testing"
	"time"

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

func TestRecord(t *testing.T) {
	agg := NewMetricsAggregator(1*time.Hour, 100)
	agg.Record("request_latency", 150.5)
	
	names := agg.GetMetricNames()
	assert.Equal(t, 1, len(names))
	assert.Equal(t, "request_latency", names[0])
}

func TestGetTimeSeries(t *testing.T) {
	agg := NewMetricsAggregator(1*time.Hour, 100)
	
	agg.Record("latency", 100)
	agg.Record("latency", 200)
	agg.Record("latency", 150)
	
	series := agg.GetTimeSeries("latency")
	assert.Equal(t, 3, len(series))
	assert.Equal(t, 100.0, series[0].Value)
	assert.Equal(t, 200.0, series[1].Value)
	assert.Equal(t, 150.0, series[2].Value)
}

func TestGetPercentile(t *testing.T) {
	agg := NewMetricsAggregator(1*time.Hour, 100)
	
	for i := 1; i <= 100; i++ {
		agg.Record("latency", float64(i))
	}
	
	p50, _ := agg.GetPercentile("latency", 50)
	p95, _ := agg.GetPercentile("latency", 95)
	p99, _ := agg.GetPercentile("latency", 99)
	
	assert.True(t, p50 > 40 && p50 < 60)
	assert.True(t, p95 > 90)
	assert.True(t, p99 > 95)
}

func TestGetAverage(t *testing.T) {
	agg := NewMetricsAggregator(1*time.Hour, 100)
	
	agg.Record("latency", 100)
	agg.Record("latency", 200)
	agg.Record("latency", 300)
	
	avg, _ := agg.GetAverage("latency")
	assert.Equal(t, 200.0, avg)
}

func TestGetMax(t *testing.T) {
	agg := NewMetricsAggregator(1*time.Hour, 100)
	
	agg.Record("latency", 100)
	agg.Record("latency", 500)
	agg.Record("latency", 300)
	
	max, _ := agg.GetMax("latency")
	assert.Equal(t, 500.0, max)
}

func TestGetMin(t *testing.T) {
	agg := NewMetricsAggregator(1*time.Hour, 100)
	
	agg.Record("latency", 100)
	agg.Record("latency", 500)
	agg.Record("latency", 50)
	
	min, _ := agg.GetMin("latency")
	assert.Equal(t, 50.0, min)
}

func TestGetLatest(t *testing.T) {
	agg := NewMetricsAggregator(1*time.Hour, 100)
	
	agg.Record("latency", 100)
	agg.Record("latency", 200)
	
	latest, _ := agg.GetLatest("latency")
	assert.Equal(t, 200.0, latest.Value)
}

func TestMultipleMetrics(t *testing.T) {
	agg := NewMetricsAggregator(1*time.Hour, 100)
	
	agg.Record("latency", 100)
	agg.Record("errors", 5)
	agg.Record("throughput", 1000)
	
	names := agg.GetMetricNames()
	assert.Equal(t, 3, len(names))
}

func TestClear(t *testing.T) {
	agg := NewMetricsAggregator(1*time.Hour, 100)
	
	agg.Record("latency", 100)
	agg.Clear()
	
	names := agg.GetMetricNames()
	assert.Equal(t, 0, len(names))
}

func TestGetCountInRange(t *testing.T) {
	agg := NewMetricsAggregator(1*time.Hour, 100)
	
	now := time.Now()
	agg.Record("latency", 100)
	agg.Record("latency", 200)
	
	count, _ := agg.GetCountInRange("latency", now.Add(-1*time.Minute), now.Add(1*time.Minute))
	assert.Equal(t, 2, count)
}

func TestNotFoundError(t *testing.T) {
	agg := NewMetricsAggregator(1*time.Hour, 100)
	
	_, err := agg.GetPercentile("nonexistent", 50)
	assert.Error(t, err)
	
	_, err = agg.GetAverage("nonexistent")
	assert.Error(t, err)
	
	_, err = agg.GetLatest("nonexistent")
	assert.Error(t, err)
}

func TestMaxSize(t *testing.T) {
	agg := NewMetricsAggregator(1*time.Hour, 5)
	
	for i := 0; i < 10; i++ {
		agg.Record("latency", float64(i))
	}
	
	series := agg.GetTimeSeries("latency")
	assert.Equal(t, 5, len(series))
}

func BenchmarkRecord(b *testing.B) {
	agg := NewMetricsAggregator(1*time.Hour, 1000)
	
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		agg.Record("latency", float64(i))
	}
}
