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

package telemetry

import (
	
	
	
)

const (
	traceIDSize = 16
	spanIDSize  = 8
)

// TraceID is a custom data type that is used for all trace IDs.
type TraceID [traceIDSize]byte

// String returns the hex string representation form of a TraceID.
func ( TraceID) () string {
	return hex.EncodeToString([:])
}

// IsEmpty returns false if id contains at least one non-zero byte.
func ( TraceID) () bool {
	return  == [traceIDSize]byte{}
}

// MarshalJSON converts the trace ID into a hex string enclosed in quotes.
func ( TraceID) () ([]byte, error) {
	if .IsEmpty() {
		return []byte(`""`), nil
	}
	return marshalJSON([:])
}

// UnmarshalJSON inflates the trace ID from hex string, possibly enclosed in
// quotes.
func ( *TraceID) ( []byte) error {
	* = [traceIDSize]byte{}
	return unmarshalJSON([:], )
}

// SpanID is a custom data type that is used for all span IDs.
type SpanID [spanIDSize]byte

// String returns the hex string representation form of a SpanID.
func ( SpanID) () string {
	return hex.EncodeToString([:])
}

// IsEmpty returns true if the span ID contains at least one non-zero byte.
func ( SpanID) () bool {
	return  == [spanIDSize]byte{}
}

// MarshalJSON converts span ID into a hex string enclosed in quotes.
func ( SpanID) () ([]byte, error) {
	if .IsEmpty() {
		return []byte(`""`), nil
	}
	return marshalJSON([:])
}

// UnmarshalJSON decodes span ID from hex string, possibly enclosed in quotes.
func ( *SpanID) ( []byte) error {
	* = [spanIDSize]byte{}
	return unmarshalJSON([:], )
}

// marshalJSON converts id into a hex string enclosed in quotes.
func marshalJSON( []byte) ([]byte, error) {
	// Plus 2 quote chars at the start and end.
	 := hex.EncodedLen(len()) + 2

	 := make([]byte, )
	hex.Encode([1:-1], )
	[0], [-1] = '"', '"'

	return , nil
}

// unmarshalJSON inflates trace id from hex string, possibly enclosed in quotes.
func unmarshalJSON( []byte,  []byte) error {
	if  := len();  >= 2 && [0] == '"' && [-1] == '"' {
		 = [1 : -1]
	}
	 := len()
	if  == 0 {
		return nil
	}

	if len() != hex.DecodedLen() {
		return errors.New("invalid length for ID")
	}

	,  := hex.Decode(, )
	if  != nil {
		return fmt.Errorf("cannot unmarshal ID from string '%s': %w", string(), )
	}
	return nil
}