// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

package otlptrace // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace"

import (
	
	
	
	

	
	tracesdk 
)

var errAlreadyStarted = errors.New("already started")

// Exporter exports trace data in the OTLP wire format.
type Exporter struct {
	client Client

	mu      sync.RWMutex
	started bool

	startOnce sync.Once
	stopOnce  sync.Once
}

// ExportSpans exports a batch of spans.
func ( *Exporter) ( context.Context,  []tracesdk.ReadOnlySpan) error {
	 := tracetransform.Spans()
	if len() == 0 {
		return nil
	}

	 := .client.UploadTraces(, )
	if  != nil {
		return fmt.Errorf("traces export: %w", )
	}
	return nil
}

// Start establishes a connection to the receiving endpoint.
func ( *Exporter) ( context.Context) error {
	 := errAlreadyStarted
	.startOnce.Do(func() {
		.mu.Lock()
		.started = true
		.mu.Unlock()
		 = .client.Start()
	})

	return 
}

// Shutdown flushes all exports and closes all connections to the receiving endpoint.
func ( *Exporter) ( context.Context) error {
	.mu.RLock()
	 := .started
	.mu.RUnlock()

	if ! {
		return nil
	}

	var  error

	.stopOnce.Do(func() {
		 = .client.Stop()
		.mu.Lock()
		.started = false
		.mu.Unlock()
	})

	return 
}

var _ tracesdk.SpanExporter = (*Exporter)(nil)

// New constructs a new Exporter and starts it.
func ( context.Context,  Client) (*Exporter, error) {
	 := NewUnstarted()
	if  := .Start();  != nil {
		return nil, 
	}
	return , nil
}

// NewUnstarted constructs a new Exporter and does not start it.
func ( Client) *Exporter {
	return &Exporter{
		client: ,
	}
}

// MarshalLog is the marshaling function used by the logging system to represent this Exporter.
func ( *Exporter) () any {
	return struct {
		   string
		 Client
	}{
		:   "otlptrace",
		: .client,
	}
}