// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package metric

//go:generate stringer -type=NumberKind

import (
	"fmt"
	"math"
	"sync/atomic"

	"go.opentelemetry.io/otel/internal"
)

// NumberKind describes the data type of the Number.
type NumberKind int8

const (
	// Int64NumberKind means that the Number stores int64.
	Int64NumberKind NumberKind = iota
	// Float64NumberKind means that the Number stores float64.
	Float64NumberKind
)

// Zero returns a zero value for a given NumberKind
func (k NumberKind) Zero() Number {
	switch k {
	case Int64NumberKind:
		return NewInt64Number(0)
	case Float64NumberKind:
		return NewFloat64Number(0.)
	default:
		return Number(0)
	}
}

// Minimum returns the minimum representable value
// for a given NumberKind
func (k NumberKind) Minimum() Number {
	switch k {
	case Int64NumberKind:
		return NewInt64Number(math.MinInt64)
	case Float64NumberKind:
		return NewFloat64Number(-1. * math.MaxFloat64)
	default:
		return Number(0)
	}
}

// Maximum returns the maximum representable value
// for a given NumberKind
func (k NumberKind) Maximum() Number {
	switch k {
	case Int64NumberKind:
		return NewInt64Number(math.MaxInt64)
	case Float64NumberKind:
		return NewFloat64Number(math.MaxFloat64)
	default:
		return Number(0)
	}
}

// Number represents either an integral or a floating point value. It
// needs to be accompanied with a source of NumberKind that describes
// the actual type of the value stored within Number.
type Number uint64

// - constructors

// NewNumberFromRaw creates a new Number from a raw value.
func NewNumberFromRaw(r uint64) Number {
	return Number(r)
}

// NewInt64Number creates an integral Number.
func NewInt64Number(i int64) Number {
	return NewNumberFromRaw(internal.Int64ToRaw(i))
}

// NewFloat64Number creates a floating point Number.
func NewFloat64Number(f float64) Number {
	return NewNumberFromRaw(internal.Float64ToRaw(f))
}

// NewNumberSignChange returns a number with the same magnitude and
// the opposite sign.  `kind` must describe the kind of number in `nn`.
//
// Does not change Uint64NumberKind values.
func NewNumberSignChange(kind NumberKind, nn Number) Number {
	switch kind {
	case Int64NumberKind:
		return NewInt64Number(-nn.AsInt64())
	case Float64NumberKind:
		return NewFloat64Number(-nn.AsFloat64())
	}
	return nn
}

// - as x

// AsNumber gets the Number.
func (n *Number) AsNumber() Number {
	return *n
}

// AsRaw gets the uninterpreted raw value. Might be useful for some
// atomic operations.
func (n *Number) AsRaw() uint64 {
	return uint64(*n)
}

// AsInt64 assumes that the value contains an int64 and returns it as
// such.
func (n *Number) AsInt64() int64 {
	return internal.RawToInt64(n.AsRaw())
}

// AsFloat64 assumes that the measurement value contains a float64 and
// returns it as such.
func (n *Number) AsFloat64() float64 {
	return internal.RawToFloat64(n.AsRaw())
}

// - as x atomic

// AsNumberAtomic gets the Number atomically.
func (n *Number) AsNumberAtomic() Number {
	return NewNumberFromRaw(n.AsRawAtomic())
}

// AsRawAtomic gets the uninterpreted raw value atomically. Might be
// useful for some atomic operations.
func (n *Number) AsRawAtomic() uint64 {
	return atomic.LoadUint64(n.AsRawPtr())
}

// AsInt64Atomic assumes that the number contains an int64 and returns
// it as such atomically.
func (n *Number) AsInt64Atomic() int64 {
	return atomic.LoadInt64(n.AsInt64Ptr())
}

// AsFloat64Atomic assumes that the measurement value contains a
// float64 and returns it as such atomically.
func (n *Number) AsFloat64Atomic() float64 {
	return internal.RawToFloat64(n.AsRawAtomic())
}

// - as x ptr

