// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
*******************************************************************************
* Copyright (C) 2010-2015, International Business Machines Corporation and
* others. All Rights Reserved.
*******************************************************************************
*
*
* File NUMSYS.CPP
*
* Modification History:*
*   Date        Name        Description
*
********************************************************************************
*/

#include "unicode/utypes.h"
#include "unicode/localpointer.h"
#include "unicode/uchar.h"
#include "unicode/unistr.h"
#include "unicode/ures.h"
#include "unicode/ustring.h"
#include "unicode/uloc.h"
#include "unicode/schriter.h"
#include "unicode/numsys.h"
#include "cstring.h"
#include "uassert.h"
#include "ucln_in.h"
#include "umutex.h"
#include "uresimp.h"
#include "numsys_impl.h"

#if !UCONFIG_NO_FORMATTING

U_NAMESPACE_BEGIN

// Useful constants

#define DEFAULT_DIGITS UNICODE_STRING_SIMPLE("0123456789")
static const char gNumberingSystems[] = "numberingSystems";
static const char gNumberElements[] = "NumberElements";
static const char gDefault[] = "default";
static const char gNative[] = "native";
static const char gTraditional[] = "traditional";
static const char gFinance[] = "finance";
static const char gDesc[] = "desc";
static const char gRadix[] = "radix";
static const char gAlgorithmic[] = "algorithmic";
static const char gLatn[] = "latn";


UOBJECT_DEFINE_RTTI_IMPLEMENTATION(NumberingSystem)
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(NumsysNameEnumeration)

    /**
     * Default Constructor.
     *
     * @draft ICU 4.2
     */

NumberingSystem::NumberingSystem() {
     radix = 10;
     algorithmic = FALSE;
     UnicodeString defaultDigits = DEFAULT_DIGITS;
     desc.setTo(defaultDigits);
     uprv_strcpy(name,gLatn);
}

    /**
     * Copy constructor.
     * @draft ICU 4.2
     */

NumberingSystem::NumberingSystem(const NumberingSystem& other) 
:  UObject(other) {
    *this=other;
}

NumberingSystem* U_EXPORT2
NumberingSystem::createInstance(int32_t radix_in, UBool isAlgorithmic_in, const UnicodeString & desc_in, UErrorCode &status) {

    if (U_FAILURE(status)) {
        return nullptr;
    }

    if ( radix_in < 2 ) {
        status = U_ILLEGAL_ARGUMENT_ERROR;
        return nullptr;
    }

    if ( !isAlgorithmic_in ) {
       if ( desc_in.countChar32() != radix_in ) {
           status = U_ILLEGAL_ARGUMENT_ERROR;
           return nullptr;
       }
    }

    LocalPointer<NumberingSystem> ns(new NumberingSystem(), status);
    if (U_FAILURE(status)) {
        return nullptr;
    }

    ns->setRadix(radix_in);
    ns->setDesc(desc_in);
    ns->setAlgorithmic(isAlgorithmic_in);
    ns->setName(nullptr);

    return ns.orphan();
}

