// 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(, , &, &, &.spanContext)

	.sampled.Store()

	 = 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) {}

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 {
		.DroppedLinks = uint32(len())
	} else {
		if  > 0 {
			 := max(len()-, 0)
			.DroppedLinks = uint32()
			 = [:]
		}
		.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.
}