// © 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 "unicode/numberformatter.h"
#include "number_patternstring.h"
#include "uresimp.h"

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

namespace {

int16_t getMinGroupingForLocale(const Locale& locale) {
    // TODO: Cache this?
    UErrorCode localStatus = U_ZERO_ERROR;
    LocalUResourceBundlePointer bundle(ures_open(NULL, locale.getName(), &localStatus));
    int32_t resultLen = 0;
    const char16_t* result = ures_getStringByKeyWithFallback(
        bundle.getAlias(),
        "NumberElements/minimumGroupingDigits",
        &resultLen,
        &localStatus);
    // TODO: Is it safe to assume resultLen == 1? Would locales set minGrouping >= 10?
    if (U_FAILURE(localStatus) || resultLen != 1) {
        return 1;
    }
    return result[0] - u'0';
}

}

Grouper Grouper::forStrategy(UGroupingStrategy grouping) {
    switch (grouping) {
    case UNUM_GROUPING_OFF:
        return {-1, -1, -2, grouping};
    case UNUM_GROUPING_AUTO:
        return {-2, -2, -2, grouping};
    case UNUM_GROUPING_MIN2:
        return {-2, -2, -3, grouping};
    case UNUM_GROUPING_ON_ALIGNED:
        return {-4, -4, 1, grouping};
    case UNUM_GROUPING_THOUSANDS:
        return {3, 3, 1, grouping};
    default:
        U_ASSERT(FALSE);
        return {}; // return a value: silence compiler warning
    }
}

Grouper Grouper::forProperties(const DecimalFormatProperties& properties) {
    if (!properties.groupingUsed) {
        return forStrategy(UNUM_GROUPING_OFF);
    }
    auto grouping1 = static_cast<int16_t>(properties.groupingSize);
    auto grouping2 = static_cast<int16_t>(properties.secondaryGroupingSize);
    auto minGrouping = static_cast<int16_t>(properties.minimumGroupingDigits);
    grouping1 = grouping1 > 0 ? grouping1 : grouping2 > 0 ? grouping2 : grouping1;
    grouping2 = grouping2 > 0 ? grouping2 : grouping1;
    return {grouping1, grouping2, minGrouping, UNUM_GROUPING_COUNT};
}

void Grouper::setLocaleData(const impl::ParsedPatternInfo &patternInfo, const Locale& locale) {
    if (fGrouping1 != -2 && fGrouping2 != -4) {
        return;
    }
    auto grouping1 = static_cast<int16_t> (patternInfo.positive.groupingSizes & 0xffff);
    auto grouping2 = static_cast<int16_t> ((patternInfo.positive.groupingSizes >> 16) & 0xffff);
    auto grouping3 = static_cast<int16_t> ((patternInfo.positive.groupingSizes >> 32) & 0xffff);
    if (grouping2 == -1) {
        grouping1 = fGrouping1 == -4 ? (short) 3 : (short) -1;
    }
    if (grouping3 == -1) {
        grouping2 = grouping1;
    }
    if (fMinGrouping == -2) {
        fMinGrouping = getMinGroupingForLocale(locale);
    } else if (fMinGrouping == -3) {
        fMinGrouping = uprv_max(2, getMinGroupingForLocale(locale));
    } else {
        // leave fMinGrouping alone
    }
    fGrouping1 = grouping1;
    fGrouping2 = grouping2;
}

bool Grouper::groupAtPosition(int32_t position, const impl::DecimalQuantity &value) const {
    U_ASSERT(fGrouping1 > -2);
    if (fGrouping1 == -1 || fGrouping1 == 0) {
        // Either -1 or 0 means "no grouping"
        return false;
    }
    position -= fGrouping1;
    return position >= 0 && (position % fGrouping2) == 0
           && value.getUpperDisplayMagnitude() - fGrouping1 + 1 >= fMinGrouping;
}

int16_t Grouper::getPrimary() const {
    return fGrouping1;
}

int16_t Grouper::getSecondary() const {
    return fGrouping2;
}

#endif /* #if !UCONFIG_NO_FORMATTING */
