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

#include "charstr.h"
#include "uassert.h"
#include "unicode/numberformatter.h"
#include "number_types.h"
#include "number_decimalquantity.h"
#include "double-conversion.h"
#include "number_roundingutils.h"
#include "number_skeletons.h"
#include "putilimp.h"
#include "string_segment.h"

using namespace icu;
using namespace icu::number;
using namespace icu::number::impl;


using double_conversion::DoubleToStringConverter;
using icu::StringSegment;

void number::impl::parseIncrementOption(const StringSegment &segment,
                                        Precision &outPrecision,
                                        UErrorCode &status) {
    // Need to do char <-> UChar conversion...
    U_ASSERT(U_SUCCESS(status));
    CharString buffer;
    SKELETON_UCHAR_TO_CHAR(buffer, segment.toTempUnicodeString(), 0, segment.length(), status);

    // Utilize DecimalQuantity/decNumber to parse this for us.
    DecimalQuantity dq;
    UErrorCode localStatus = U_ZERO_ERROR;
    dq.setToDecNumber({buffer.data(), buffer.length()}, localStatus);
    if (U_FAILURE(localStatus)) {
        // throw new SkeletonSyntaxException("Invalid rounding increment", segment, e);
        status = U_NUMBER_SKELETON_SYNTAX_ERROR;
        return;
    }
    double increment = dq.toDouble();

    // We also need to figure out how many digits. Do a brute force string operation.
    int decimalOffset = 0;
    while (decimalOffset < segment.length() && segment.charAt(decimalOffset) != '.') {
        decimalOffset++;
    }
    if (decimalOffset == segment.length()) {
        outPrecision = Precision::increment(increment);
    } else {
        int32_t fractionLength = segment.length() - decimalOffset - 1;
        outPrecision = Precision::increment(increment).withMinFraction(fractionLength);
    }
}

namespace {

int32_t getRoundingMagnitudeFraction(int maxFrac) {
    if (maxFrac == -1) {
        return INT32_MIN;
    }
    return -maxFrac;
}

int32_t getRoundingMagnitudeSignificant(const DecimalQuantity &value, int maxSig) {
    if (maxSig == -1) {
        return INT32_MIN;
    }
    int magnitude = value.isZeroish() ? 0 : value.getMagnitude();
    return magnitude - maxSig + 1;
}

int32_t getDisplayMagnitudeFraction(int minFrac) {
    if (minFrac == 0) {
        return INT32_MAX;
    }
    return -minFrac;
}

int32_t getDisplayMagnitudeSignificant(const DecimalQuantity &value, int minSig) {
    int magnitude = value.isZeroish() ? 0 : value.getMagnitude();
    return magnitude - minSig + 1;
}

}


MultiplierProducer::~MultiplierProducer() = default;


digits_t roundingutils::doubleFractionLength(double input, int8_t* singleDigit) {
    char buffer[DoubleToStringConverter::kBase10MaximalLength + 1];
    bool sign; // unused; always positive
    int32_t length;
    int32_t point;
    DoubleToStringConverter::DoubleToAscii(
            input,
            DoubleToStringConverter::DtoaMode::SHORTEST,
            0,
            buffer,
            sizeof(buffer),
            &sign,
            &length,
            &point
    );

    if (singleDigit == nullptr) {
        // no-op
    } else if (length == 1) {
        *singleDigit = buffer[0] - '0';
    } else {
        *singleDigit = -1;
    }

    return static_cast<digits_t>(length - point);
}


Precision Precision::unlimited() {
    return Precision(RND_NONE, {});
}

FractionPrecision Precision::integer() {
    return constructFraction(0, 0);
}

FractionPrecision Precision::fixedFraction(int32_t minMaxFractionPlaces) {
    if (minMaxFractionPlaces >= 0 && minMaxFractionPlaces <= kMaxIntFracSig) {
        return constructFraction(minMaxFractionPlaces, minMaxFractionPlaces);
    } else {
        return {U_NUMBER_ARG_OUTOFBOUNDS_ERROR};
    }
}

