// Code generated by mdatagen. DO NOT EDIT.

package metadata

import (
	"context"
	"errors"
	"sync"

	"go.opentelemetry.io/otel/metric"
	"go.opentelemetry.io/otel/metric/embedded"
	"go.opentelemetry.io/otel/trace"

	"go.opentelemetry.io/collector/component"
)

func Meter(settings component.TelemetrySettings) metric.Meter {
	return settings.MeterProvider.Meter("go.opentelemetry.io/collector/exporter/exporterhelper")
}

func Tracer(settings component.TelemetrySettings) trace.Tracer {
	return settings.TracerProvider.Tracer("go.opentelemetry.io/collector/exporter/exporterhelper")
}

// TelemetryBuilder provides an interface for components to report telemetry
// as defined in metadata and user config.
type TelemetryBuilder struct {
	meter                               metric.Meter
	mu                                  sync.Mutex
	registrations                       []metric.Registration
	ExporterEnqueueFailedLogRecords     metric.Int64Counter
	ExporterEnqueueFailedMetricPoints   metric.Int64Counter
	ExporterEnqueueFailedProfileSamples metric.Int64Counter
	ExporterEnqueueFailedSpans          metric.Int64Counter
	ExporterQueueBatchSendSize          metric.Int64Histogram
	ExporterQueueBatchSendSizeBytes     metric.Int64Histogram
	ExporterQueueCapacity               metric.Int64ObservableGauge
	ExporterQueueSize                   metric.Int64ObservableGauge
	ExporterSendFailedLogRecords        metric.Int64Counter
	ExporterSendFailedMetricPoints      metric.Int64Counter
	ExporterSendFailedProfileSamples    metric.Int64Counter
	ExporterSendFailedSpans             metric.Int64Counter
	ExporterSentLogRecords              metric.Int64Counter
	ExporterSentMetricPoints            metric.Int64Counter
	ExporterSentProfileSamples          metric.Int64Counter
	ExporterSentSpans                   metric.Int64Counter
}

// TelemetryBuilderOption applies changes to default builder.
type TelemetryBuilderOption interface {
	apply(*TelemetryBuilder)
}

type telemetryBuilderOptionFunc func(mb *TelemetryBuilder)

func (tbof telemetryBuilderOptionFunc) apply(mb *TelemetryBuilder) {
	tbof(mb)
}

// RegisterExporterQueueCapacityCallback sets callback for observable ExporterQueueCapacity metric.
func (builder *TelemetryBuilder) RegisterExporterQueueCapacityCallback(cb metric.Int64Callback) error {
	reg, err := builder.meter.RegisterCallback(func(ctx context.Context, o metric.Observer) error {
		cb(ctx, &observerInt64{inst: builder.ExporterQueueCapacity, obs: o})
		return nil
	}, builder.ExporterQueueCapacity)
	if err != nil {
		return err
	}
	builder.mu.Lock()
	defer builder.mu.Unlock()
	builder.registrations = append(builder.registrations, reg)
	return nil
}

// RegisterExporterQueueSizeCallback sets callback for observable ExporterQueueSize metric.
func (builder *TelemetryBuilder) RegisterExporterQueueSizeCallback(cb metric.Int64Callback) error {
	reg, err := builder.meter.RegisterCallback(func(ctx context.Context, o metric.Observer) error {
		cb(ctx, &observerInt64{inst: builder.ExporterQueueSize, obs: o})
		return nil
	}, builder.ExporterQueueSize)
	if err != nil {
		return err
	}
	builder.mu.Lock()
	defer builder.mu.Unlock()
	builder.registrations = append(builder.registrations, reg)
	return nil
}

type observerInt64 struct {
	embedded.Int64Observer
	inst metric.Int64Observable
	obs  metric.Observer
}

func (oi *observerInt64) Observe(value int64, opts ...metric.ObserveOption) {
	oi.obs.ObserveInt64(oi.inst, value, opts...)
}

// Shutdown unregister all registered callbacks for async instruments.
func (builder *TelemetryBuilder) Shutdown() {
	builder.mu.Lock()
	defer builder.mu.Unlock()
	for _, reg := range builder.registrations {
		reg.Unregister()
	}
}

