// © 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 && !UPRV_INCOMPLETE_CPP11_SUPPORT

#include "uassert.h"
#include "unicode/numberformatter.h"
#include "number_types.h"
#include "number_decimalquantity.h"

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

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.isZero() ? 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.isZero() ? 0 : value.getMagnitude();
    return magnitude - minSig + 1;
}

}


Rounder Rounder::unlimited() {
    return Rounder(RND_NONE, {}, kDefaultMode);
}

FractionRounder Rounder::integer() {
    return constructFraction(0, 0);
}

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

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

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

FractionRounder Rounder::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};
    }
}

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

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

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

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

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

CurrencyRounder Rounder::currency(UCurrencyUsage currencyUsage) {
    return constructCurrency(currencyUsage);
}

Rounder Rounder::withMode(RoundingMode roundingMode) const {
    if (fType == RND_ERROR) { return *this; } // no-op in error state
    return {fType, fUnion, roundingMode};
}

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

Rounder FractionRounder::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);
    } else {
        return {U_NUMBER_ARG_OUTOFBOUNDS_ERROR};
    }
}

// Private method on base class
Rounder Rounder::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 CurrencyRounder subclass
Rounder CurrencyRounder::withCurrency(const CurrencyUnit &currency) const {
    UErrorCode localStatus = U_ZERO_ERROR;
    Rounder result = Rounder::withCurrency(currency, localStatus);
    if (U_FAILURE(localStatus)) {
        return {localStatus};
    }
    return result;
}

Rounder IncrementRounder::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};
    }
}

FractionRounder Rounder::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;
    RounderUnion union_;
    union_.fracSig = settings;
    return {RND_FRACTION, union_, kDefaultMode};
}

Rounder Rounder::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);
    RounderUnion union_;
    union_.fracSig = settings;
    return {RND_SIGNIFICANT, union_, kDefaultMode};
}

Rounder
Rounder::constructFractionSignificant(const FractionRounder &base, int32_t minSig, int32_t maxSig) {
    FractionSignificantSettings settings = base.fUnion.fracSig;
    settings.fMinSig = static_cast<digits_t>(minSig);
    settings.fMaxSig = static_cast<digits_t>(maxSig);
    RounderUnion union_;
    union_.fracSig = settings;
    return {RND_FRACTION_SIGNIFICANT, union_, kDefaultMode};
}

IncrementRounder Rounder::constructIncrement(double increment, int32_t minFrac) {
    IncrementSettings settings;
    settings.fIncrement = increment;
    settings.fMinFrac = static_cast<digits_t>(minFrac);
    RounderUnion union_;
    union_.increment = settings;
    return {RND_INCREMENT, union_, kDefaultMode};
}

CurrencyRounder Rounder::constructCurrency(UCurrencyUsage usage) {
    RounderUnion union_;
    union_.currencyUsage = usage;
    return {RND_CURRENCY, union_, kDefaultMode};
}

Rounder Rounder::constructPassThrough() {
    RounderUnion union_;
    union_.errorCode = U_ZERO_ERROR; // initialize the variable
    return {RND_PASS_THROUGH, union_, kDefaultMode};
}

void Rounder::setLocaleData(const CurrencyUnit &currency, UErrorCode &status) {
    if (fType == RND_CURRENCY) {
        *this = withCurrency(currency, status);
    }
}

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

    // 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.isZero() || 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 Rounder::apply(impl::DecimalQuantity &value, UErrorCode& status) const {
    switch (fType) {
        case RND_BOGUS:
        case RND_ERROR:
            // Errors should be caught before the apply() method is called
            status = U_INTERNAL_PROGRAM_ERROR;
            break;

        case RND_NONE:
            value.roundToInfinity();
            break;

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

        case RND_SIGNIFICANT:
            value.roundToMagnitude(
                    getRoundingMagnitudeSignificant(value, fUnion.fracSig.fMaxSig),
                    fRoundingMode,
                    status);
            value.setFractionLength(
                    uprv_max(0, -getDisplayMagnitudeSignificant(value, fUnion.fracSig.fMinSig)),
                    INT32_MAX);
            break;

        case RND_FRACTION_SIGNIFICANT: {
            int32_t displayMag = getDisplayMagnitudeFraction(fUnion.fracSig.fMinFrac);
            int32_t roundingMag = getRoundingMagnitudeFraction(fUnion.fracSig.fMaxFrac);
            if (fUnion.fracSig.fMinSig == -1) {
                // Max Sig override
                int32_t candidate = getRoundingMagnitudeSignificant(value, fUnion.fracSig.fMaxSig);
                roundingMag = uprv_max(roundingMag, candidate);
            } else {
                // Min Sig override
                int32_t candidate = getDisplayMagnitudeSignificant(value, fUnion.fracSig.fMinSig);
                roundingMag = uprv_min(roundingMag, candidate);
            }
            value.roundToMagnitude(roundingMag, fRoundingMode, status);
            value.setFractionLength(uprv_max(0, -displayMag), INT32_MAX);
            break;
        }

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

        case RND_CURRENCY:
            // Call .withCurrency() before .apply()!
            U_ASSERT(false);
            break;

        case RND_PASS_THROUGH:
            break;
    }
}

void Rounder::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(fType == RND_SIGNIFICANT);
    U_ASSERT(value.isZero());
    value.setFractionLength(fUnion.fracSig.fMinSig - minInt, INT32_MAX);
}

#endif /* #if !UCONFIG_NO_FORMATTING */
