// 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
	ExporterEnqueueFailedSpans        metric.Int64Counter
	ExporterQueueBatchSendSize        metric.Int64Histogram
	ExporterQueueBatchSendSizeBytes   metric.Int64Histogram
	ExporterQueueCapacity             metric.Int64ObservableGauge
	ExporterQueueSize                 metric.Int64ObservableGauge
	ExporterSendFailedLogRecords      metric.Int64Counter
	ExporterSendFailedMetricPoints    metric.Int64Counter
	ExporterSendFailedSpans           metric.Int64Counter
	ExporterSentLogRecords            metric.Int64Counter
	ExporterSentMetricPoints          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("{records}"),
	)
	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("{datapoints}"),
	)
	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("{spans}"),
	)
	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("{units}"),
		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("{batches}"),
	)
	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("{batches}"),
	)
	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. [Alpha]"),
		metric.WithUnit("{records}"),
	)
	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. [Alpha]"),
		metric.WithUnit("{datapoints}"),
	)
	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. [Alpha]"),
		metric.WithUnit("{spans}"),
	)
	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("{records}"),
	)
	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("{datapoints}"),
	)
	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("{spans}"),
	)
	errs = errors.Join(errs, err)
	return &builder, errs
}
