// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Code generated by mdatagen. DO NOT EDIT.

package {{ .Package }}

import (
	"go.opentelemetry.io/collector/config"
	"go.opentelemetry.io/collector/model/pdata"
)

// Type is the component type name.
const Type config.Type = "{{ .Name }}"

// MetricIntf is an interface to generically interact with generated metric.
type MetricIntf interface {
	Name() string
	New() pdata.Metric
	Init(metric pdata.Metric)
}

// Intentionally not exposing this so that it is opaque and can change freely.
type metricImpl struct {
	name string
	initFunc func(pdata.Metric)
}

// Name returns the metric name.
func (m *metricImpl) Name() string {
	return m.name
}

// New creates a metric object preinitialized.
func (m *metricImpl) New() pdata.Metric {
	metric := pdata.NewMetric()
	m.Init(metric)
	return metric
}

// Init initializes the provided metric object.
func (m *metricImpl) Init(metric pdata.Metric) {
	m.initFunc(metric)
}

type metricStruct struct {
	{{- range $name, $metric := .Metrics }}
	{{ $name.Render }} MetricIntf
	{{- end }}
}

// Names returns a list of all the metric name strings.
func (m *metricStruct) Names() []string {
    return []string {
    {{- range $name, $metric := .Metrics }}
        "{{ $name }}",
    {{- end }}
    }
}

var metricsByName = map[string]MetricIntf {
{{- range $name, $metric := .Metrics }}
  "{{ $name }}": Metrics.{{ $name.Render }},
{{- end }}
}

func (m *metricStruct) ByName(n string) MetricIntf {
    return metricsByName[n]
}

func (m *metricStruct) FactoriesByName() map[string]func(pdata.Metric) {
    return map[string]func(pdata.Metric) {
    {{- range $name, $metric := .Metrics }}
      Metrics.{{ $name.Render }}.Name(): Metrics.{{ $name.Render }}.Init,
    {{- end }}
    }
}


{{- /* Renders metric descriptors. */}}
// Metrics contains a set of methods for each metric that help with
// manipulating those metrics.
var Metrics = &metricStruct{
	{{- range $name, $metric := .Metrics }}
	&metricImpl{
		"{{ $name }}",
		func(metric pdata.Metric) {
			metric.SetName("{{ $name }}")
			metric.SetDescription("{{ $metric.Description }}")
			metric.SetUnit("{{ $metric.Unit }}")
			metric.SetDataType(pdata.MetricDataType{{ $metric.Data.Type }})
			{{- if $metric.Data.HasMonotonic }}
			metric.{{ $metric.Data.Type }}().SetIsMonotonic({{ $metric.Data.Monotonic }})
			{{- end }}
			{{- if $metric.Data.HasAggregated }}
			metric.{{ $metric.Data.Type }}().SetAggregationTemporality({{ $metric.Data.Aggregated.Type }})
			{{- end }}
		},
	},
	{{- end }}
}

// M contains a set of methods for each metric that help with
// manipulating those metrics. M is an alias for Metrics
var M = Metrics

{{- /* Renders label names. */}}
// Labels contains the possible metric labels that can be used.
var Labels = struct {
    {{- range $name, $info := .Labels }}
    // {{ $name.Render }} ({{ $info.Description }})
    {{ $name.Render }} string
    {{- end }}
}{
    {{- range $name, $info := .Labels }}
    {{- if $info.Value }}
    "{{ $info.Value }}",
    {{- else }}
    "{{ $name }}",
    {{- end }}
    {{- end }}
}

// L contains the possible metric labels that can be used. L is an alias for
// Labels.
var L = Labels

{{- /* Renders label enum values. */}}

{{ range $name, $info := .Labels }}
{{ if $info.Enum }}
// Label{{ $name.Render }} are the possible values that the label "{{ $name }}" can have.
var Label{{ $name.Render }} = struct {
    {{- range $info.Enum }}
    {{ . | publicVar }} string
    {{- end }}
}{
    {{- range $info.Enum }}
    "{{ . }}",
    {{- end }}
}
{{- end }}
{{- end }}