// NewTelemetryBuilder provides a struct with methods to update all internal telemetry
// for a component
func NewTelemetryBuilder(settings component.TelemetrySettings, options ...TelemetryBuilderOption) (*TelemetryBuilder, error) {
	builder := TelemetryBuilder{}
	for _, op := range options {
		op.apply(&builder)
	}
	builder.meter = Meter(settings)
	var err, errs error
	builder.ExporterEnqueueFailedLogRecords, err = builder.meter.Int64Counter(
		"otelcol_exporter_enqueue_failed_log_records",
		metric.WithDescription("Number of log records failed to be added to the sending queue. [Alpha]"),
		metric.WithUnit("{record}"),
	)
	errs = errors.Join(errs, err)
	builder.ExporterEnqueueFailedMetricPoints, err = builder.meter.Int64Counter(
		"otelcol_exporter_enqueue_failed_metric_points",
		metric.WithDescription("Number of metric points failed to be added to the sending queue. [Alpha]"),
		metric.WithUnit("{datapoint}"),
	)
	errs = errors.Join(errs, err)
	builder.ExporterEnqueueFailedProfileSamples, err = builder.meter.Int64Counter(
		"otelcol_exporter_enqueue_failed_profile_samples",
		metric.WithDescription("Number of profile samples failed to be added to the sending queue. [Development]"),
		metric.WithUnit("{sample}"),
	)
	errs = errors.Join(errs, err)
	builder.ExporterEnqueueFailedSpans, err = builder.meter.Int64Counter(
		"otelcol_exporter_enqueue_failed_spans",
		metric.WithDescription("Number of spans failed to be added to the sending queue. [Alpha]"),
		metric.WithUnit("{span}"),
	)
	errs = errors.Join(errs, err)
	builder.ExporterQueueBatchSendSize, err = builder.meter.Int64Histogram(
		"otelcol_exporter_queue_batch_send_size",
		metric.WithDescription("Number of units in the batch [Development]"),
		metric.WithUnit("{unit}"),
		metric.WithExplicitBucketBoundaries([]float64{10, 25, 50, 75, 100, 250, 500, 750, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 20000, 30000, 50000, 100000}...),
	)
	errs = errors.Join(errs, err)
	builder.ExporterQueueBatchSendSizeBytes, err = builder.meter.Int64Histogram(
		"otelcol_exporter_queue_batch_send_size_bytes",
		metric.WithDescription("Number of bytes in batch that was sent. Only available on detailed level. [Development]"),
		metric.WithUnit("By"),
		metric.WithExplicitBucketBoundaries([]float64{10, 25, 50, 75, 100, 250, 500, 750, 1000, 2000, 3000, 4000, 5000, 6000}...),
	)
	errs = errors.Join(errs, err)
	builder.ExporterQueueCapacity, err = builder.meter.Int64ObservableGauge(
		"otelcol_exporter_queue_capacity",
		metric.WithDescription("Fixed capacity of the retry queue (in batches). [Alpha]"),
		metric.WithUnit("{batch}"),
	)
	errs = errors.Join(errs, err)
	builder.ExporterQueueSize, err = builder.meter.Int64ObservableGauge(
		"otelcol_exporter_queue_size",
		metric.WithDescription("Current size of the retry queue (in batches). [Alpha]"),
		metric.WithUnit("{batch}"),
	)
	errs = errors.Join(errs, err)
	builder.ExporterSendFailedLogRecords, err = builder.meter.Int64Counter(
		"otelcol_exporter_send_failed_log_records",
		metric.WithDescription("Number of log records in failed attempts to send to destination. At detailed telemetry level, includes attributes: error.type (semantic convention), error.permanent. [Alpha]"),
		metric.WithUnit("{record}"),
	)
	errs = errors.Join(errs, err)
	builder.ExporterSendFailedMetricPoints, err = builder.meter.Int64Counter(
		"otelcol_exporter_send_failed_metric_points",
		metric.WithDescription("Number of metric points in failed attempts to send to destination. At detailed telemetry level, includes attributes: error.type (semantic convention), error.permanent. [Alpha]"),
		metric.WithUnit("{datapoint}"),
	)
	errs = errors.Join(errs, err)
	builder.ExporterSendFailedProfileSamples, err = builder.meter.Int64Counter(
		"otelcol_exporter_send_failed_profile_samples",
		metric.WithDescription("Number of profile samples in failed attempts to send to destination. At detailed telemetry level, includes attributes: error.type (semantic convention), error.permanent. [Development]"),
		metric.WithUnit("{sample}"),
	)
	errs = errors.Join(errs, err)
	builder.ExporterSendFailedSpans, err = builder.meter.Int64Counter(
		"otelcol_exporter_send_failed_spans",
		metric.WithDescription("Number of spans in failed attempts to send to destination. At detailed telemetry level, includes attributes: error.type (semantic convention), error.permanent. [Alpha]"),
		metric.WithUnit("{span}"),
	)
	errs = errors.Join(errs, err)
	builder.ExporterSentLogRecords, err = builder.meter.Int64Counter(
		"otelcol_exporter_sent_log_records",
		metric.WithDescription("Number of log record successfully sent to destination. [Alpha]"),
		metric.WithUnit("{record}"),
	)
	errs = errors.Join(errs, err)
	builder.ExporterSentMetricPoints, err = builder.meter.Int64Counter(
		"otelcol_exporter_sent_metric_points",
		metric.WithDescription("Number of metric points successfully sent to destination. [Alpha]"),
		metric.WithUnit("{datapoint}"),
	)
	errs = errors.Join(errs, err)
	builder.ExporterSentProfileSamples, err = builder.meter.Int64Counter(
		"otelcol_exporter_sent_profile_samples",
		metric.WithDescription("Number of profile samples successfully sent to destination. [Development]"),
		metric.WithUnit("{sample}"),
	)
	errs = errors.Join(errs, err)
	builder.ExporterSentSpans, err = builder.meter.Int64Counter(
		"otelcol_exporter_sent_spans",
		metric.WithDescription("Number of spans successfully sent to destination. [Alpha]"),
		metric.WithUnit("{span}"),
	)
	errs = errors.Join(errs, err)
	return &builder, errs
}
