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

#include "unicode/utypes.h"

#if !UCONFIG_NO_FORMATTING

// Allow implicit conversion from char16_t* to UnicodeString for this file:
// Helpful in toString methods and elsewhere.
#define UNISTR_FROM_STRING_EXPLICIT

#include "numparse_types.h"
#include "number_currencysymbols.h"

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


CurrencySymbols::CurrencySymbols(CurrencyUnit currency, const Locale& locale, UErrorCode& status)
        : fCurrency(currency), fLocaleName(locale.getName(), status) {
    fCurrencySymbol.setToBogus();
    fIntlCurrencySymbol.setToBogus();
}

CurrencySymbols::CurrencySymbols(CurrencyUnit currency, const Locale& locale,
                                 const DecimalFormatSymbols& symbols, UErrorCode& status)
        : CurrencySymbols(currency, locale, status) {
    // If either of the overrides is present, save it in the local UnicodeString.
    if (symbols.isCustomCurrencySymbol()) {
        fCurrencySymbol = symbols.getConstSymbol(DecimalFormatSymbols::kCurrencySymbol);
    }
    if (symbols.isCustomIntlCurrencySymbol()) {
        fIntlCurrencySymbol = symbols.getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol);
    }
}

const char16_t* CurrencySymbols::getIsoCode() const {
    return fCurrency.getISOCurrency();
}

UnicodeString CurrencySymbols::getNarrowCurrencySymbol(UErrorCode& status) const {
    // Note: currently no override is available for narrow currency symbol
    return loadSymbol(UCURR_NARROW_SYMBOL_NAME, status);
}

UnicodeString CurrencySymbols::getCurrencySymbol(UErrorCode& status) const {
    if (!fCurrencySymbol.isBogus()) {
        return fCurrencySymbol;
    }
    return loadSymbol(UCURR_SYMBOL_NAME, status);
}

UnicodeString CurrencySymbols::loadSymbol(UCurrNameStyle selector, UErrorCode& status) const {
    const char16_t* isoCode = fCurrency.getISOCurrency();
    UBool ignoredIsChoiceFormatFillIn = FALSE;
    int32_t symbolLen = 0;
    const char16_t* symbol = ucurr_getName(
            isoCode,
            fLocaleName.data(),
            selector,
            &ignoredIsChoiceFormatFillIn,
            &symbolLen,
            &status);
    // If given an unknown currency, ucurr_getName returns the input string, which we can't alias safely!
    // Otherwise, symbol points to a resource bundle, and we can use readonly-aliasing constructor.
    if (symbol == isoCode) {
        return UnicodeString(isoCode, 3);
    } else {
        return UnicodeString(TRUE, symbol, symbolLen);
    }
}

UnicodeString CurrencySymbols::getIntlCurrencySymbol(UErrorCode&) const {
    if (!fIntlCurrencySymbol.isBogus()) {
        return fIntlCurrencySymbol;
    }
    // Note: Not safe to use readonly-aliasing constructor here because the buffer belongs to this object,
    // which could be destructed or moved during the lifetime of the return value.
    return UnicodeString(fCurrency.getISOCurrency(), 3);
}

UnicodeString CurrencySymbols::getPluralName(StandardPlural::Form plural, UErrorCode& status) const {
    const char16_t* isoCode = fCurrency.getISOCurrency();
    UBool isChoiceFormat = FALSE;
    int32_t symbolLen = 0;
    const char16_t* symbol = ucurr_getPluralName(
            isoCode,
            fLocaleName.data(),
            &isChoiceFormat,
            StandardPlural::getKeyword(plural),
            &symbolLen,
            &status);
    // If given an unknown currency, ucurr_getName returns the input string, which we can't alias safely!
    // Otherwise, symbol points to a resource bundle, and we can use readonly-aliasing constructor.
    if (symbol == isoCode) {
        return UnicodeString(isoCode, 3);
    } else {
        return UnicodeString(TRUE, symbol, symbolLen);
    }
}


CurrencyUnit
icu::number::impl::resolveCurrency(const DecimalFormatProperties& properties, const Locale& locale,
                                   UErrorCode& status) {
    if (!properties.currency.isNull()) {
        return properties.currency.getNoError();
    } else {
        UErrorCode localStatus = U_ZERO_ERROR;
        char16_t buf[4] = {};
        ucurr_forLocale(locale.getName(), buf, 4, &localStatus);
        if (U_SUCCESS(localStatus)) {
            return CurrencyUnit(buf, status);
        } else {
            // Default currency (XXX)
            return CurrencyUnit();
        }
    }
}


#endif /* #if !UCONFIG_NO_FORMATTING */
