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

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

import (
	"bytes"
	"sync"
	"sync/atomic"
)

type (
	// Encoder is a mechanism for serializing an attribute set into a specific
	// string representation that supports caching, to avoid repeated
	// serialization. An example could be an exporter encoding the attribute
	// set into a wire representation.
	Encoder interface {
		// Encode returns the serialized encoding of the attribute set using
		// its Iterator. This result may be cached by a attribute.Set.
		Encode(iterator Iterator) string

		// ID returns a value that is unique for each class of attribute
		// encoder. Attribute encoders allocate these using `NewEncoderID`.
		ID() EncoderID
	}

	// EncoderID is used to identify distinct Encoder
	// implementations, for caching encoded results.
	EncoderID struct {
		value uint64
	}

	// defaultAttrEncoder uses a sync.Pool of buffers to reduce the number of
	// allocations used in encoding attributes. This implementation encodes a
	// comma-separated list of key=value, with '/'-escaping of '=', ',', and
	// '\'.
	defaultAttrEncoder struct {
		// pool is a pool of attribute set builders. The buffers in this pool
		// grow to a size that most attribute encodings will not allocate new
		// memory.
		pool sync.Pool // *bytes.Buffer
	}
)

// escapeChar is used to ensure uniqueness of the attribute encoding where
// keys or values contain either '=' or ','.  Since there is no parser needed
// for this encoding and its only requirement is to be unique, this choice is
// arbitrary.  Users will see these in some exporters (e.g., stdout), so the
// backslash ('\') is used as a conventional choice.
const escapeChar = '\\'

var (
	_ Encoder = &defaultAttrEncoder{}

	// encoderIDCounter is for generating IDs for other attribute encoders.
	encoderIDCounter uint64

	defaultEncoderOnce     sync.Once
	defaultEncoderID       = NewEncoderID()
	defaultEncoderInstance *defaultAttrEncoder
)

// NewEncoderID returns a unique attribute encoder ID. It should be called
// once per each type of attribute encoder. Preferably in init() or in var
// definition.
func NewEncoderID() EncoderID {
	return EncoderID{value: atomic.AddUint64(&encoderIDCounter, 1)}
}

// DefaultEncoder returns an attribute encoder that encodes attributes in such
// a way that each escaped attribute's key is followed by an equal sign and
// then by an escaped attribute's value. All key-value pairs are separated by
// a comma.
//
// Escaping is done by prepending a backslash before either a backslash, equal
// sign or a comma.
func DefaultEncoder() Encoder {
	defaultEncoderOnce.Do(func() {
		defaultEncoderInstance = &defaultAttrEncoder{
			pool: sync.Pool{
				New: func() any {
					return &bytes.Buffer{}
				},
			},
		}
	})
	return defaultEncoderInstance
}

// Encode is a part of an implementation of the AttributeEncoder interface.
func (d *defaultAttrEncoder) Encode(iter Iterator) string {
	buf := d.pool.Get().(*bytes.Buffer)
	defer d.pool.Put(buf)
	buf.Reset()

	for iter.Next() {
		i, keyValue := iter.IndexedAttribute()
		if i > 0 {
			_ = buf.WriteByte(',')
		}
		copyAndEscape(buf, string(keyValue.Key))

		_ = buf.WriteByte('=')

		if keyValue.Value.Type() == STRING {
			copyAndEscape(buf, keyValue.Value.AsString())
		} else {
			_, _ = buf.WriteString(keyValue.Value.Emit())
		}
	}
	return buf.String()
}

// ID is a part of an implementation of the AttributeEncoder interface.
func (*defaultAttrEncoder) ID() EncoderID {
	return defaultEncoderID
}

// copyAndEscape escapes `=`, `,` and its own escape character (`\`),
// making the default encoding unique.
func copyAndEscape(buf *bytes.Buffer, val string) {
	for _, ch := range val {
		switch ch {
		case '=', ',', escapeChar:
			_ = buf.WriteByte(escapeChar)
		}
		_, _ = buf.WriteRune(ch)
	}
}

// Valid reports whether this encoder ID was allocated by
// [NewEncoderID]. Invalid encoder IDs will not be cached.
func (id EncoderID) Valid() bool {
	return id.value != 0
}
