// © 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;

/**
 * A 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 occurred; 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);

    /**
     * Resets the DecimalQuantity to the value before adjustMagnitude and adjustExponent.
     */
    void resetExponent();

    /**
     * @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. */
    DecNum& toDecNum(DecNum& output, UErrorCode& status) const;

    DecimalQuantity &setToInt(int32_t n);

    DecimalQuantity &setToLong(int64_t n);

    DecimalQuantity &setToDouble(double n);

    /**
     * Produces a DecimalQuantity that was parsed from a string by the decNumber
     * C Library.
     *
     * decNumber is similar to BigDecimal in Java, and supports parsing strings
     * such as "123.456621E+40".
     */
    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, and to ensure
     * that the precision field is updated to reflect the correct number of digits if a
     * nonzero digit is added to the decimal.
     *
     * @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 */