FractionPrecision Precision::minFraction(int32_t minFractionPlaces) {
    if (minFractionPlaces >= 0 && minFractionPlaces <= kMaxIntFracSig) {
        return constructFraction(minFractionPlaces, -1);
    } else {
        return {U_NUMBER_ARG_OUTOFBOUNDS_ERROR};
    }
}

FractionPrecision Precision::maxFraction(int32_t maxFractionPlaces) {
    if (maxFractionPlaces >= 0 && maxFractionPlaces <= kMaxIntFracSig) {
        return constructFraction(0, maxFractionPlaces);
    } else {
        return {U_NUMBER_ARG_OUTOFBOUNDS_ERROR};
    }
}

FractionPrecision Precision::minMaxFraction(int32_t minFractionPlaces, int32_t maxFractionPlaces) {
    if (minFractionPlaces >= 0 && maxFractionPlaces <= kMaxIntFracSig &&
        minFractionPlaces <= maxFractionPlaces) {
        return constructFraction(minFractionPlaces, maxFractionPlaces);
    } else {
        return {U_NUMBER_ARG_OUTOFBOUNDS_ERROR};
    }
}

Precision Precision::fixedSignificantDigits(int32_t minMaxSignificantDigits) {
    if (minMaxSignificantDigits >= 1 && minMaxSignificantDigits <= kMaxIntFracSig) {
        return constructSignificant(minMaxSignificantDigits, minMaxSignificantDigits);
    } else {
        return {U_NUMBER_ARG_OUTOFBOUNDS_ERROR};
    }
}

Precision Precision::minSignificantDigits(int32_t minSignificantDigits) {
    if (minSignificantDigits >= 1 && minSignificantDigits <= kMaxIntFracSig) {
        return constructSignificant(minSignificantDigits, -1);
    } else {
        return {U_NUMBER_ARG_OUTOFBOUNDS_ERROR};
    }
}

Precision Precision::maxSignificantDigits(int32_t maxSignificantDigits) {
    if (maxSignificantDigits >= 1 && maxSignificantDigits <= kMaxIntFracSig) {
        return constructSignificant(1, maxSignificantDigits);
    } else {
        return {U_NUMBER_ARG_OUTOFBOUNDS_ERROR};
    }
}

Precision Precision::minMaxSignificantDigits(int32_t minSignificantDigits, int32_t maxSignificantDigits) {
    if (minSignificantDigits >= 1 && maxSignificantDigits <= kMaxIntFracSig &&
        minSignificantDigits <= maxSignificantDigits) {
        return constructSignificant(minSignificantDigits, maxSignificantDigits);
    } else {
        return {U_NUMBER_ARG_OUTOFBOUNDS_ERROR};
    }
}

IncrementPrecision Precision::increment(double roundingIncrement) {
    if (roundingIncrement > 0.0) {
        return constructIncrement(roundingIncrement, 0);
    } else {
        return {U_NUMBER_ARG_OUTOFBOUNDS_ERROR};
    }
}

CurrencyPrecision Precision::currency(UCurrencyUsage currencyUsage) {
    return constructCurrency(currencyUsage);
}

Precision FractionPrecision::withSignificantDigits(
        int32_t minSignificantDigits,
        int32_t maxSignificantDigits,
        UNumberRoundingPriority priority) const {
    if (fType == RND_ERROR) { return *this; } // no-op in error state
    if (minSignificantDigits >= 1 &&
            maxSignificantDigits >= minSignificantDigits &&
            maxSignificantDigits <= kMaxIntFracSig) {
        return constructFractionSignificant(
            *this,
            minSignificantDigits,
            maxSignificantDigits,
            priority);
    } else {
        return {U_NUMBER_ARG_OUTOFBOUNDS_ERROR};
    }
}

