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

package propagation // import "go.opentelemetry.io/otel/propagation"

import (
	

	
)

const baggageHeader = "baggage"

// Baggage is a propagator that supports the W3C Baggage format.
//
// This propagates user-defined baggage associated with a trace. The complete
// specification is defined at https://www.w3.org/TR/baggage/.
type Baggage struct{}

var _ TextMapPropagator = Baggage{}

// Inject sets baggage key-values from ctx into the carrier.
func (Baggage) ( context.Context,  TextMapCarrier) {
	 := baggage.FromContext().String()
	if  != "" {
		.Set(baggageHeader, )
	}
}

// Extract returns a copy of parent with the baggage from the carrier added.
// If carrier implements [ValuesGetter] (e.g. [HeaderCarrier]), Values is invoked
// for multiple values extraction. Otherwise, Get is called.
func (Baggage) ( context.Context,  TextMapCarrier) context.Context {
	if ,  := .(ValuesGetter);  {
		return extractMultiBaggage(, )
	}
	return extractSingleBaggage(, )
}

// Fields returns the keys who's values are set with Inject.
func (Baggage) () []string {
	return []string{baggageHeader}
}

func extractSingleBaggage( context.Context,  TextMapCarrier) context.Context {
	 := .Get(baggageHeader)
	if  == "" {
		return 
	}

	,  := baggage.Parse()
	if  != nil {
		return 
	}
	return baggage.ContextWithBaggage(, )
}

func extractMultiBaggage( context.Context,  ValuesGetter) context.Context {
	 := .Values(baggageHeader)
	if len() == 0 {
		return 
	}
	var  []baggage.Member
	for ,  := range  {
		,  := baggage.Parse()
		if  != nil {
			continue
		}
		 = append(, .Members()...)
	}

	,  := baggage.New(...)
	if  != nil || .Len() == 0 {
		return 
	}
	return baggage.ContextWithBaggage(, )
}