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

package sdk

import (
	
	
	

	
	

	
)

type tracer struct {
	noop.Tracer

	name, schemaURL, version string
}

var _ trace.Tracer = tracer{}

func ( tracer) (
	 context.Context,
	 string,
	 ...trace.SpanStartOption,
) (context.Context, trace.Span) {
	var ,  trace.SpanContext
	 := true
	 := new(span)

	// Ask eBPF for sampling decision and span context info.
	.start(, , &, &, &)

	.sampled.Store()
	.spanContext = 

	 = trace.ContextWithSpan(, )

	if  {
		// Only build traces if sampled.
		 := trace.NewSpanStartConfig(...)
		.traces, .span = .traces(, , .spanContext, )
	}

	return , 
}

// Expected to be implemented in eBPF.
//
//go:noinline
func ( *tracer) (
	 context.Context,
	 *span,
	 *trace.SpanContext,
	 *bool,
	 *trace.SpanContext,
) {
	start(, , , , )
}

// start is used for testing.
var start = func(context.Context, *span, *trace.SpanContext, *bool, *trace.SpanContext) {}

var intToUint32Bound = min(math.MaxInt, math.MaxUint32)

func ( tracer) (
	 string,
	 trace.SpanConfig,
	,  trace.SpanContext,
) (*telemetry.Traces, *telemetry.Span) {
	 := &telemetry.Span{
		TraceID:      telemetry.TraceID(.TraceID()),
		SpanID:       telemetry.SpanID(.SpanID()),
		Flags:        uint32(.TraceFlags()),
		TraceState:   .TraceState().String(),
		ParentSpanID: telemetry.SpanID(.SpanID()),
		Name:         ,
		Kind:         spanKind(.SpanKind()),
	}

	.Attrs, .DroppedAttrs = convCappedAttrs(maxSpan.Attrs, .Attributes())

	 := .Links()
	if  := maxSpan.Links;  == 0 {
		 := len()
		if  > 0 {
			 := max(min(, intToUint32Bound), 0)
			.DroppedLinks = uint32() //nolint:gosec  // Bounds checked.
		}
	} else {
		if  > 0 {
			 := max(len()-, 0)
			 := min(, intToUint32Bound)
			.DroppedLinks = uint32() //nolint:gosec  // Bounds checked.
			 = [:]
		}
		.Links = convLinks()
	}

	if  := .Timestamp(); !.IsZero() {
		.StartTime = .Timestamp()
	} else {
		.StartTime = time.Now()
	}

	return &telemetry.Traces{
		ResourceSpans: []*telemetry.ResourceSpans{
			{
				ScopeSpans: []*telemetry.ScopeSpans{
					{
						Scope: &telemetry.Scope{
							Name:    .name,
							Version: .version,
						},
						Spans:     []*telemetry.Span{},
						SchemaURL: .schemaURL,
					},
				},
			},
		},
	}, 
}

func spanKind( trace.SpanKind) telemetry.SpanKind {
	switch  {
	case trace.SpanKindInternal:
		return telemetry.SpanKindInternal
	case trace.SpanKindServer:
		return telemetry.SpanKindServer
	case trace.SpanKindClient:
		return telemetry.SpanKindClient
	case trace.SpanKindProducer:
		return telemetry.SpanKindProducer
	case trace.SpanKindConsumer:
		return telemetry.SpanKindConsumer
	}
	return telemetry.SpanKind(0) // undefined.
}