// AsRawPtr gets the pointer to the raw, uninterpreted raw
// value. Might be useful for some atomic operations.
func (n *Number) AsRawPtr() *uint64 {
	return (*uint64)(n)
}

// AsInt64Ptr assumes that the number contains an int64 and returns a
// pointer to it.
func (n *Number) AsInt64Ptr() *int64 {
	return internal.RawPtrToInt64Ptr(n.AsRawPtr())
}

// AsFloat64Ptr assumes that the number contains a float64 and returns a
// pointer to it.
func (n *Number) AsFloat64Ptr() *float64 {
	return internal.RawPtrToFloat64Ptr(n.AsRawPtr())
}

// - coerce

// CoerceToInt64 casts the number to int64. May result in
// data/precision loss.
func (n *Number) CoerceToInt64(kind NumberKind) int64 {
	switch kind {
	case Int64NumberKind:
		return n.AsInt64()
	case Float64NumberKind:
		return int64(n.AsFloat64())
	default:
		// you get what you deserve
		return 0
	}
}

// CoerceToFloat64 casts the number to float64. May result in
// data/precision loss.
func (n *Number) CoerceToFloat64(kind NumberKind) float64 {
	switch kind {
	case Int64NumberKind:
		return float64(n.AsInt64())
	case Float64NumberKind:
		return n.AsFloat64()
	default:
		// you get what you deserve
		return 0
	}
}

// - set

// SetNumber sets the number to the passed number. Both should be of
// the same kind.
func (n *Number) SetNumber(nn Number) {
	*n.AsRawPtr() = nn.AsRaw()
}

// SetRaw sets the number to the passed raw value. Both number and the
// raw number should represent the same kind.
func (n *Number) SetRaw(r uint64) {
	*n.AsRawPtr() = r
}

// SetInt64 assumes that the number contains an int64 and sets it to
// the passed value.
func (n *Number) SetInt64(i int64) {
	*n.AsInt64Ptr() = i
}

// SetFloat64 assumes that the number contains a float64 and sets it
// to the passed value.
func (n *Number) SetFloat64(f float64) {
	*n.AsFloat64Ptr() = f
}

// - set atomic

// SetNumberAtomic sets the number to the passed number
// atomically. Both should be of the same kind.
func (n *Number) SetNumberAtomic(nn Number) {
	atomic.StoreUint64(n.AsRawPtr(), nn.AsRaw())
}

// SetRawAtomic sets the number to the passed raw value
// atomically. Both number and the raw number should represent the
// same kind.
func (n *Number) SetRawAtomic(r uint64) {
	atomic.StoreUint64(n.AsRawPtr(), r)
}

// SetInt64Atomic assumes that the number contains an int64 and sets
// it to the passed value atomically.
func (n *Number) SetInt64Atomic(i int64) {
	atomic.StoreInt64(n.AsInt64Ptr(), i)
}

// SetFloat64Atomic assumes that the number contains a float64 and
// sets it to the passed value atomically.
func (n *Number) SetFloat64Atomic(f float64) {
	atomic.StoreUint64(n.AsRawPtr(), internal.Float64ToRaw(f))
}

// - swap

// SwapNumber sets the number to the passed number and returns the old
// number. Both this number and the passed number should be of the
// same kind.
func (n *Number) SwapNumber(nn Number) Number {
	old := *n
	n.SetNumber(nn)
	return old
}

// SwapRaw sets the number to the passed raw value and returns the old
// raw value. Both number and the raw number should represent the same
// kind.
func (n *Number) SwapRaw(r uint64) uint64 {
	old := n.AsRaw()
	n.SetRaw(r)
	return old
}

// SwapInt64 assumes that the number contains an int64, sets it to the
// passed value and returns the old int64 value.
func (n *Number) SwapInt64(i int64) int64 {
	old := n.AsInt64()
	n.SetInt64(i)
	return old
}

// SwapFloat64 assumes that the number contains an float64, sets it to
// the passed value and returns the old float64 value.
func (n *Number) SwapFloat64(f float64) float64 {
	old := n.AsFloat64()
	n.SetFloat64(f)
	return old
}