Precision FractionPrecision::withMinDigits(int32_t minSignificantDigits) const {
    if (fType == RND_ERROR) { return *this; } // no-op in error state
    if (minSignificantDigits >= 1 && minSignificantDigits <= kMaxIntFracSig) {
        return constructFractionSignificant(
            *this,
            1,
            minSignificantDigits,
            UNUM_ROUNDING_PRIORITY_RELAXED);
    } else {
        return {U_NUMBER_ARG_OUTOFBOUNDS_ERROR};
    }
}

Precision FractionPrecision::withMaxDigits(int32_t maxSignificantDigits) const {
    if (fType == RND_ERROR) { return *this; } // no-op in error state
    if (maxSignificantDigits >= 1 && maxSignificantDigits <= kMaxIntFracSig) {
        return constructFractionSignificant(*this,
            1,
            maxSignificantDigits,
            UNUM_ROUNDING_PRIORITY_STRICT);
    } else {
        return {U_NUMBER_ARG_OUTOFBOUNDS_ERROR};
    }
}

// Private method on base class
Precision Precision::withCurrency(const CurrencyUnit &currency, UErrorCode &status) const {
    if (fType == RND_ERROR) { return *this; } // no-op in error state
    U_ASSERT(fType == RND_CURRENCY);
    const char16_t *isoCode = currency.getISOCurrency();
    double increment = ucurr_getRoundingIncrementForUsage(isoCode, fUnion.currencyUsage, &status);
    int32_t minMaxFrac = ucurr_getDefaultFractionDigitsForUsage(
            isoCode, fUnion.currencyUsage, &status);
    if (increment != 0.0) {
        return constructIncrement(increment, minMaxFrac);
    } else {
        return constructFraction(minMaxFrac, minMaxFrac);
    }
}

// Public method on CurrencyPrecision subclass
Precision CurrencyPrecision::withCurrency(const CurrencyUnit &currency) const {
    UErrorCode localStatus = U_ZERO_ERROR;
    Precision result = Precision::withCurrency(currency, localStatus);
    if (U_FAILURE(localStatus)) {
        return {localStatus};
    }
    return result;
}

Precision IncrementPrecision::withMinFraction(int32_t minFrac) const {
    if (fType == RND_ERROR) { return *this; } // no-op in error state
    if (minFrac >= 0 && minFrac <= kMaxIntFracSig) {
        return constructIncrement(fUnion.increment.fIncrement, minFrac);
    } else {
        return {U_NUMBER_ARG_OUTOFBOUNDS_ERROR};
    }
}

FractionPrecision Precision::constructFraction(int32_t minFrac, int32_t maxFrac) {
    FractionSignificantSettings settings;
    settings.fMinFrac = static_cast<digits_t>(minFrac);
    settings.fMaxFrac = static_cast<digits_t>(maxFrac);
    settings.fMinSig = -1;
    settings.fMaxSig = -1;
    PrecisionUnion union_;
    union_.fracSig = settings;
    return {RND_FRACTION, union_};
}

Precision Precision::constructSignificant(int32_t minSig, int32_t maxSig) {
    FractionSignificantSettings settings;
    settings.fMinFrac = -1;
    settings.fMaxFrac = -1;
    settings.fMinSig = static_cast<digits_t>(minSig);
    settings.fMaxSig = static_cast<digits_t>(maxSig);
    PrecisionUnion union_;
    union_.fracSig = settings;
    return {RND_SIGNIFICANT, union_};
}

Precision
Precision::constructFractionSignificant(
        const FractionPrecision &base,
        int32_t minSig,
        int32_t maxSig,
        UNumberRoundingPriority priority) {
    FractionSignificantSettings settings = base.fUnion.fracSig;
    settings.fMinSig = static_cast<digits_t>(minSig);
    settings.fMaxSig = static_cast<digits_t>(maxSig);
    settings.fPriority = priority;
    PrecisionUnion union_;
    union_.fracSig = settings;
    return {RND_FRACTION_SIGNIFICANT, union_};
}