NumberingSystem* U_EXPORT2
NumberingSystem::createInstance(const Locale & inLocale, UErrorCode& status) {

    if (U_FAILURE(status)) {
        return nullptr;
    }

    UBool nsResolved = TRUE;
    UBool usingFallback = FALSE;
    char buffer[ULOC_KEYWORDS_CAPACITY];
    int32_t count = inLocale.getKeywordValue("numbers", buffer, sizeof(buffer), status);
    if (U_FAILURE(status) || status == U_STRING_NOT_TERMINATED_WARNING) {
        // the "numbers" keyword exceeds ULOC_KEYWORDS_CAPACITY; ignore and use default.
        count = 0;
        status = U_ZERO_ERROR;
    }
    if ( count > 0 ) { // @numbers keyword was specified in the locale
        U_ASSERT(count < ULOC_KEYWORDS_CAPACITY);
        buffer[count] = '\0'; // Make sure it is null terminated.
        if ( !uprv_strcmp(buffer,gDefault) || !uprv_strcmp(buffer,gNative) || 
             !uprv_strcmp(buffer,gTraditional) || !uprv_strcmp(buffer,gFinance)) {
            nsResolved = FALSE;
        }
    } else {
        uprv_strcpy(buffer, gDefault);
        nsResolved = FALSE;
    }

    if (!nsResolved) { // Resolve the numbering system ( default, native, traditional or finance ) into a "real" numbering system
        UErrorCode localStatus = U_ZERO_ERROR;
        LocalUResourceBundlePointer resource(ures_open(nullptr, inLocale.getName(), &localStatus));
        LocalUResourceBundlePointer numberElementsRes(ures_getByKey(resource.getAlias(), gNumberElements, nullptr, &localStatus));
        // Don't stomp on the catastrophic failure of OOM.
        if (localStatus == U_MEMORY_ALLOCATION_ERROR) {
            status = U_MEMORY_ALLOCATION_ERROR;
            return nullptr;
        }
        while (!nsResolved) {
            localStatus = U_ZERO_ERROR;
            count = 0;
            const UChar *nsName = ures_getStringByKeyWithFallback(numberElementsRes.getAlias(), buffer, &count, &localStatus);
            // Don't stomp on the catastrophic failure of OOM.
            if (localStatus == U_MEMORY_ALLOCATION_ERROR) {
                status = U_MEMORY_ALLOCATION_ERROR;
                return nullptr;
            }
            if ( count > 0 && count < ULOC_KEYWORDS_CAPACITY ) { // numbering system found
                u_UCharsToChars(nsName, buffer, count);
                buffer[count] = '\0'; // Make sure it is null terminated.
                nsResolved = TRUE;
            } 

            if (!nsResolved) { // Fallback behavior per TR35 - traditional falls back to native, finance and native fall back to default
                if (!uprv_strcmp(buffer,gNative) || !uprv_strcmp(buffer,gFinance)) { 
                    uprv_strcpy(buffer,gDefault);
                } else if (!uprv_strcmp(buffer,gTraditional)) {
                    uprv_strcpy(buffer,gNative);
                } else { // If we get here we couldn't find even the default numbering system
                    usingFallback = TRUE;
                    nsResolved = TRUE;
                }
            }
        }
    }

    if (usingFallback) {
        status = U_USING_FALLBACK_WARNING;
        NumberingSystem *ns = new NumberingSystem();
        if (ns == nullptr) {
            status = U_MEMORY_ALLOCATION_ERROR;
        }
        return ns;
    } else {
        return NumberingSystem::createInstanceByName(buffer, status);
    }
 }

NumberingSystem* U_EXPORT2
NumberingSystem::createInstance(UErrorCode& status) {
    return NumberingSystem::createInstance(Locale::getDefault(), status);
}

NumberingSystem* U_EXPORT2
NumberingSystem::createInstanceByName(const char *name, UErrorCode& status) {
    int32_t radix = 10;
    int32_t algorithmic = 0;

    LocalUResourceBundlePointer numberingSystemsInfo(ures_openDirect(nullptr, gNumberingSystems, &status));
    LocalUResourceBundlePointer nsCurrent(ures_getByKey(numberingSystemsInfo.getAlias(), gNumberingSystems, nullptr, &status));
    LocalUResourceBundlePointer nsTop(ures_getByKey(nsCurrent.getAlias(), name, nullptr, &status));

    UnicodeString nsd = ures_getUnicodeStringByKey(nsTop.getAlias(), gDesc, &status);

    ures_getByKey(nsTop.getAlias(), gRadix, nsCurrent.getAlias(), &status);
    radix = ures_getInt(nsCurrent.getAlias(), &status);

    ures_getByKey(nsTop.getAlias(), gAlgorithmic, nsCurrent.getAlias(), &status);
    algorithmic = ures_getInt(nsCurrent.getAlias(), &status);

    UBool isAlgorithmic = ( algorithmic == 1 );

    if (U_FAILURE(status)) {
        // Don't stomp on the catastrophic failure of OOM.
        if (status != U_MEMORY_ALLOCATION_ERROR) {
            status = U_UNSUPPORTED_ERROR;
        }
        return nullptr;
    }

    LocalPointer<NumberingSystem> ns(NumberingSystem::createInstance(radix, isAlgorithmic, nsd, status), status);
    if (U_FAILURE(status)) {
        return nullptr;
    }
    ns->setName(name);
    return ns.orphan();
}

    /**
     * Destructor.
     * @draft ICU 4.2
     */
NumberingSystem::~NumberingSystem() {
}

int32_t NumberingSystem::getRadix() const {
    return radix;
}

UnicodeString NumberingSystem::getDescription() const {
    return desc;
}

const char * NumberingSystem::getName() const {
    return name;
}