// - swap atomic

// SwapNumberAtomic sets the number to the passed number and returns
// the old number atomically. Both this number and the passed number
// should be of the same kind.
func (n *Number) SwapNumberAtomic(nn Number) Number {
	return NewNumberFromRaw(atomic.SwapUint64(n.AsRawPtr(), nn.AsRaw()))
}

// SwapRawAtomic sets the number to the passed raw value and returns
// the old raw value atomically. Both number and the raw number should
// represent the same kind.
func (n *Number) SwapRawAtomic(r uint64) uint64 {
	return atomic.SwapUint64(n.AsRawPtr(), r)
}

// SwapInt64Atomic assumes that the number contains an int64, sets it
// to the passed value and returns the old int64 value atomically.
func (n *Number) SwapInt64Atomic(i int64) int64 {
	return atomic.SwapInt64(n.AsInt64Ptr(), i)
}

// SwapFloat64Atomic assumes that the number contains an float64, sets
// it to the passed value and returns the old float64 value
// atomically.
func (n *Number) SwapFloat64Atomic(f float64) float64 {
	return internal.RawToFloat64(atomic.SwapUint64(n.AsRawPtr(), internal.Float64ToRaw(f)))
}

// - add

// AddNumber assumes that this and the passed number are of the passed
// kind and adds the passed number to this number.
func (n *Number) AddNumber(kind NumberKind, nn Number) {
	switch kind {
	case Int64NumberKind:
		n.AddInt64(nn.AsInt64())
	case Float64NumberKind:
		n.AddFloat64(nn.AsFloat64())
	}
}

// AddRaw assumes that this number and the passed raw value are of the
// passed kind and adds the passed raw value to this number.
func (n *Number) AddRaw(kind NumberKind, r uint64) {
	n.AddNumber(kind, NewNumberFromRaw(r))
}

// AddInt64 assumes that the number contains an int64 and adds the
// passed int64 to it.
func (n *Number) AddInt64(i int64) {
	*n.AsInt64Ptr() += i
}

// AddFloat64 assumes that the number contains a float64 and adds the
// passed float64 to it.
func (n *Number) AddFloat64(f float64) {
	*n.AsFloat64Ptr() += f
}

// - add atomic

// AddNumberAtomic assumes that this and the passed number are of the
// passed kind and adds the passed number to this number atomically.
func (n *Number) AddNumberAtomic(kind NumberKind, nn Number) {
	switch kind {
	case Int64NumberKind:
		n.AddInt64Atomic(nn.AsInt64())
	case Float64NumberKind:
		n.AddFloat64Atomic(nn.AsFloat64())
	}
}

// AddRawAtomic assumes that this number and the passed raw value are
// of the passed kind and adds the passed raw value to this number
// atomically.
func (n *Number) AddRawAtomic(kind NumberKind, r uint64) {
	n.AddNumberAtomic(kind, NewNumberFromRaw(r))
}

// AddInt64Atomic assumes that the number contains an int64 and adds
// the passed int64 to it atomically.
func (n *Number) AddInt64Atomic(i int64) {
	atomic.AddInt64(n.AsInt64Ptr(), i)
}

// AddFloat64Atomic assumes that the number contains a float64 and
// adds the passed float64 to it atomically.
func (n *Number) AddFloat64Atomic(f float64) {
	for {
		o := n.AsFloat64Atomic()
		if n.CompareAndSwapFloat64(o, o+f) {
			break
		}
	}
}

// - compare and swap (atomic only)

// CompareAndSwapNumber does the atomic CAS operation on this
// number. This number and passed old and new numbers should be of the
// same kind.
func (n *Number) CompareAndSwapNumber(on, nn Number) bool {
	return atomic.CompareAndSwapUint64(n.AsRawPtr(), on.AsRaw(), nn.AsRaw())
}

// CompareAndSwapRaw does the atomic CAS operation on this
// number. This number and passed old and new raw values should be of
// the same kind.
func (n *Number) CompareAndSwapRaw(or, nr uint64) bool {
	return atomic.CompareAndSwapUint64(n.AsRawPtr(), or, nr)
}

