// 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 event

import (
	"fmt"
	"math"
	"reflect"
	"strconv"
	"time"
	"unsafe"
)

// Value holds any value in an efficient way that avoids allocations for
// most types.
type Value struct {
	packed  uint64
	untyped interface{}
}

// Label is a named value.
type Label struct {
	Name  string
	Value Value
}

// Equal reports whether two labels are equal.
func (l1 Label) Equal(l2 Label) bool {
	return l1.Name == l2.Name && l1.Value.Equal(l2.Value)
}

// stringptr is used in untyped when the Value is a string
type stringptr unsafe.Pointer

// bytesptr is used in untyped when the Value is a byte slice
type bytesptr unsafe.Pointer

// int64Kind is used in untyped when the Value is a signed integer
type int64Kind struct{}

// uint64Kind is used in untyped when the Value is an unsigned integer
type uint64Kind struct{}

// float64Kind is used in untyped when the Value is a floating point number
type float64Kind struct{}

// boolKind is used in untyped when the Value is a boolean
type boolKind struct{}

// durationKind is used in untyped when the Value is a time.Duration
type durationKind struct{}

// HasValue returns true if the value is set to any type.
func (v *Value) HasValue() bool { return v.untyped != nil }

// Equal reports whether two values are equal.
func (v1 *Value) Equal(v2 Value) bool {
	if !v1.HasValue() {
		return !v2.HasValue()
	}
	if !v2.HasValue() {
		return false
	}
	switch {
	case v1.IsString():
		return v2.IsString() && v1.String() == v2.String()
	case v1.IsInt64():
		return v2.IsInt64() && v1.packed == v2.packed
	case v1.IsUint64():
		return v2.IsUint64() && v1.packed == v2.packed
	case v1.IsFloat64():
		return v2.IsFloat64() && v1.Float64() == v2.Float64()
	case v1.IsBool():
		return v2.IsBool() && v1.packed == v2.packed
	case v1.IsDuration():
		return v2.IsDuration() && v1.packed == v2.packed
	default:
		return v1.untyped == v2.untyped
	}
}

// ValueOf returns a Value for the supplied value.
func ValueOf(value interface{}) Value {
	return Value{untyped: value}
}

// Interface returns the value.
// This will never panic, things that were not set using SetInterface will be
// unpacked and returned anyway.
func (v Value) Interface() interface{} {
	switch {
	case v.IsString():
		return v.String()
	case v.IsInt64():
		return v.Int64()
	case v.IsUint64():
		return v.Uint64()
	case v.IsFloat64():
		return v.Float64()
	case v.IsBool():
		return v.Bool()
	case v.IsDuration():
		return v.Duration()
	default:
		return v.untyped
	}
}

// StringOf returns a new Value for a string.
func StringOf(s string) Value {
	hdr := (*reflect.StringHeader)(unsafe.Pointer(&s))
	return Value{packed: uint64(hdr.Len), untyped: stringptr(hdr.Data)}
}

// String returns the value as a string.
// This does not panic if v's Kind is not String, instead, it returns a string
// representation of the value in all cases.
func (v Value) String() string {
	if sp, ok := v.untyped.(stringptr); ok {
		var s string
		hdr := (*reflect.StringHeader)(unsafe.Pointer(&s))
		hdr.Data = uintptr(sp)
		hdr.Len = int(v.packed)
		return s
	}
	// not a string, convert to one
	switch {
	case v.IsInt64():
		return strconv.FormatInt(v.Int64(), 10)
	case v.IsUint64():
		return strconv.FormatUint(v.Uint64(), 10)
	case v.IsFloat64():
		return strconv.FormatFloat(v.Float64(), 'g', -1, 64)
	case v.IsBool():
		if v.Bool() {
			return "true"
		} else {
			return "false"
		}
	default:
		return fmt.Sprint(v.Interface())
	}
}

// IsString returns true if the value was built with StringOf.
func (v Value) IsString() bool {
	_, ok := v.untyped.(stringptr)
	return ok
}

// BytesOf returns a new Value for a string.
func BytesOf(data []byte) Value {
	hdr := (*reflect.SliceHeader)(unsafe.Pointer(&data))
	return Value{packed: uint64(hdr.Len), untyped: bytesptr(hdr.Data)}
}

// Bytes returns the value as a bytes array.
func (v Value) Bytes() []byte {
	bp, ok := v.untyped.(bytesptr)
	if !ok {
		panic("Bytes called on non []byte value")
	}
	var buf []byte
	hdr := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
	hdr.Data = uintptr(bp)
	hdr.Len = int(v.packed)
	hdr.Cap = hdr.Len
	return buf
}

// IsBytes returns true if the value was built with BytesOf.
func (v Value) IsBytes() bool {
	_, ok := v.untyped.(bytesptr)
	return ok
}

// Int64Of returns a new Value for a signed integer.
func Int64Of(u int64) Value {
	return Value{packed: uint64(u), untyped: int64Kind{}}
}

// Int64 returns the int64 from a value that was set with SetInt64.
// It will panic for any value for which IsInt64 is not true.
func (v Value) Int64() int64 {
	if !v.IsInt64() {
		panic("Int64 called on non int64 value")
	}
	return int64(v.packed)
}

// IsInt64 returns true if the value was built with SetInt64.
func (v Value) IsInt64() bool {
	_, ok := v.untyped.(int64Kind)
	return ok
}

// Uint64Of returns a new Value for an unsigned integer.
func Uint64Of(u uint64) Value {
	return Value{packed: u, untyped: uint64Kind{}}
}

// Uint64 returns the uint64 from a value that was set with SetUint64.
// It will panic for any value for which IsUint64 is not true.
func (v Value) Uint64() uint64 {
	if !v.IsUint64() {
		panic("Uint64 called on non uint64 value")
	}
	return v.packed
}

// IsUint64 returns true if the value was built with SetUint64.
func (v Value) IsUint64() bool {
	_, ok := v.untyped.(uint64Kind)
	return ok
}

// Float64Of returns a new Value for a floating point number.
func Float64Of(f float64) Value {
	return Value{packed: math.Float64bits(f), untyped: float64Kind{}}
}

// Float64 returns the float64 from a value that was set with SetFloat64.
// It will panic for any value for which IsFloat64 is not true.
func (v Value) Float64() float64 {
	if !v.IsFloat64() {
		panic("Float64 called on non float64 value")
	}
	return math.Float64frombits(v.packed)
}

// IsFloat64 returns true if the value was built with SetFloat64.
func (v Value) IsFloat64() bool {
	_, ok := v.untyped.(float64Kind)
	return ok
}

// BoolOf returns a new Value for a bool.
func BoolOf(b bool) Value {
	if b {
		return Value{packed: 1, untyped: boolKind{}}
	}
	return Value{packed: 0, untyped: boolKind{}}
}

// Bool returns the bool from a value that was set with SetBool.
// It will panic for any value for which IsBool is not true.
func (v Value) Bool() bool {
	if !v.IsBool() {
		panic("Bool called on non bool value")
	}
	if v.packed != 0 {
		return true
	}
	return false
}

// IsBool returns true if the value was built with SetBool.
func (v Value) IsBool() bool {
	_, ok := v.untyped.(boolKind)
	return ok
}

func DurationOf(d time.Duration) Value {
	return Value{packed: uint64(d), untyped: durationKind{}}
}

func (v Value) Duration() time.Duration {
	if !v.IsDuration() {
		panic("Duration called on non-Duration value")
	}
	return time.Duration(v.packed)
}

func (v Value) IsDuration() bool {
	_, ok := v.untyped.(durationKind)
	return ok
}