IncrementPrecision Precision::constructIncrement(double increment, int32_t minFrac) {
    IncrementSettings settings;
    // Note: For number formatting, fIncrement is used for RND_INCREMENT but not
    // RND_INCREMENT_ONE or RND_INCREMENT_FIVE. However, fIncrement is used in all
    // three when constructing a skeleton.
    settings.fIncrement = increment;
    settings.fMinFrac = static_cast<digits_t>(minFrac);
    // One of the few pre-computed quantities:
    // Note: it is possible for minFrac to be more than maxFrac... (misleading)
    int8_t singleDigit;
    settings.fMaxFrac = roundingutils::doubleFractionLength(increment, &singleDigit);
    PrecisionUnion union_;
    union_.increment = settings;
    if (singleDigit == 1) {
        // NOTE: In C++, we must return the correct value type with the correct union.
        // It would be invalid to return a RND_FRACTION here because the methods on the
        // IncrementPrecision type assume that the union is backed by increment data.
        return {RND_INCREMENT_ONE, union_};
    } else if (singleDigit == 5) {
        return {RND_INCREMENT_FIVE, union_};
    } else {
        return {RND_INCREMENT, union_};
    }
}

CurrencyPrecision Precision::constructCurrency(UCurrencyUsage usage) {
    PrecisionUnion union_;
    union_.currencyUsage = usage;
    return {RND_CURRENCY, union_};
}


RoundingImpl::RoundingImpl(const Precision& precision, UNumberFormatRoundingMode roundingMode,
                           const CurrencyUnit& currency, UErrorCode& status)
        : fPrecision(precision), fRoundingMode(roundingMode), fPassThrough(false) {
    if (precision.fType == Precision::RND_CURRENCY) {
        fPrecision = precision.withCurrency(currency, status);
    }
}

RoundingImpl RoundingImpl::passThrough() {
    return {};
}

bool RoundingImpl::isSignificantDigits() const {
    return fPrecision.fType == Precision::RND_SIGNIFICANT;
}

int32_t
RoundingImpl::chooseMultiplierAndApply(impl::DecimalQuantity &input, const impl::MultiplierProducer &producer,
                                  UErrorCode &status) {
    // Do not call this method with zero, NaN, or infinity.
    U_ASSERT(!input.isZeroish());

    // Perform the first attempt at rounding.
    int magnitude = input.getMagnitude();
    int multiplier = producer.getMultiplier(magnitude);
    input.adjustMagnitude(multiplier);
    apply(input, status);

    // If the number rounded to zero, exit.
    if (input.isZeroish() || U_FAILURE(status)) {
        return multiplier;
    }

    // If the new magnitude after rounding is the same as it was before rounding, then we are done.
    // This case applies to most numbers.
    if (input.getMagnitude() == magnitude + multiplier) {
        return multiplier;
    }

    // If the above case DIDN'T apply, then we have a case like 99.9 -> 100 or 999.9 -> 1000:
    // The number rounded up to the next magnitude. Check if the multiplier changes; if it doesn't,
    // we do not need to make any more adjustments.
    int _multiplier = producer.getMultiplier(magnitude + 1);
    if (multiplier == _multiplier) {
        return multiplier;
    }

    // We have a case like 999.9 -> 1000, where the correct output is "1K", not "1000".
    // Fix the magnitude and re-apply the rounding strategy.
    input.adjustMagnitude(_multiplier - multiplier);
    apply(input, status);
    return _multiplier;
}

