// © 2017 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html

#include "unicode/utypes.h"

#if !UCONFIG_NO_FORMATTING
#ifndef __NUMBER_DECIMALQUANTITY_H__
#define __NUMBER_DECIMALQUANTITY_H__

#include <cstdint>
#include "unicode/umachine.h"
#include "standardplural.h"
#include "plurrule_impl.h"
#include "number_types.h"

U_NAMESPACE_BEGIN namespace number {
namespace impl {

// Forward-declare (maybe don't want number_utils.h included here):
class DecNum;

/**
 * An class for representing a number to be processed by the decimal formatting pipeline. Includes
 * methods for rounding, plural rules, and decimal digit extraction.
 *
 * <p>By design, this is NOT IMMUTABLE and NOT THREAD SAFE. It is intended to be an intermediate
 * object holding state during a pass through the decimal formatting pipeline.
 *
 * <p>Represents numbers and digit display properties using Binary Coded Decimal (BCD).
 *
 * <p>Java has multiple implementations for testing, but C++ has only one implementation.
 */
class U_I18N_API DecimalQuantity : public IFixedDecimal, public UMemory {
  public:
    /** Copy constructor. */
    DecimalQuantity(const DecimalQuantity &other);

    /** Move constructor. */
    DecimalQuantity(DecimalQuantity &&src) U_NOEXCEPT;

    DecimalQuantity();

    ~DecimalQuantity() override;

    /**
     * Sets this instance to be equal to another instance.
     *
     * @param other The instance to copy from.
     */
    DecimalQuantity &operator=(const DecimalQuantity &other);

    /** Move assignment */
    DecimalQuantity &operator=(DecimalQuantity&& src) U_NOEXCEPT;

    /**
     * Sets the minimum integer digits that this {@link DecimalQuantity} should generate.
     * This method does not perform rounding.
     *
     * @param minInt The minimum number of integer digits.
     */
    void setMinInteger(int32_t minInt);

    /**
     * Sets the minimum fraction digits that this {@link DecimalQuantity} should generate.
     * This method does not perform rounding.
     *
     * @param minFrac The minimum number of fraction digits.
     */
    void setMinFraction(int32_t minFrac);

    /**
     * Truncates digits from the upper magnitude of the number in order to satisfy the
     * specified maximum number of integer digits.
     *
     * @param maxInt The maximum number of integer digits.
     */
    void applyMaxInteger(int32_t maxInt);

    /**
     * Rounds the number to a specified interval, such as 0.05.
     *
     * <p>If rounding to a power of ten, use the more efficient {@link #roundToMagnitude} instead.
     *
     * @param roundingIncrement The increment to which to round.
     * @param roundingMode The {@link RoundingMode} to use if rounding is necessary.
     */
    void roundToIncrement(double roundingIncrement, RoundingMode roundingMode,
                          UErrorCode& status);

    /** Removes all fraction digits. */
    void truncate();

    /**
     * Rounds the number to the nearest multiple of 5 at the specified magnitude.
     * For example, when magnitude == -2, this performs rounding to the nearest 0.05.
     *
     * @param magnitude The magnitude at which the digit should become either 0 or 5.
     * @param roundingMode Rounding strategy.
     */
    void roundToNickel(int32_t magnitude, RoundingMode roundingMode, UErrorCode& status);

    /**
     * Rounds the number to a specified magnitude (power of ten).
     *
     * @param roundingMagnitude The power of ten to which to round. For example, a value of -2 will
     *     round to 2 decimal places.
     * @param roundingMode The {@link RoundingMode} to use if rounding is necessary.
     */
    void roundToMagnitude(int32_t magnitude, RoundingMode roundingMode, UErrorCode& status);

    /**
     * Rounds the number to an infinite number of decimal points. This has no effect except for
     * forcing the double in {@link DecimalQuantity_AbstractBCD} to adopt its exact representation.
     */
    void roundToInfinity();

    /**
     * Multiply the internal value. Uses decNumber.
     *
     * @param multiplicand The value by which to multiply.
     */
    void multiplyBy(const DecNum& multiplicand, UErrorCode& status);

    /**
     * Divide the internal value. Uses decNumber.
     *
     * @param multiplicand The value by which to multiply.
     */
    void divideBy(const DecNum& divisor, UErrorCode& status);

    /** Flips the sign from positive to negative and back. */
    void negate();

    /**
     * Scales the number by a power of ten. For example, if the value is currently "1234.56", calling
     * this method with delta=-3 will change the value to "1.23456".
     *
     * @param delta The number of magnitudes of ten to change by.
     * @return true if integer overflow occured; false otherwise.
     */
    bool adjustMagnitude(int32_t delta);

    /**
     * @return The power of ten corresponding to the most significant nonzero digit.
     * The number must not be zero.
     */
    int32_t getMagnitude() const;

    /**
     * @return The value of the (suppressed) exponent after the number has been
     * put into a notation with exponents (ex: compact, scientific).  Ex: given
     * the number 1000 as "1K" / "1E3", the return value will be 3 (positive).
     */
    int32_t getExponent() const;

    /**
     * Adjusts the value for the (suppressed) exponent stored when using
     * notation with exponents (ex: compact, scientific).
     *
     * <p>Adjusting the exponent is decoupled from {@link #adjustMagnitude} in
     * order to allow flexibility for {@link StandardPlural} to be selected in
     * formatting (ex: for compact notation) either with or without the exponent
     * applied in the value of the number.
     * @param delta
     *             The value to adjust the exponent by.
     */
    void adjustExponent(int32_t delta);

    /**
     * @return Whether the value represented by this {@link DecimalQuantity} is
     * zero, infinity, or NaN.
     */
    bool isZeroish() const;

    /** @return Whether the value represented by this {@link DecimalQuantity} is less than zero. */
    bool isNegative() const;

    /** @return The appropriate value from the Signum enum. */
    Signum signum() const;

    /** @return Whether the value represented by this {@link DecimalQuantity} is infinite. */
    bool isInfinite() const U_OVERRIDE;

    /** @return Whether the value represented by this {@link DecimalQuantity} is not a number. */
    bool isNaN() const U_OVERRIDE;

    /**  
     * Note: this method incorporates the value of {@code exponent}
     * (for cases such as compact notation) to return the proper long value
     * represented by the result.
     * @param truncateIfOverflow if false and the number does NOT fit, fails with an assertion error. 
     */
    int64_t toLong(bool truncateIfOverflow = false) const;

    /**
     * Note: this method incorporates the value of {@code exponent}
     * (for cases such as compact notation) to return the proper long value
     * represented by the result.
     */
    uint64_t toFractionLong(bool includeTrailingZeros) const;

    /**
     * Returns whether or not a Long can fully represent the value stored in this DecimalQuantity.
     * @param ignoreFraction if true, silently ignore digits after the decimal place.
     */
    bool fitsInLong(bool ignoreFraction = false) const;

    /** @return The value contained in this {@link DecimalQuantity} approximated as a double. */
    double toDouble() const;

    /** Computes a DecNum representation of this DecimalQuantity, saving it to the output parameter. */
    void toDecNum(DecNum& output, UErrorCode& status) const;

    DecimalQuantity &setToInt(int32_t n);

    DecimalQuantity &setToLong(int64_t n);

    DecimalQuantity &setToDouble(double n);

    /** decNumber is similar to BigDecimal in Java. */
    DecimalQuantity &setToDecNumber(StringPiece n, UErrorCode& status);

    /** Internal method if the caller already has a DecNum. */
    DecimalQuantity &setToDecNum(const DecNum& n, UErrorCode& status);

    /**
     * Appends a digit, optionally with one or more leading zeros, to the end of the value represented
     * by this DecimalQuantity.
     *
     * <p>The primary use of this method is to construct numbers during a parsing loop. It allows
     * parsing to take advantage of the digit list infrastructure primarily designed for formatting.
     *
     * @param value The digit to append.
     * @param leadingZeros The number of zeros to append before the digit. For example, if the value
     *     in this instance starts as 12.3, and you append a 4 with 1 leading zero, the value becomes
     *     12.304.
     * @param appendAsInteger If true, increase the magnitude of existing digits to make room for the
     *     new digit. If false, append to the end like a fraction digit. If true, there must not be
     *     any fraction digits already in the number.
     * @internal
     * @deprecated This API is ICU internal only.
     */
    void appendDigit(int8_t value, int32_t leadingZeros, bool appendAsInteger);

    double getPluralOperand(PluralOperand operand) const U_OVERRIDE;

    bool hasIntegerValue() const U_OVERRIDE;

    /**
     * Gets the digit at the specified magnitude. For example, if the represented number is 12.3,
     * getDigit(-1) returns 3, since 3 is the digit corresponding to 10^-1.
     *
     * @param magnitude The magnitude of the digit.
     * @return The digit at the specified magnitude.
     */
    int8_t getDigit(int32_t magnitude) const;

    /**
     * Gets the largest power of ten that needs to be displayed. The value returned by this function
     * will be bounded between minInt and maxInt.
     *
     * @return The highest-magnitude digit to be displayed.
     */
    int32_t getUpperDisplayMagnitude() const;

    /**
     * Gets the smallest power of ten that needs to be displayed. The value returned by this function
     * will be bounded between -minFrac and -maxFrac.
     *
     * @return The lowest-magnitude digit to be displayed.
     */
    int32_t getLowerDisplayMagnitude() const;

    int32_t fractionCount() const;

    int32_t fractionCountWithoutTrailingZeros() const;

    void clear();

    /** This method is for internal testing only. */
    uint64_t getPositionFingerprint() const;

//    /**
//     * If the given {@link FieldPosition} is a {@link UFieldPosition}, populates it with the fraction
//     * length and fraction long value. If the argument is not a {@link UFieldPosition}, nothing
//     * happens.
//     *
//     * @param fp The {@link UFieldPosition} to populate.
//     */
//    void populateUFieldPosition(FieldPosition fp);

    /**
     * Checks whether the bytes stored in this instance are all valid. For internal unit testing only.
     *
     * @return An error message if this instance is invalid, or null if this instance is healthy.
     */
    const char16_t* checkHealth() const;

    UnicodeString toString() const;

    /** Returns the string in standard exponential notation. */
    UnicodeString toScientificString() const;

    /** Returns the string without exponential notation. Slightly slower than toScientificString(). */
    UnicodeString toPlainString() const;

    /** Visible for testing */
    inline bool isUsingBytes() { return usingBytes; }

    /** Visible for testing */
    inline bool isExplicitExactDouble() { return explicitExactDouble; }

    bool operator==(const DecimalQuantity& other) const;

    inline bool operator!=(const DecimalQuantity& other) const {
        return !(*this == other);
    }

    /**
     * Bogus flag for when a DecimalQuantity is stored on the stack.
     */
    bool bogus = false;

  private:
    /**
     * The power of ten corresponding to the least significant digit in the BCD. For example, if this
     * object represents the number "3.14", the BCD will be "0x314" and the scale will be -2.
     *
     * <p>Note that in {@link java.math.BigDecimal}, the scale is defined differently: the number of
     * digits after the decimal place, which is the negative of our definition of scale.
     */
    int32_t scale;

    /**
     * The number of digits in the BCD. For example, "1007" has BCD "0x1007" and precision 4. The
     * maximum precision is 16 since a long can hold only 16 digits.
     *
     * <p>This value must be re-calculated whenever the value in bcd changes by using {@link
     * #computePrecisionAndCompact()}.
     */
    int32_t precision;

    /**
     * A bitmask of properties relating to the number represented by this object.
     *
     * @see #NEGATIVE_FLAG
     * @see #INFINITY_FLAG
     * @see #NAN_FLAG
     */
    int8_t flags;

    // The following three fields relate to the double-to-ascii fast path algorithm.
    // When a double is given to DecimalQuantityBCD, it is converted to using a fast algorithm. The
    // fast algorithm guarantees correctness to only the first ~12 digits of the double. The process
    // of rounding the number ensures that the converted digits are correct, falling back to a slow-
    // path algorithm if required.  Therefore, if a DecimalQuantity is constructed from a double, it
    // is *required* that roundToMagnitude(), roundToIncrement(), or roundToInfinity() is called. If
    // you don't round, assertions will fail in certain other methods if you try calling them.

    /**
     * Whether the value in the BCD comes from the double fast path without having been rounded to
     * ensure correctness
     */
    UBool isApproximate;

    /**
     * The original number provided by the user and which is represented in BCD. Used when we need to
     * re-compute the BCD for an exact double representation.
     */
    double origDouble;

    /**
     * The change in magnitude relative to the original double. Used when we need to re-compute the
     * BCD for an exact double representation.
     */
    int32_t origDelta;

    // Positions to keep track of leading and trailing zeros.
    // lReqPos is the magnitude of the first required leading zero.
    // rReqPos is the magnitude of the last required trailing zero.
    int32_t lReqPos = 0;
    int32_t rReqPos = 0;

    // The value of the (suppressed) exponent after the number has been put into
    // a notation with exponents (ex: compact, scientific).
    int32_t exponent = 0;

    /**
     * The BCD of the 16 digits of the number represented by this object. Every 4 bits of the long map
     * to one digit. For example, the number "12345" in BCD is "0x12345".
     *
     * <p>Whenever bcd changes internally, {@link #compact()} must be called, except in special cases
     * like setting the digit to zero.
     */
    union {
        struct {
            int8_t *ptr;
            int32_t len;
        } bcdBytes;
        uint64_t bcdLong;
    } fBCD;

    bool usingBytes = false;

    /**
     * Whether this {@link DecimalQuantity} has been explicitly converted to an exact double. true if
     * backed by a double that was explicitly converted via convertToAccurateDouble; false otherwise.
     * Used for testing.
     */
    bool explicitExactDouble = false;

    void roundToMagnitude(int32_t magnitude, RoundingMode roundingMode, bool nickel, UErrorCode& status);

    /**
     * Returns a single digit from the BCD list. No internal state is changed by calling this method.
     *
     * @param position The position of the digit to pop, counted in BCD units from the least
     *     significant digit. If outside the range supported by the implementation, zero is returned.
     * @return The digit at the specified location.
     */
    int8_t getDigitPos(int32_t position) const;

    /**
     * Sets the digit in the BCD list. This method only sets the digit; it is the caller's
     * responsibility to call {@link #compact} after setting the digit.
     *
     * @param position The position of the digit to pop, counted in BCD units from the least
     *     significant digit. If outside the range supported by the implementation, an AssertionError
     *     is thrown.
     * @param value The digit to set at the specified location.
     */
    void setDigitPos(int32_t position, int8_t value);

    /**
     * Adds zeros to the end of the BCD list. This will result in an invalid BCD representation; it is
     * the caller's responsibility to do further manipulation and then call {@link #compact}.
     *
     * @param numDigits The number of zeros to add.
     */
    void shiftLeft(int32_t numDigits);

    /**
     * Directly removes digits from the end of the BCD list.
     * Updates the scale and precision.
     *
     * CAUTION: it is the caller's responsibility to call {@link #compact} after this method.
     */
    void shiftRight(int32_t numDigits);

    /**
     * Directly removes digits from the front of the BCD list.
     * Updates precision.
     *
     * CAUTION: it is the caller's responsibility to call {@link #compact} after this method.
     */
    void popFromLeft(int32_t numDigits);

    /**
     * Sets the internal representation to zero. Clears any values stored in scale, precision,
     * hasDouble, origDouble, origDelta, exponent, and BCD data.
     */
    void setBcdToZero();

    /**
     * Sets the internal BCD state to represent the value in the given int. The int is guaranteed to
     * be either positive. The internal state is guaranteed to be empty when this method is called.
     *
     * @param n The value to consume.
     */
    void readIntToBcd(int32_t n);

    /**
     * Sets the internal BCD state to represent the value in the given long. The long is guaranteed to
     * be either positive. The internal state is guaranteed to be empty when this method is called.
     *
     * @param n The value to consume.
     */
    void readLongToBcd(int64_t n);

    void readDecNumberToBcd(const DecNum& dn);

    void readDoubleConversionToBcd(const char* buffer, int32_t length, int32_t point);

    void copyFieldsFrom(const DecimalQuantity& other);

    void copyBcdFrom(const DecimalQuantity &other);

    void moveBcdFrom(DecimalQuantity& src);

    /**
     * Removes trailing zeros from the BCD (adjusting the scale as required) and then computes the
     * precision. The precision is the number of digits in the number up through the greatest nonzero
     * digit.
     *
     * <p>This method must always be called when bcd changes in order for assumptions to be correct in
     * methods like {@link #fractionCount()}.
     */
    void compact();

    void _setToInt(int32_t n);

    void _setToLong(int64_t n);

    void _setToDoubleFast(double n);

    void _setToDecNum(const DecNum& dn, UErrorCode& status);

    void convertToAccurateDouble();

    /** Ensure that a byte array of at least 40 digits is allocated. */
    void ensureCapacity();

    void ensureCapacity(int32_t capacity);

    /** Switches the internal storage mechanism between the 64-bit long and the byte array. */
    void switchStorage();
};

} // namespace impl
} // namespace number
U_NAMESPACE_END


#endif //__NUMBER_DECIMALQUANTITY_H__

#endif /* #if !UCONFIG_NO_FORMATTING */