// CompareAndSwapInt64 assumes that this number contains an int64 and
// does the atomic CAS operation on it.
func (n *Number) CompareAndSwapInt64(oi, ni int64) bool {
	return atomic.CompareAndSwapInt64(n.AsInt64Ptr(), oi, ni)
}

// CompareAndSwapFloat64 assumes that this number contains a float64 and
// does the atomic CAS operation on it.
func (n *Number) CompareAndSwapFloat64(of, nf float64) bool {
	return atomic.CompareAndSwapUint64(n.AsRawPtr(), internal.Float64ToRaw(of), internal.Float64ToRaw(nf))
}

// - compare

// CompareNumber compares two Numbers given their kind.  Both numbers
// should have the same kind.  This returns:
//    0 if the numbers are equal
//    -1 if the subject `n` is less than the argument `nn`
//    +1 if the subject `n` is greater than the argument `nn`
func (n *Number) CompareNumber(kind NumberKind, nn Number) int {
	switch kind {
	case Int64NumberKind:
		return n.CompareInt64(nn.AsInt64())
	case Float64NumberKind:
		return n.CompareFloat64(nn.AsFloat64())
	default:
		// you get what you deserve
		return 0
	}
}

// CompareRaw compares two numbers, where one is input as a raw
// uint64, interpreting both values as a `kind` of number.
func (n *Number) CompareRaw(kind NumberKind, r uint64) int {
	return n.CompareNumber(kind, NewNumberFromRaw(r))
}

// CompareInt64 assumes that the Number contains an int64 and performs
// a comparison between the value and the other value. It returns the
// typical result of the compare function: -1 if the value is less
// than the other, 0 if both are equal, 1 if the value is greater than
// the other.
func (n *Number) CompareInt64(i int64) int {
	this := n.AsInt64()
	if this < i {
		return -1
	} else if this > i {
		return 1
	}
	return 0
}

// CompareFloat64 assumes that the Number contains a float64 and
// performs a comparison between the value and the other value. It
// returns the typical result of the compare function: -1 if the value
// is less than the other, 0 if both are equal, 1 if the value is
// greater than the other.
//
// Do not compare NaN values.
func (n *Number) CompareFloat64(f float64) int {
	this := n.AsFloat64()
	if this < f {
		return -1
	} else if this > f {
		return 1
	}
	return 0
}

// - relations to zero

// IsPositive returns true if the actual value is greater than zero.
func (n *Number) IsPositive(kind NumberKind) bool {
	return n.compareWithZero(kind) > 0
}

// IsNegative returns true if the actual value is less than zero.
func (n *Number) IsNegative(kind NumberKind) bool {
	return n.compareWithZero(kind) < 0
}

// IsZero returns true if the actual value is equal to zero.
func (n *Number) IsZero(kind NumberKind) bool {
	return n.compareWithZero(kind) == 0
}

// - misc

// Emit returns a string representation of the raw value of the
// Number. A %d is used for integral values, %f for floating point
// values.
func (n *Number) Emit(kind NumberKind) string {
	switch kind {
	case Int64NumberKind:
		return fmt.Sprintf("%d", n.AsInt64())
	case Float64NumberKind:
		return fmt.Sprintf("%f", n.AsFloat64())
	default:
		return ""
	}
}

// AsInterface returns the number as an interface{}, typically used
// for NumberKind-correct JSON conversion.
func (n *Number) AsInterface(kind NumberKind) interface{} {
	switch kind {
	case Int64NumberKind:
		return n.AsInt64()
	case Float64NumberKind:
		return n.AsFloat64()
	default:
		return math.NaN()
	}
}

// - private stuff

func (n *Number) compareWithZero(kind NumberKind) int {
	switch kind {
	case Int64NumberKind:
		return n.CompareInt64(0)
	case Float64NumberKind:
		return n.CompareFloat64(0.)
	default:
		// you get what you deserve
		return 0
	}
}