void NumberingSystem::setRadix(int32_t r) {
    radix = r;
}

void NumberingSystem::setAlgorithmic(UBool c) {
    algorithmic = c;
}

void NumberingSystem::setDesc(const UnicodeString &d) {
    desc.setTo(d);
}
void NumberingSystem::setName(const char *n) {
    if ( n == nullptr ) {
        name[0] = (char) 0;
    } else {
        uprv_strncpy(name,n,kInternalNumSysNameCapacity);
        name[kInternalNumSysNameCapacity] = '\0'; // Make sure it is null terminated.
    }
}
UBool NumberingSystem::isAlgorithmic() const {
    return ( algorithmic );
}

namespace {

UVector* gNumsysNames = nullptr;
UInitOnce gNumSysInitOnce = U_INITONCE_INITIALIZER;

U_CFUNC UBool U_CALLCONV numSysCleanup() {
    delete gNumsysNames;
    gNumsysNames = nullptr;
    gNumSysInitOnce.reset();
    return true;
}

U_CFUNC void initNumsysNames(UErrorCode &status) {
    U_ASSERT(gNumsysNames == nullptr);
    ucln_i18n_registerCleanup(UCLN_I18N_NUMSYS, numSysCleanup);

    // TODO: Simple array of UnicodeString objects, based on length of table resource?
    LocalPointer<UVector> numsysNames(new UVector(uprv_deleteUObject, nullptr, status), status);
    if (U_FAILURE(status)) {
        return;
    }

    UErrorCode rbstatus = U_ZERO_ERROR;
    UResourceBundle *numberingSystemsInfo = ures_openDirect(nullptr, "numberingSystems", &rbstatus);
    numberingSystemsInfo =
            ures_getByKey(numberingSystemsInfo, "numberingSystems", numberingSystemsInfo, &rbstatus);
    if (U_FAILURE(rbstatus)) {
        // Don't stomp on the catastrophic failure of OOM.
        if (rbstatus == U_MEMORY_ALLOCATION_ERROR) {
            status = rbstatus;
        } else {
            status = U_MISSING_RESOURCE_ERROR;
        }
        ures_close(numberingSystemsInfo);
        return;
    }

    while ( ures_hasNext(numberingSystemsInfo) && U_SUCCESS(status) ) {
        LocalUResourceBundlePointer nsCurrent(ures_getNextResource(numberingSystemsInfo, nullptr, &rbstatus));
        if (rbstatus == U_MEMORY_ALLOCATION_ERROR) {
            status = rbstatus; // we want to report OOM failure back to the caller.
            break;
        }
        const char *nsName = ures_getKey(nsCurrent.getAlias());
        LocalPointer<UnicodeString> newElem(new UnicodeString(nsName, -1, US_INV), status);
        if (U_SUCCESS(status)) {
            numsysNames->addElement(newElem.getAlias(), status);
            if (U_SUCCESS(status)) {
                newElem.orphan(); // on success, the numsysNames vector owns newElem.
            }
        }
    }

    ures_close(numberingSystemsInfo);
    if (U_SUCCESS(status)) {
        gNumsysNames = numsysNames.orphan();
    }
    return;
}

}   // end anonymous namespace

StringEnumeration* NumberingSystem::getAvailableNames(UErrorCode &status) {
    umtx_initOnce(gNumSysInitOnce, &initNumsysNames, status);
    LocalPointer<StringEnumeration> result(new NumsysNameEnumeration(status), status);
    return result.orphan();
}

NumsysNameEnumeration::NumsysNameEnumeration(UErrorCode& status) : pos(0) {
    (void)status;
}

const UnicodeString*
NumsysNameEnumeration::snext(UErrorCode& status) {
    if (U_SUCCESS(status) && (gNumsysNames != nullptr) && (pos < gNumsysNames->size())) {
        return (const UnicodeString*)gNumsysNames->elementAt(pos++);
    }
    return nullptr;
}

void
NumsysNameEnumeration::reset(UErrorCode& /*status*/) {
    pos=0;
}

int32_t
NumsysNameEnumeration::count(UErrorCode& /*status*/) const {
    return (gNumsysNames==nullptr) ? 0 : gNumsysNames->size();
}

NumsysNameEnumeration::~NumsysNameEnumeration() {
}
U_NAMESPACE_END

#endif /* #if !UCONFIG_NO_FORMATTING */

//eof