/** This is the method that contains the actual rounding logic. */
void RoundingImpl::apply(impl::DecimalQuantity &value, UErrorCode& status) const {
    if (U_FAILURE(status)) {
        return;
    }
    if (fPassThrough) {
        return;
    }
    switch (fPrecision.fType) {
        case Precision::RND_BOGUS:
        case Precision::RND_ERROR:
            // Errors should be caught before the apply() method is called
            status = U_INTERNAL_PROGRAM_ERROR;
            break;

        case Precision::RND_NONE:
            value.roundToInfinity();
            break;

        case Precision::RND_FRACTION:
            value.roundToMagnitude(
                    getRoundingMagnitudeFraction(fPrecision.fUnion.fracSig.fMaxFrac),
                    fRoundingMode,
                    status);
            value.setMinFraction(
                    uprv_max(0, -getDisplayMagnitudeFraction(fPrecision.fUnion.fracSig.fMinFrac)));
            break;

        case Precision::RND_SIGNIFICANT:
            value.roundToMagnitude(
                    getRoundingMagnitudeSignificant(value, fPrecision.fUnion.fracSig.fMaxSig),
                    fRoundingMode,
                    status);
            value.setMinFraction(
                    uprv_max(0, -getDisplayMagnitudeSignificant(value, fPrecision.fUnion.fracSig.fMinSig)));
            // Make sure that digits are displayed on zero.
            if (value.isZeroish() && fPrecision.fUnion.fracSig.fMinSig > 0) {
                value.setMinInteger(1);
            }
            break;

        case Precision::RND_FRACTION_SIGNIFICANT: {
            int32_t roundingMag1 = getRoundingMagnitudeFraction(fPrecision.fUnion.fracSig.fMaxFrac);
            int32_t roundingMag2 = getRoundingMagnitudeSignificant(value, fPrecision.fUnion.fracSig.fMaxSig);
            int32_t roundingMag;
            if (fPrecision.fUnion.fracSig.fPriority == UNUM_ROUNDING_PRIORITY_RELAXED) {
                roundingMag = uprv_min(roundingMag1, roundingMag2);
            } else {
                roundingMag = uprv_max(roundingMag1, roundingMag2);
            }
            value.roundToMagnitude(roundingMag, fRoundingMode, status);

            int32_t displayMag1 = getDisplayMagnitudeFraction(fPrecision.fUnion.fracSig.fMinFrac);
            int32_t displayMag2 = getDisplayMagnitudeSignificant(value, fPrecision.fUnion.fracSig.fMinSig);
            int32_t displayMag = uprv_min(displayMag1, displayMag2);
            value.setMinFraction(uprv_max(0, -displayMag));

            break;
        }

        case Precision::RND_INCREMENT:
            value.roundToIncrement(
                    fPrecision.fUnion.increment.fIncrement,
                    fRoundingMode,
                    status);
            value.setMinFraction(fPrecision.fUnion.increment.fMinFrac);
            break;

        case Precision::RND_INCREMENT_ONE:
            value.roundToMagnitude(
                    -fPrecision.fUnion.increment.fMaxFrac,
                    fRoundingMode,
                    status);
            value.setMinFraction(fPrecision.fUnion.increment.fMinFrac);
            break;

        case Precision::RND_INCREMENT_FIVE:
            value.roundToNickel(
                    -fPrecision.fUnion.increment.fMaxFrac,
                    fRoundingMode,
                    status);
            value.setMinFraction(fPrecision.fUnion.increment.fMinFrac);
            break;

        case Precision::RND_CURRENCY:
            // Call .withCurrency() before .apply()!
            UPRV_UNREACHABLE;

        default:
            UPRV_UNREACHABLE;
    }
}

void RoundingImpl::apply(impl::DecimalQuantity &value, int32_t minInt, UErrorCode /*status*/) {
    // This method is intended for the one specific purpose of helping print "00.000E0".
    U_ASSERT(isSignificantDigits());
    U_ASSERT(value.isZeroish());
    value.setMinFraction(fPrecision.fUnion.fracSig.fMinSig - minInt);
}

#endif /* #if !UCONFIG_NO_FORMATTING */
