// Code generated by mdatagen. DO NOT EDIT.

package metadata

import (
	"testing"

	"github.com/stretchr/testify/assert"
	"go.uber.org/zap"
	"go.uber.org/zap/zaptest/observer"

	"go.opentelemetry.io/collector/pdata/pcommon"
	"go.opentelemetry.io/collector/pdata/pmetric"
	"go.opentelemetry.io/collector/receiver/receivertest"
)

type testDataSet int

const (
	testDataSetDefault testDataSet = iota
	testDataSetAll
	testDataSetNone
	testDataSetReag
)

func TestMetricsBuilder(t *testing.T) {
	tests := []struct {
		name        string
		metricsSet  testDataSet
		resAttrsSet testDataSet
		expectEmpty bool
	}{
		{
			name: "default",
		},
		{
			name:        "all_set",
			metricsSet:  testDataSetAll,
			resAttrsSet: testDataSetAll,
		},
		{
			name:        "reaggregate_set",
			metricsSet:  testDataSetReag,
			resAttrsSet: testDataSetReag,
		},
		{
			name:        "none_set",
			metricsSet:  testDataSetNone,
			resAttrsSet: testDataSetNone,
			expectEmpty: true,
		},
		{
			name:        "filter_set_include",
			resAttrsSet: testDataSetAll,
		},
		{
			name:        "filter_set_exclude",
			resAttrsSet: testDataSetAll,
			expectEmpty: true,
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			start := pcommon.Timestamp(1_000_000_000)
			ts := pcommon.Timestamp(1_000_001_000)
			observedZapCore, observedLogs := observer.New(zap.WarnLevel)
			settings := receivertest.NewNopSettings(receivertest.NopType)
			settings.Logger = zap.New(observedZapCore)
			mb := NewMetricsBuilder(loadMetricsBuilderConfig(t, tt.name), settings, WithStartTime(start))
			aggMap := make(map[string]string) // contains the aggregation strategies for each metric name
			aggMap["k8s.pod.phase"] = mb.metricK8sPodPhase.config.AggregationStrategy

			expectedWarnings := 0
			if tt.metricsSet != testDataSetReag {
				assert.Equal(t, expectedWarnings, observedLogs.Len())
			}

			defaultMetricsCount := 0
			allMetricsCount := 0
			ebK8sReplicaset := mb.ForK8sReplicaset(NewK8sReplicasetEntity("k8s.replicaset.uid-val"))
			ebK8sPod := mb.ForK8sPod(NewK8sPodEntity("k8s.pod.uid-val"))
			defaultMetricsCount++
			allMetricsCount++
			ebK8sPod.RecordK8sPodCPUTimeDataPoint(ts, 1)
			defaultMetricsCount++
			allMetricsCount++
			ebK8sPod.RecordK8sPodPhaseDataPoint(ts, 1, AttributePhasePending)
			if tt.name == "reaggregate_set" {
				ebK8sPod.RecordK8sPodPhaseDataPoint(ts, 3, AttributePhaseRunning)
			}
			defaultMetricsCount++
			allMetricsCount++
			ebK8sReplicaset.RecordK8sReplicasetDesiredDataPoint(ts, 1)
			ebK8sReplicaset.Emit()
			ebK8sPod.Emit()

			rb := mb.NewResourceBuilder()
			rb.SetK8sNamespaceName("k8s.namespace.name-val")
			rb.SetK8sPodName("k8s.pod.name-val")
			rb.SetK8sPodUID("k8s.pod.uid-val")
			rb.SetK8sReplicasetName("k8s.replicaset.name-val")
			rb.SetK8sReplicasetUID("k8s.replicaset.uid-val")
			res := rb.Emit()
			metrics := mb.Emit(WithResource(res))
			if tt.name == "reaggregate_set" {
				assert.Empty(t, mb.metricK8sPodPhase.aggDataPoints)
			}

			if tt.expectEmpty {
				assert.Equal(t, 0, metrics.ResourceMetrics().Len())
				return
			}

			var allMetricsList []pmetric.Metric
			totalMetricsCount := 0
			for ri := 0; ri < metrics.ResourceMetrics().Len(); ri++ {
				rm := metrics.ResourceMetrics().At(ri)
				assert.Equal(t, 1, rm.ScopeMetrics().Len())
				ms := rm.ScopeMetrics().At(0).Metrics()
				totalMetricsCount += ms.Len()
				for mi := 0; mi < ms.Len(); mi++ {
					allMetricsList = append(allMetricsList, ms.At(mi))
				}
			}
			if tt.metricsSet == testDataSetDefault {
				assert.Equal(t, defaultMetricsCount, totalMetricsCount)
			}
			if tt.metricsSet == testDataSetAll {
				assert.Equal(t, allMetricsCount, totalMetricsCount)
			}
			validatedMetrics := make(map[string]bool)
			for _, mi := range allMetricsList {
				switch mi.Name() {
				case "k8s.pod.cpu_time":
					assert.False(t, validatedMetrics["k8s.pod.cpu_time"], "Found a duplicate in the metrics slice: k8s.pod.cpu_time")
					validatedMetrics["k8s.pod.cpu_time"] = true
					assert.Equal(t, pmetric.MetricTypeSum, mi.Type())
					assert.Equal(t, 1, mi.Sum().DataPoints().Len())
					assert.Equal(t, "CPU time consumed by the pod", mi.Description())
					assert.Equal(t, "s", mi.Unit())
					assert.True(t, mi.Sum().IsMonotonic())
					assert.Equal(t, pmetric.AggregationTemporalityCumulative, mi.Sum().AggregationTemporality())
					dp := mi.Sum().DataPoints().At(0)
					assert.Equal(t, start, dp.StartTimestamp())
					assert.Equal(t, ts, dp.Timestamp())
					assert.Equal(t, pmetric.NumberDataPointValueTypeDouble, dp.ValueType())
					assert.InDelta(t, float64(1), dp.DoubleValue(), 0.01)
				case "k8s.pod.phase":
					if tt.name != "reaggregate_set" {
						assert.False(t, validatedMetrics["k8s.pod.phase"], "Found a duplicate in the metrics slice: k8s.pod.phase")
						validatedMetrics["k8s.pod.phase"] = true
						assert.Equal(t, pmetric.MetricTypeGauge, mi.Type())
						assert.Equal(t, 1, mi.Gauge().DataPoints().Len())
						assert.Equal(t, "Current phase of the pod", mi.Description())
						assert.Equal(t, "1", mi.Unit())
						dp := mi.Gauge().DataPoints().At(0)
						assert.Equal(t, start, dp.StartTimestamp())
						assert.Equal(t, ts, dp.Timestamp())
						assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType())
						assert.Equal(t, int64(1), dp.IntValue())
						phaseAttrVal, ok := dp.Attributes().Get("phase")
						assert.True(t, ok)
						assert.Equal(t, "Pending", phaseAttrVal.Str())
					} else {
						assert.False(t, validatedMetrics["k8s.pod.phase"], "Found a duplicate in the metrics slice: k8s.pod.phase")
						validatedMetrics["k8s.pod.phase"] = true
						assert.Equal(t, pmetric.MetricTypeGauge, mi.Type())
						assert.Equal(t, 1, mi.Gauge().DataPoints().Len())
						assert.Equal(t, "Current phase of the pod", mi.Description())
						assert.Equal(t, "1", mi.Unit())
						dp := mi.Gauge().DataPoints().At(0)
						assert.Equal(t, start, dp.StartTimestamp())
						assert.Equal(t, ts, dp.Timestamp())
						assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType())
						switch aggMap["k8s.pod.phase"] {
						case "sum":
							assert.Equal(t, int64(4), dp.IntValue())
						case "avg":
							assert.Equal(t, int64(2), dp.IntValue())
						case "min":
							assert.Equal(t, int64(1), dp.IntValue())
						case "max":
							assert.Equal(t, int64(3), dp.IntValue())
						}
						_, ok := dp.Attributes().Get("phase")
						assert.False(t, ok)
					}
				case "k8s.replicaset.desired":
					assert.False(t, validatedMetrics["k8s.replicaset.desired"], "Found a duplicate in the metrics slice: k8s.replicaset.desired")
					validatedMetrics["k8s.replicaset.desired"] = true
					assert.Equal(t, pmetric.MetricTypeGauge, mi.Type())
					assert.Equal(t, 1, mi.Gauge().DataPoints().Len())
					assert.Equal(t, "Number of desired replicas", mi.Description())
					assert.Equal(t, "{replicas}", mi.Unit())
					dp := mi.Gauge().DataPoints().At(0)
					assert.Equal(t, start, dp.StartTimestamp())
					assert.Equal(t, ts, dp.Timestamp())
					assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType())
					assert.Equal(t, int64(1), dp.IntValue())
				}
			}
		})
	}
}
