// Code generated by mdatagen. DO NOT EDIT.

package {{ .Package }}

import (
	"testing"

	"github.com/stretchr/testify/assert"
	"go.opentelemetry.io/collector/pdata/pcommon"
	"go.opentelemetry.io/collector/pdata/pmetric"
	"go.opentelemetry.io/collector/receiver/receivertest"
	"go.uber.org/zap"
	"go.uber.org/zap/zaptest/observer"
)


type testConfigCollection int

const (
	testSetDefault testConfigCollection = iota
	testSetAll
	testSetNone
)

func TestMetricsBuilder(t *testing.T) {
	tests := []struct {
		name      string
		configSet testConfigCollection
	}{
		{
			name:       "default",
			configSet: testSetDefault,
		},
		{
			name:       "all_set",
			configSet: testSetAll,
		},
		{
			name:       "none_set",
			configSet: testSetNone,
		},
	}
	for _, test := range tests {
		t.Run(test.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.NewNopCreateSettings()
			settings.Logger = zap.New(observedZapCore)
			mb := NewMetricsBuilder(loadMetricsBuilderConfig(t, test.name), settings, WithStartTime(start))

			expectedWarnings := 0
			{{- range $name, $metric := .Metrics }}
			{{- if and $metric.Enabled $metric.Warnings.IfEnabled }}
			if test.configSet == testSetDefault || test.configSet == testSetAll {
				assert.Equal(t, "[WARNING] `{{ $name }}` should not be enabled: {{ $metric.Warnings.IfEnabled }}", observedLogs.All()[expectedWarnings].Message)
				expectedWarnings++
			}
			{{- end }}
			{{- if $metric.Warnings.IfEnabledNotSet }}
			if test.configSet == testSetDefault {
				assert.Equal(t, "[WARNING] Please set `enabled` field explicitly for `{{ $name }}`: {{ $metric.Warnings.IfEnabledNotSet }}", observedLogs.All()[expectedWarnings].Message)
				expectedWarnings++
			}
			{{- end }}
			{{- if $metric.Warnings.IfConfigured }}
			if test.configSet == testSetAll || test.configSet == testSetNone {
				assert.Equal(t, "[WARNING] `{{ $name }}` should not be configured: {{ $metric.Warnings.IfConfigured }}", observedLogs.All()[expectedWarnings].Message)
				expectedWarnings++
			}
			{{- end }}
			{{- end }}
			{{- range $name, $attr := .ResourceAttributes }}
			{{- if and $attr.Enabled $attr.Warnings.IfEnabled }}
			if test.configSet == testSetDefault || test.configSet == testSetAll {
				assert.Equal(t, "[WARNING] `{{ $name }}` should not be enabled: {{ $attr.Warnings.IfEnabled }}", observedLogs.All()[expectedWarnings].Message)
				expectedWarnings++
			}
			{{- end }}
			{{- if $attr.Warnings.IfEnabledNotSet }}
			if test.configSet == testSetDefault {
				assert.Equal(t, "[WARNING] Please set `enabled` field explicitly for `{{ $name }}`: {{ $attr.Warnings.IfEnabledNotSet }}", observedLogs.All()[expectedWarnings].Message)
				expectedWarnings++
			}
			{{- end }}
			{{- if $attr.Warnings.IfConfigured }}
			if test.configSet == testSetAll || test.configSet == testSetNone {
				assert.Equal(t, "[WARNING] `{{ $name }}` should not be configured: {{ $attr.Warnings.IfConfigured }}", observedLogs.All()[expectedWarnings].Message)
				expectedWarnings++
			}
			{{- end }}
			{{- end }}


			assert.Equal(t, expectedWarnings, observedLogs.Len())

			defaultMetricsCount := 0
			allMetricsCount := 0
			{{- range $name, $metric := .Metrics }}

				{{ if $metric.Enabled }}defaultMetricsCount++{{ end }}
				allMetricsCount++
				mb.Record{{ $name.Render }}DataPoint(ts, {{ if $metric.Data.HasMetricInputType }}"1"{{ else }}1{{ end }}
				{{- range $metric.Attributes -}}
					, {{ if (attributeInfo .).Enum }}Attribute{{ .Render }}{{ (index (attributeInfo .).Enum 0) | publicVar }}{{ else }}{{ (attributeInfo .).TestValue }}{{ end }}
				{{- end }})
			{{- end }}

			{{ if .ResourceAttributes }}
			rb := mb.NewResourceBuilder()
			{{- range $name, $attr := .ResourceAttributes }}
			{{- if $attr.Enum }}
			rb.Set{{ $attr.Name.Render }}{{ index $attr.Enum 0 | publicVar }}()
			{{- else }}
			rb.Set{{ $attr.Name.Render }}({{ $attr.TestValue }})
			{{- end }}
			{{- end }}
			res := rb.Emit()
			{{- else }}
			res := pcommon.NewResource()
			{{- end }}
			metrics := mb.Emit(WithResource(res))

			if test.configSet == testSetNone {
				assert.Equal(t, 0, metrics.ResourceMetrics().Len())
				return
			}

			assert.Equal(t, 1, metrics.ResourceMetrics().Len())
			rm := metrics.ResourceMetrics().At(0)
			assert.Equal(t, res, rm.Resource())
			assert.Equal(t, 1, rm.ScopeMetrics().Len())
			ms := rm.ScopeMetrics().At(0).Metrics()
			if test.configSet == testSetDefault {
				assert.Equal(t, defaultMetricsCount, ms.Len())
			}
			if test.configSet == testSetAll {
				assert.Equal(t, allMetricsCount, ms.Len())
			}
			validatedMetrics := make(map[string]bool)
			for i := 0; i < ms.Len(); i++ {
				switch ms.At(i).Name() {
				{{- range $name, $metric := .Metrics }}
				case "{{ $name }}":
					assert.False(t, validatedMetrics["{{ $name }}"], "Found a duplicate in the metrics slice: {{ $name }}")
					validatedMetrics["{{ $name }}"] = true
					assert.Equal(t, pmetric.MetricType{{ $metric.Data.Type }}, ms.At(i).Type())
					assert.Equal(t, 1, ms.At(i).{{ $metric.Data.Type }}().DataPoints().Len())
					assert.Equal(t, "{{ $metric.Description }}", ms.At(i).Description())
					assert.Equal(t, "{{ $metric.Unit }}", ms.At(i).Unit())
					{{- if $metric.Data.HasMonotonic }}
					assert.Equal(t, {{ $metric.Data.Monotonic }}, ms.At(i).{{ $metric.Data.Type }}().IsMonotonic())
					{{- end }}
					{{- if $metric.Data.HasAggregated }}
					assert.Equal(t, pmetric.AggregationTemporality{{ $metric.Data.AggregationTemporality }}, ms.At(i).{{ $metric.Data.Type }}().AggregationTemporality())
					{{- end }}
					dp := ms.At(i).{{ $metric.Data.Type }}().DataPoints().At(0)
					assert.Equal(t, start, dp.StartTimestamp())
					assert.Equal(t, ts, dp.Timestamp())
					assert.Equal(t, pmetric.NumberDataPointValueType{{ $metric.Data.MetricValueType }}, dp.ValueType())
					assert.Equal(t, {{ $metric.Data.MetricValueType.BasicType }}(1), dp.{{ $metric.Data.MetricValueType }}Value())

					{{- range $i, $attr := $metric.Attributes }}
					attrVal, ok {{ if eq $i 0 }}:{{ end }}= dp.Attributes().Get("{{ (attributeInfo $attr).Name }}")
					assert.True(t, ok)
					assert.EqualValues(t, {{ (attributeInfo $attr).TestValue }}, attrVal.{{ (attributeInfo $attr).Type }}()
					{{- if or (eq (attributeInfo $attr).Type.String "Slice") (eq (attributeInfo $attr).Type.String "Map")}}.AsRaw(){{ end }})
					{{- end }}
				{{- end }}
				}
			}
		})
	}
}
