/*
Copyright 2014 The Kubernetes Authors All rights reserved.

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 api

import (
	"errors"
	"fmt"
	"math/big"
	"regexp"
	"strings"

	"gopkg.in/inf.v0"
)

// Quantity is a fixed-point representation of a number.
// It provides convenient marshaling/unmarshaling in JSON and YAML,
// in addition to String() and Int64() accessors.
//
// The serialization format is:
//
//	<quantity>        ::= <signedNumber><suffix>
//	  (Note that <suffix> may be empty, from the "" case in <decimalSI>.)
//	<digit>           ::= 0 | 1 | ... | 9
//	<digits>          ::= <digit> | <digit><digits>
//	<number>          ::= <digits> | <digits>.<digits> | <digits>. | .<digits>
//	<sign>            ::= "+" | "-"
//	<signedNumber>    ::= <number> | <sign><number>
//	<suffix>          ::= <binarySI> | <decimalExponent> | <decimalSI>
//	<binarySI>        ::= Ki | Mi | Gi | Ti | Pi | Ei
//	  (International System of units; See: http://physics.nist.gov/cuu/Units/binary.html)
//	<decimalSI>       ::= m | "" | k | M | G | T | P | E
//	  (Note that 1024 = 1Ki but 1000 = 1k; I didn't choose the capitalization.)
//	<decimalExponent> ::= "e" <signedNumber> | "E" <signedNumber>
//
// No matter which of the three exponent forms is used, no quantity may represent
// a number greater than 2^63-1 in magnitude, nor may it have more than 3 decimal
// places. Numbers larger or more precise will be capped or rounded up.
// (E.g.: 0.1m will rounded up to 1m.)
// This may be extended in the future if we require larger or smaller quantities.
//
// When a Quantity is parsed from a string, it will remember the type of suffix
// it had, and will use the same type again when it is serialized.
//
// Before serializing, Quantity will be put in "canonical form".
// This means that Exponent/suffix will be adjusted up or down (with a
// corresponding increase or decrease in Mantissa) such that:
//
//	a. No precision is lost
//	b. No fractional digits will be emitted
//	c. The exponent (or suffix) is as large as possible.
//
// The sign will be omitted unless the number is negative.
//
// Examples:
//
//	1.5 will be serialized as "1500m"
//	1.5Gi will be serialized as "1536Mi"
//
// NOTE: We reserve the right to amend this canonical format, perhaps to
// allow 1.5 to be canonical.
// TODO: Remove above disclaimer after all bikeshedding about format is over,
// or after March 2015.
//
// Note that the quantity will NEVER be internally represented by a
// floating point number. That is the whole point of this exercise.
//
// Non-canonical values will still parse as long as they are well formed,
// but will be re-emitted in their canonical form. (So always use canonical
// form, or don't diff.)
//
// This format is intended to make it difficult to use these numbers without
// writing some sort of special handling code in the hopes that that will
// cause implementors to also use a fixed point implementation.
type Quantity struct {
	// Amount is public, so you can manipulate it if the accessor
	// functions are not sufficient.
	Amount *inf.Dec

	// Change Format at will. See the comment for Canonicalize for
	// more details.
	Format
}

// Format lists the three possible formattings of a quantity.
type Format string

const (
	DecimalExponent = Format("DecimalExponent") // e.g., 12e6
	BinarySI        = Format("BinarySI")        // e.g., 12Mi (12 * 2^20)
	DecimalSI       = Format("DecimalSI")       // e.g., 12M  (12 * 10^6)
)

// MustParse turns the given string into a quantity or panics; for tests
// or others cases where you know the string is valid.
func MustParse(str string) Quantity {
	q, err := ParseQuantity(str)
	if err != nil {
		panic(fmt.Errorf("cannot parse '%v': %v", str, err))
	}
	return *q
}

const (
	// splitREString is used to separate a number from its suffix; as such,
	// this is overly permissive, but that's OK-- it will be checked later.
	splitREString = "^([+-]?[0-9.]+)([eEimkKMGTP]*[-+]?[0-9]*)$"
)

var (
	// splitRE is used to get the various parts of a number.
	splitRE = regexp.MustCompile(splitREString)

	// Errors that could happen while parsing a string.
	ErrFormatWrong = errors.New("quantities must match the regular expression '" + splitREString + "'")
	ErrNumeric     = errors.New("unable to parse numeric part of quantity")
	ErrSuffix      = errors.New("unable to parse quantity's suffix")

	// Commonly needed big.Int values-- treat as read only!
	bigTen      = big.NewInt(10)
	bigZero     = big.NewInt(0)
	bigOne      = big.NewInt(1)
	bigThousand = big.NewInt(1000)
	big1024     = big.NewInt(1024)

	// Commonly needed inf.Dec values-- treat as read only!
	decZero      = inf.NewDec(0, 0)
	decOne       = inf.NewDec(1, 0)
	decMinusOne  = inf.NewDec(-1, 0)
	decThousand  = inf.NewDec(1000, 0)
	dec1024      = inf.NewDec(1024, 0)
	decMinus1024 = inf.NewDec(-1024, 0)

	// Largest (in magnitude) number allowed.
	maxAllowed = inf.NewDec((1<<63)-1, 0) // == max int64

	// The maximum value we can represent milli-units for.
	// Compare with the return value of Quantity.Value() to
	// see if it's safe to use Quantity.MilliValue().
	MaxMilliValue = int64(((1 << 63) - 1) / 1000)
)

// ParseQuantity turns str into a Quantity, or returns an error.
func ParseQuantity(str string) (*Quantity, error) {
	parts := splitRE.FindStringSubmatch(strings.TrimSpace(str))
	// regexp returns are entire match, followed by an entry for each () section.
	if len(parts) != 3 {
		return nil, ErrFormatWrong
	}

	amount := new(inf.Dec)
	if _, ok := amount.SetString(parts[1]); !ok {
		return nil, ErrNumeric
	}

	base, exponent, format, ok := quantitySuffixer.interpret(suffix(parts[2]))
	if !ok {
		return nil, ErrSuffix
	}

	// So that no one but us has to think about suffixes, remove it.
	if base == 10 {
		amount.SetScale(amount.Scale() + inf.Scale(-exponent))
	} else if base == 2 {
		// numericSuffix = 2 ** exponent
		numericSuffix := big.NewInt(1).Lsh(bigOne, uint(exponent))
		ub := amount.UnscaledBig()
		amount.SetUnscaledBig(ub.Mul(ub, numericSuffix))
	}

	// Cap at min/max bounds.
	sign := amount.Sign()
	if sign == -1 {
		amount.Neg(amount)
	}
	// This rounds non-zero values up to the minimum representable
	// value, under the theory that if you want some resources, you
	// should get some resources, even if you asked for way too small
	// of an amount.
	// Arguably, this should be inf.RoundHalfUp (normal rounding), but
	// that would have the side effect of rounding values < .5m to zero.
	if v, ok := amount.Unscaled(); v != int64(0) || !ok {
		amount.Round(amount, 3, inf.RoundUp)
	}

	// The max is just a simple cap.
	if amount.Cmp(maxAllowed) > 0 {
		amount.Set(maxAllowed)
	}
	if format == BinarySI && amount.Cmp(decOne) < 0 && amount.Cmp(decZero) > 0 {
		// This avoids rounding and hopefully confusion, too.
		format = DecimalSI
	}
	if sign == -1 {
		amount.Neg(amount)
	}

	return &Quantity{amount, format}, nil
}

// removeFactors divides in a loop; the return values have the property that
// d == result * factor ^ times
// d may be modified in place.
// If d == 0, then the return values will be (0, 0)
func removeFactors(d, factor *big.Int) (result *big.Int, times int) {
	q := big.NewInt(0)
	m := big.NewInt(0)
	for d.Cmp(bigZero) != 0 {
		q.DivMod(d, factor, m)
		if m.Cmp(bigZero) != 0 {
			break
		}
		times++
		d, q = q, d
	}
	return d, times
}

// Canonicalize returns the canonical form of q and its suffix (see comment on Quantity).
//
// Note about BinarySI:
//   - If q.Format is set to BinarySI and q.Amount represents a non-zero value between
//     -1 and +1, it will be emitted as if q.Format were DecimalSI.
//   - Otherwise, if q.Format is set to BinarySI, frational parts of q.Amount will be
//     rounded up. (1.1i becomes 2i.)
func (q *Quantity) Canonicalize() (string, suffix) {
	if q.Amount == nil {
		return "0", ""
	}

	// zero is zero always
	if q.Amount.Cmp(&inf.Dec{}) == 0 {
		return "0", ""
	}

	format := q.Format
	switch format {
	case DecimalExponent, DecimalSI:
	case BinarySI:
		if q.Amount.Cmp(decMinus1024) > 0 && q.Amount.Cmp(dec1024) < 0 {
			// This avoids rounding and hopefully confusion, too.
			format = DecimalSI
		} else {
			tmp := &inf.Dec{}
			tmp.Round(q.Amount, 0, inf.RoundUp)
			if tmp.Cmp(q.Amount) != 0 {
				// Don't lose precision-- show as DecimalSI
				format = DecimalSI
			}
		}
	default:
		format = DecimalExponent
	}

	// TODO: If BinarySI formatting is requested but would cause rounding, upgrade to
	// one of the other formats.
	switch format {
	case DecimalExponent, DecimalSI:
		mantissa := q.Amount.UnscaledBig()
		exponent := int(-q.Amount.Scale())
		amount := big.NewInt(0).Set(mantissa)
		// move all factors of 10 into the exponent for easy reasoning
		amount, times := removeFactors(amount, bigTen)
		exponent += times

		// make sure exponent is a multiple of 3
		for exponent%3 != 0 {
			amount.Mul(amount, bigTen)
			exponent--
		}

		suffix, _ := quantitySuffixer.construct(10, exponent, format)
		number := amount.String()
		return number, suffix
	case BinarySI:
		tmp := &inf.Dec{}
		tmp.Round(q.Amount, 0, inf.RoundUp)

		amount, exponent := removeFactors(tmp.UnscaledBig(), big1024)
		suffix, _ := quantitySuffixer.construct(2, exponent*10, format)
		number := amount.String()
		return number, suffix
	}
	return "0", ""
}

// String formats the Quantity as a string.
func (q *Quantity) String() string {
	number, suffix := q.Canonicalize()
	return number + string(suffix)
}

func (q *Quantity) Add(y Quantity) error {
	if q.Format != y.Format {
		return fmt.Errorf("format mismatch: %v vs. %v", q.Format, y.Format)
	}
	q.Amount.Add(q.Amount, y.Amount)
	return nil
}

func (q *Quantity) Sub(y Quantity) error {
	if q.Format != y.Format {
		return fmt.Errorf("format mismatch: %v vs. %v", q.Format, y.Format)
	}
	q.Amount.Sub(q.Amount, y.Amount)
	return nil
}

// MarshalJSON implements the json.Marshaller interface.
func (q Quantity) MarshalJSON() ([]byte, error) {
	return []byte(`"` + q.String() + `"`), nil
}

// UnmarshalJSON implements the json.Unmarshaller interface.
func (q *Quantity) UnmarshalJSON(value []byte) error {
	str := string(value)
	parsed, err := ParseQuantity(strings.Trim(str, `"`))
	if err != nil {
		return err
	}
	// This copy is safe because parsed will not be referred to again.
	*q = *parsed
	return nil
}

// NewQuantity returns a new Quantity representing the given
// value in the given format.
func NewQuantity(value int64, format Format) *Quantity {
	return &Quantity{
		Amount: inf.NewDec(value, 0),
		Format: format,
	}
}

// NewMilliQuantity returns a new Quantity representing the given
// value * 1/1000 in the given format. Note that BinarySI formatting
// will round fractional values, and will be changed to DecimalSI for
// values x where (-1 < x < 1) && (x != 0).
func NewMilliQuantity(value int64, format Format) *Quantity {
	return &Quantity{
		Amount: inf.NewDec(value, 3),
		Format: format,
	}
}

// Value returns the value of q; any fractional part will be lost.
func (q *Quantity) Value() int64 {
	if q.Amount == nil {
		return 0
	}
	tmp := &inf.Dec{}
	return tmp.Round(q.Amount, 0, inf.RoundUp).UnscaledBig().Int64()
}

// MilliValue returns the value of q * 1000; this could overflow an int64;
// if that's a concern, call Value() first to verify the number is small enough.
func (q *Quantity) MilliValue() int64 {
	if q.Amount == nil {
		return 0
	}
	tmp := &inf.Dec{}
	return tmp.Round(tmp.Mul(q.Amount, decThousand), 0, inf.RoundUp).UnscaledBig().Int64()
}

// Set sets q's value to be value.
func (q *Quantity) Set(value int64) {
	if q.Amount == nil {
		q.Amount = &inf.Dec{}
	}
	q.Amount.SetUnscaled(value)
	q.Amount.SetScale(0)
}

// SetMilli sets q's value to be value * 1/1000.
func (q *Quantity) SetMilli(value int64) {
	if q.Amount == nil {
		q.Amount = &inf.Dec{}
	}
	q.Amount.SetUnscaled(value)
	q.Amount.SetScale(3)
}

// Copy is a convenience function that makes a deep copy for you. Non-deep
// copies of quantities share pointers and you will regret that.
func (q *Quantity) Copy() *Quantity {
	if q.Amount == nil {
		return NewQuantity(0, q.Format)
	}
	tmp := &inf.Dec{}
	return &Quantity{
		Amount: tmp.Set(q.Amount),
		Format: q.Format,
	}
}
