// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package label

import (
	"fmt"
	"io"
	"reflect"
	"unsafe"
)

// Key is used as the identity of a Label.
// Keys are intended to be compared by pointer only, the name should be unique
// for communicating with external systems, but it is not required or enforced.
type Key interface {
	// Name returns the key name.
	Name() string
	// Description returns a string that can be used to describe the value.
	Description() string

	// Format is used in formatting to append the value of the label to the
	// supplied buffer.
	// The formatter may use the supplied buf as a scratch area to avoid
	// allocations.
	Format(w io.Writer, buf []byte, l Label)
}

// Label holds a key and value pair.
// It is normally used when passing around lists of labels.
type Label struct {
	key     Key
	packed  uint64
	untyped interface{}
}

// Map is the interface to a collection of Labels indexed by key.
type Map interface {
	// Find returns the label that matches the supplied key.
	Find(key Key) Label
}

// List is the interface to something that provides an iterable
// list of labels.
// Iteration should start from 0 and continue until Valid returns false.
type List interface {
	// Valid returns true if the index is within range for the list.
	// It does not imply the label at that index will itself be valid.
	Valid(index int) bool
	// Label returns the label at the given index.
	Label(index int) Label
}

// list implements LabelList for a list of Labels.
type list struct {
	labels []Label
}

// filter wraps a LabelList filtering out specific labels.
type filter struct {
	keys       []Key
	underlying List
}

// listMap implements LabelMap for a simple list of labels.
type listMap struct {
	labels []Label
}

// mapChain implements LabelMap for a list of underlying LabelMap.
type mapChain struct {
	maps []Map
}

// OfValue creates a new label from the key and value.
// This method is for implementing new key types, label creation should
// normally be done with the Of method of the key.
func OfValue(k Key, value interface{}) Label { return Label{key: k, untyped: value} }

// UnpackValue assumes the label was built using LabelOfValue and returns the value
// that was passed to that constructor.
// This method is for implementing new key types, for type safety normal
// access should be done with the From method of the key.
func (t Label) UnpackValue() interface{} { return t.untyped }

// Of64 creates a new label from a key and a uint64. This is often
// used for non uint64 values that can be packed into a uint64.
// This method is for implementing new key types, label creation should
// normally be done with the Of method of the key.
func Of64(k Key, v uint64) Label { return Label{key: k, packed: v} }

// Unpack64 assumes the label was built using LabelOf64 and returns the value that
// was passed to that constructor.
// This method is for implementing new key types, for type safety normal
// access should be done with the From method of the key.
func (t Label) Unpack64() uint64 { return t.packed }

type stringptr unsafe.Pointer

// OfString creates a new label from a key and a string.
// This method is for implementing new key types, label creation should
// normally be done with the Of method of the key.
func OfString(k Key, v string) Label {
	hdr := (*reflect.StringHeader)(unsafe.Pointer(&v))
	return Label{
		key:     k,
		packed:  uint64(hdr.Len),
		untyped: stringptr(hdr.Data),
	}
}

// UnpackString assumes the label was built using LabelOfString and returns the
// value that was passed to that constructor.
// This method is for implementing new key types, for type safety normal
// access should be done with the From method of the key.
func (t Label) UnpackString() string {
	var v string
	hdr := (*reflect.StringHeader)(unsafe.Pointer(&v))
	hdr.Data = uintptr(t.untyped.(stringptr))
	hdr.Len = int(t.packed)
	return v
}

// Valid returns true if the Label is a valid one (it has a key).
func (t Label) Valid() bool { return t.key != nil }

// Key returns the key of this Label.
func (t Label) Key() Key { return t.key }

// Format is used for debug printing of labels.
func (t Label) Format(f fmt.State, r rune) {
	if !t.Valid() {
		io.WriteString(f, `nil`)
		return
	}
	io.WriteString(f, t.Key().Name())
	io.WriteString(f, "=")
	var buf [128]byte
	t.Key().Format(f, buf[:0], t)
}

func (l *list) Valid(index int) bool {
	return index >= 0 && index < len(l.labels)
}

func (l *list) Label(index int) Label {
	return l.labels[index]
}

func (f *filter) Valid(index int) bool {
	return f.underlying.Valid(index)
}

func (f *filter) Label(index int) Label {
	l := f.underlying.Label(index)
	for _, f := range f.keys {
		if l.Key() == f {
			return Label{}
		}
	}
	return l
}

func (lm listMap) Find(key Key) Label {
	for _, l := range lm.labels {
		if l.Key() == key {
			return l
		}
	}
	return Label{}
}

func (c mapChain) Find(key Key) Label {
	for _, src := range c.maps {
		l := src.Find(key)
		if l.Valid() {
			return l
		}
	}
	return Label{}
}

var emptyList = &list{}

func NewList(labels ...Label) List {
	if len(labels) == 0 {
		return emptyList
	}
	return &list{labels: labels}
}

func Filter(l List, keys ...Key) List {
	if len(keys) == 0 {
		return l
	}
	return &filter{keys: keys, underlying: l}
}

func NewMap(labels ...Label) Map {
	return listMap{labels: labels}
}

func MergeMaps(srcs ...Map) Map {
	var nonNil []Map
	for _, src := range srcs {
		if src != nil {
			nonNil = append(nonNil, src)
		}
	}
	if len(nonNil) == 1 {
		return nonNil[0]
	}
	return mapChain{maps: nonNil}
}
