// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
 *******************************************************************************
 * Copyright (C) 2008-2015, Google, International Business Machines Corporation
 * and others. All Rights Reserved.
 *******************************************************************************
 */

#include "unicode/tmutfmt.h"

#if !UCONFIG_NO_FORMATTING

#if defined(STARBOARD)
#include "starboard/client_porting/poem/assert_poem.h"
#include "starboard/client_porting/poem/string_poem.h"
#endif  // defined(STARBOARD)
#include "unicode/decimfmt.h"
#include "unicode/localpointer.h"
#include "plurrule_impl.h"
#include "uvector.h"
#include "charstr.h"
#include "cmemory.h"
#include "cstring.h"
#include "hash.h"
#include "uresimp.h"
#include "ureslocs.h"
#include "unicode/msgfmt.h"
#include "uassert.h"

#define LEFT_CURLY_BRACKET  ((UChar)0x007B)
#define RIGHT_CURLY_BRACKET ((UChar)0x007D)
#define SPACE             ((UChar)0x0020)
#define DIGIT_ZERO        ((UChar)0x0030)
#define LOW_S             ((UChar)0x0073)
#define LOW_M             ((UChar)0x006D)
#define LOW_I             ((UChar)0x0069)
#define LOW_N             ((UChar)0x006E)
#define LOW_H             ((UChar)0x0068)
#define LOW_W             ((UChar)0x0077)
#define LOW_D             ((UChar)0x0064)
#define LOW_Y             ((UChar)0x0079)
#define LOW_Z             ((UChar)0x007A)
#define LOW_E             ((UChar)0x0065)
#define LOW_R             ((UChar)0x0072)
#define LOW_O             ((UChar)0x006F)
#define LOW_N             ((UChar)0x006E)
#define LOW_T             ((UChar)0x0074)


//TODO: define in compile time
//#define TMUTFMT_DEBUG 1

#ifdef TMUTFMT_DEBUG
#include <iostream>
#endif

U_NAMESPACE_BEGIN



UOBJECT_DEFINE_RTTI_IMPLEMENTATION(TimeUnitFormat)

static const char gUnitsTag[] = "units";
static const char gShortUnitsTag[] = "unitsShort";
static const char gTimeUnitYear[] = "year";
static const char gTimeUnitMonth[] = "month";
static const char gTimeUnitDay[] = "day";
static const char gTimeUnitWeek[] = "week";
static const char gTimeUnitHour[] = "hour";
static const char gTimeUnitMinute[] = "minute";
static const char gTimeUnitSecond[] = "second";
static const char gPluralCountOther[] = "other";

static const UChar DEFAULT_PATTERN_FOR_SECOND[] = {LEFT_CURLY_BRACKET, DIGIT_ZERO, RIGHT_CURLY_BRACKET, SPACE, LOW_S, 0};
static const UChar DEFAULT_PATTERN_FOR_MINUTE[] = {LEFT_CURLY_BRACKET, DIGIT_ZERO, RIGHT_CURLY_BRACKET, SPACE, LOW_M, LOW_I, LOW_N, 0};
static const UChar DEFAULT_PATTERN_FOR_HOUR[] = {LEFT_CURLY_BRACKET, DIGIT_ZERO, RIGHT_CURLY_BRACKET, SPACE, LOW_H, 0};
static const UChar DEFAULT_PATTERN_FOR_WEEK[] = {LEFT_CURLY_BRACKET, DIGIT_ZERO, RIGHT_CURLY_BRACKET, SPACE, LOW_W, 0};
static const UChar DEFAULT_PATTERN_FOR_DAY[] = {LEFT_CURLY_BRACKET, DIGIT_ZERO, RIGHT_CURLY_BRACKET, SPACE, LOW_D, 0};
static const UChar DEFAULT_PATTERN_FOR_MONTH[] = {LEFT_CURLY_BRACKET, DIGIT_ZERO, RIGHT_CURLY_BRACKET, SPACE, LOW_M, 0};
static const UChar DEFAULT_PATTERN_FOR_YEAR[] = {LEFT_CURLY_BRACKET, DIGIT_ZERO, RIGHT_CURLY_BRACKET, SPACE, LOW_Y, 0};

static const UChar PLURAL_COUNT_ZERO[] = {LOW_Z, LOW_E, LOW_R, LOW_O, 0};
static const UChar PLURAL_COUNT_ONE[] = {LOW_O, LOW_N, LOW_E, 0};
static const UChar PLURAL_COUNT_TWO[] = {LOW_T, LOW_W, LOW_O, 0};

TimeUnitFormat::TimeUnitFormat(UErrorCode& status) {
    initMeasureFormat(Locale::getDefault(), UMEASFMT_WIDTH_WIDE, NULL, status);
    create(UTMUTFMT_FULL_STYLE, status);
}


TimeUnitFormat::TimeUnitFormat(const Locale& locale, UErrorCode& status) {
    initMeasureFormat(locale, UMEASFMT_WIDTH_WIDE, NULL, status);
    create(UTMUTFMT_FULL_STYLE, status);
}


TimeUnitFormat::TimeUnitFormat(const Locale& locale, UTimeUnitFormatStyle style, UErrorCode& status) {
    switch (style) {
    case UTMUTFMT_FULL_STYLE:
        initMeasureFormat(locale, UMEASFMT_WIDTH_WIDE, NULL, status);
        break;
    case UTMUTFMT_ABBREVIATED_STYLE:
        initMeasureFormat(locale, UMEASFMT_WIDTH_SHORT, NULL, status);
        break;
    default:
        initMeasureFormat(locale, UMEASFMT_WIDTH_WIDE, NULL, status);
        break;
    }
    create(style, status);
}

TimeUnitFormat::TimeUnitFormat(const TimeUnitFormat& other)
:   MeasureFormat(other),
    fStyle(other.fStyle)
{
    for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR;
         i < TimeUnit::UTIMEUNIT_FIELD_COUNT;
         i = (TimeUnit::UTimeUnitFields)(i+1)) {
        UErrorCode status = U_ZERO_ERROR;
        fTimeUnitToCountToPatterns[i] = initHash(status);
        if (U_SUCCESS(status)) {
            copyHash(other.fTimeUnitToCountToPatterns[i], fTimeUnitToCountToPatterns[i], status);
        } else {
            delete fTimeUnitToCountToPatterns[i];
            fTimeUnitToCountToPatterns[i] = NULL;
        }
    }
}


TimeUnitFormat::~TimeUnitFormat() {
    for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR;
         i < TimeUnit::UTIMEUNIT_FIELD_COUNT;
         i = (TimeUnit::UTimeUnitFields)(i+1)) {
        deleteHash(fTimeUnitToCountToPatterns[i]);
        fTimeUnitToCountToPatterns[i] = NULL;
    }
}


TimeUnitFormat*
TimeUnitFormat::clone() const {
    return new TimeUnitFormat(*this);
}


TimeUnitFormat&
TimeUnitFormat::operator=(const TimeUnitFormat& other) {
    if (this == &other) {
        return *this;
    }
    MeasureFormat::operator=(other);
    for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR;
         i < TimeUnit::UTIMEUNIT_FIELD_COUNT;
         i = (TimeUnit::UTimeUnitFields)(i+1)) {
        deleteHash(fTimeUnitToCountToPatterns[i]);
        fTimeUnitToCountToPatterns[i] = NULL;
    }
    for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR;
         i < TimeUnit::UTIMEUNIT_FIELD_COUNT;
         i = (TimeUnit::UTimeUnitFields)(i+1)) {
        UErrorCode status = U_ZERO_ERROR;
        fTimeUnitToCountToPatterns[i] = initHash(status);
        if (U_SUCCESS(status)) {
            copyHash(other.fTimeUnitToCountToPatterns[i], fTimeUnitToCountToPatterns[i], status);
        } else {
            delete fTimeUnitToCountToPatterns[i];
            fTimeUnitToCountToPatterns[i] = NULL;
        }
    }
    fStyle = other.fStyle;
    return *this;
}

void
TimeUnitFormat::parseObject(const UnicodeString& source,
                            Formattable& result,
                            ParsePosition& pos) const {
    Formattable resultNumber(0.0);
    UBool withNumberFormat = false;
    TimeUnit::UTimeUnitFields resultTimeUnit = TimeUnit::UTIMEUNIT_FIELD_COUNT;
    int32_t oldPos = pos.getIndex();
    int32_t newPos = -1;
    int32_t longestParseDistance = 0;
    UnicodeString* countOfLongestMatch = NULL;
#ifdef TMUTFMT_DEBUG
    char res[1000];
    source.extract(0, source.length(), res, "UTF-8");
    std::cout << "parse source: " << res << "\n";
#endif
    // parse by iterating through all available patterns
    // and looking for the longest match.
    for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR;
         i < TimeUnit::UTIMEUNIT_FIELD_COUNT;
         i = (TimeUnit::UTimeUnitFields)(i+1)) {
        Hashtable* countToPatterns = fTimeUnitToCountToPatterns[i];
        int32_t elemPos = UHASH_FIRST;
        const UHashElement* elem = NULL;
        while ((elem = countToPatterns->nextElement(elemPos)) != NULL){
            const UHashTok keyTok = elem->key;
            UnicodeString* count = (UnicodeString*)keyTok.pointer;
#ifdef TMUTFMT_DEBUG
            count->extract(0, count->length(), res, "UTF-8");
            std::cout << "parse plural count: " << res << "\n";
#endif
            const UHashTok valueTok = elem->value;
            // the value is a pair of MessageFormat*
            MessageFormat** patterns = (MessageFormat**)valueTok.pointer;
            for (UTimeUnitFormatStyle style = UTMUTFMT_FULL_STYLE; style < UTMUTFMT_FORMAT_STYLE_COUNT;
                 style = (UTimeUnitFormatStyle)(style + 1)) {
                MessageFormat* pattern = patterns[style];
                pos.setErrorIndex(-1);
                pos.setIndex(oldPos);
                // see if we can parse
                Formattable parsed;
                pattern->parseObject(source, parsed, pos);
                if (pos.getErrorIndex() != -1 || pos.getIndex() == oldPos) {
                    continue;
                }
    #ifdef TMUTFMT_DEBUG
                std::cout << "parsed.getType: " << parsed.getType() << "\n";
    #endif
                Formattable tmpNumber(0.0);
                if (pattern->getArgTypeCount() != 0) {
                    Formattable& temp = parsed[0];
                    if (temp.getType() == Formattable::kString) {
                        UnicodeString tmpString;
                        UErrorCode pStatus = U_ZERO_ERROR;
                        getNumberFormatInternal().parse(temp.getString(tmpString), tmpNumber, pStatus);
                        if (U_FAILURE(pStatus)) {
                            continue;
                        }
                    } else if (temp.isNumeric()) {
                        tmpNumber = temp;
                    } else {
                        continue;
                    }
                }
                int32_t parseDistance = pos.getIndex() - oldPos;
                if (parseDistance > longestParseDistance) {
                    if (pattern->getArgTypeCount() != 0) {
                        resultNumber = tmpNumber;
                        withNumberFormat = true;
                    } else {
                        withNumberFormat = false;
                    }
                    resultTimeUnit = i;
                    newPos = pos.getIndex();
                    longestParseDistance = parseDistance;
                    countOfLongestMatch = count;
                }
            }
        }
    }
    /* After find the longest match, parse the number.
     * Result number could be null for the pattern without number pattern.
     * such as unit pattern in Arabic.
     * When result number is null, use plural rule to set the number.
     */
    if (withNumberFormat == false && longestParseDistance != 0) {
        // set the number using plurrual count
        if (0 == countOfLongestMatch->compare(PLURAL_COUNT_ZERO, 4)) {
            resultNumber = Formattable(0.0);
        } else if (0 == countOfLongestMatch->compare(PLURAL_COUNT_ONE, 3)) {
            resultNumber = Formattable(1.0);
        } else if (0 == countOfLongestMatch->compare(PLURAL_COUNT_TWO, 3)) {
            resultNumber = Formattable(2.0);
        } else {
            // should not happen.
            // TODO: how to handle?
            resultNumber = Formattable(3.0);
        }
    }
    if (longestParseDistance == 0) {
        pos.setIndex(oldPos);
        pos.setErrorIndex(0);
    } else {
        UErrorCode status = U_ZERO_ERROR;
        LocalPointer<TimeUnitAmount> tmutamt(new TimeUnitAmount(resultNumber, resultTimeUnit, status), status);
        if (U_SUCCESS(status)) {
            result.adoptObject(tmutamt.orphan());
            pos.setIndex(newPos);
            pos.setErrorIndex(-1);
        } else {
            pos.setIndex(oldPos);
            pos.setErrorIndex(0);
        }
    }
}

void
TimeUnitFormat::create(UTimeUnitFormatStyle style, UErrorCode& status) {
    // fTimeUnitToCountToPatterns[] must have its elements initialized to NULL first
    // before checking for failure status.
    for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR;
         i < TimeUnit::UTIMEUNIT_FIELD_COUNT;
         i = (TimeUnit::UTimeUnitFields)(i+1)) {
        fTimeUnitToCountToPatterns[i] = NULL;
    }

    if (U_FAILURE(status)) {
        return;
    }
    if (style < UTMUTFMT_FULL_STYLE || style >= UTMUTFMT_FORMAT_STYLE_COUNT) {
        status = U_ILLEGAL_ARGUMENT_ERROR;
        return;
    }
    fStyle = style;

    //TODO: format() and parseObj() are const member functions,
    //so, can not do lazy initialization in C++.
    //setup has to be done in constructors.
    //and here, the behavior is not consistent with Java.
    //In Java, create an empty instance does not setup locale as
    //default locale. If it followed by setNumberFormat(),
    //in format(), the locale will set up as the locale in fNumberFormat.
    //But in C++, this sets the locale as the default locale.
    setup(status);
}

void
TimeUnitFormat::setup(UErrorCode& err) {
    initDataMembers(err);

    UVector pluralCounts(0, uhash_compareUnicodeString, 6, err);
    LocalPointer<StringEnumeration> keywords(getPluralRules().getKeywords(err), err);
    if (U_FAILURE(err)) {
        return;
    }
    UnicodeString* pluralCount;
    while ((pluralCount = const_cast<UnicodeString*>(keywords->snext(err))) != NULL) {
      pluralCounts.addElement(pluralCount, err);
    }
    readFromCurrentLocale(UTMUTFMT_FULL_STYLE, gUnitsTag, pluralCounts, err);
    checkConsistency(UTMUTFMT_FULL_STYLE, gUnitsTag, err);
    readFromCurrentLocale(UTMUTFMT_ABBREVIATED_STYLE, gShortUnitsTag, pluralCounts, err);
    checkConsistency(UTMUTFMT_ABBREVIATED_STYLE, gShortUnitsTag, err);
}


void
TimeUnitFormat::initDataMembers(UErrorCode& err){
    if (U_FAILURE(err)) {
        return;
    }
    for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR;
         i < TimeUnit::UTIMEUNIT_FIELD_COUNT;
         i = (TimeUnit::UTimeUnitFields)(i+1)) {
        deleteHash(fTimeUnitToCountToPatterns[i]);
        fTimeUnitToCountToPatterns[i] = NULL;
    }
}

struct TimeUnitFormatReadSink : public ResourceSink {
    TimeUnitFormat *timeUnitFormatObj;
    const UVector &pluralCounts;
    UTimeUnitFormatStyle style;
    UBool beenHere;

    TimeUnitFormatReadSink(TimeUnitFormat *timeUnitFormatObj,
            const UVector &pluralCounts, UTimeUnitFormatStyle style) :
            timeUnitFormatObj(timeUnitFormatObj), pluralCounts(pluralCounts),
            style(style), beenHere(FALSE){}

    virtual ~TimeUnitFormatReadSink();

    virtual void put(const char *key, ResourceValue &value, UBool, UErrorCode &errorCode) {
        // Skip all put() calls except the first one -- discard all fallback data.
        if (beenHere) {
            return;
        } else {
            beenHere = TRUE;
        }

        ResourceTable units = value.getTable(errorCode);
        if (U_FAILURE(errorCode)) { return; }

        for (int32_t i = 0; units.getKeyAndValue(i, key, value); ++i) {
            const char* timeUnitName = key;
            if (timeUnitName == NULL) {
                continue;
            }

            TimeUnit::UTimeUnitFields timeUnitField = TimeUnit::UTIMEUNIT_FIELD_COUNT;
            if ( uprv_strcmp(timeUnitName, gTimeUnitYear) == 0 ) {
                timeUnitField = TimeUnit::UTIMEUNIT_YEAR;
            } else if ( uprv_strcmp(timeUnitName, gTimeUnitMonth) == 0 ) {
                timeUnitField = TimeUnit::UTIMEUNIT_MONTH;
            } else if ( uprv_strcmp(timeUnitName, gTimeUnitDay) == 0 ) {
                timeUnitField = TimeUnit::UTIMEUNIT_DAY;
            } else if ( uprv_strcmp(timeUnitName, gTimeUnitHour) == 0 ) {
                timeUnitField = TimeUnit::UTIMEUNIT_HOUR;
            } else if ( uprv_strcmp(timeUnitName, gTimeUnitMinute) == 0 ) {
                timeUnitField = TimeUnit::UTIMEUNIT_MINUTE;
            } else if ( uprv_strcmp(timeUnitName, gTimeUnitSecond) == 0 ) {
                timeUnitField = TimeUnit::UTIMEUNIT_SECOND;
            } else if ( uprv_strcmp(timeUnitName, gTimeUnitWeek) == 0 ) {
                timeUnitField = TimeUnit::UTIMEUNIT_WEEK;
            } else {
                continue;
            }
            LocalPointer<Hashtable> localCountToPatterns;
            Hashtable *countToPatterns =
                timeUnitFormatObj->fTimeUnitToCountToPatterns[timeUnitField];
            if (countToPatterns == NULL) {
                localCountToPatterns.adoptInsteadAndCheckErrorCode(
                    timeUnitFormatObj->initHash(errorCode), errorCode);
                countToPatterns = localCountToPatterns.getAlias();
                if (U_FAILURE(errorCode)) {
                    return;
                }
            }

            ResourceTable countsToPatternTable = value.getTable(errorCode);
            if (U_FAILURE(errorCode)) {
                continue;
            }
            for (int32_t j = 0; countsToPatternTable.getKeyAndValue(j, key, value); ++j) {
                errorCode = U_ZERO_ERROR;
                UnicodeString pattern = value.getUnicodeString(errorCode);
                if (U_FAILURE(errorCode)) {
                    continue;
                }
                UnicodeString pluralCountUniStr(key, -1, US_INV);
                if (!pluralCounts.contains(&pluralCountUniStr)) {
                    continue;
                }
                LocalPointer<MessageFormat> messageFormat(new MessageFormat(
                    pattern, timeUnitFormatObj->getLocale(errorCode), errorCode), errorCode);
                if (U_FAILURE(errorCode)) {
                    return;
                }
                MessageFormat** formatters =
                    (MessageFormat**)countToPatterns->get(pluralCountUniStr);
                if (formatters == NULL) {
                    LocalMemory<MessageFormat *> localFormatters(
                        (MessageFormat **)uprv_malloc(UTMUTFMT_FORMAT_STYLE_COUNT*sizeof(MessageFormat*)));
                    if (localFormatters.isNull()) {
                        errorCode = U_MEMORY_ALLOCATION_ERROR;
                        return;
                    }
                    localFormatters[UTMUTFMT_FULL_STYLE] = NULL;
                    localFormatters[UTMUTFMT_ABBREVIATED_STYLE] = NULL;
                    countToPatterns->put(pluralCountUniStr, localFormatters.getAlias(), errorCode);
                    if (U_FAILURE(errorCode)) {
                        return;
                    }
                    formatters = localFormatters.orphan();
                }
                formatters[style] = messageFormat.orphan();
            }

            if (timeUnitFormatObj->fTimeUnitToCountToPatterns[timeUnitField] == NULL) {
                timeUnitFormatObj->fTimeUnitToCountToPatterns[timeUnitField] = localCountToPatterns.orphan();
            }
        }
    }

};

TimeUnitFormatReadSink::~TimeUnitFormatReadSink() {}

void
TimeUnitFormat::readFromCurrentLocale(UTimeUnitFormatStyle style, const char* key,
                                      const UVector& pluralCounts, UErrorCode& err) {
    if (U_FAILURE(err)) {
        return;
    }
    // fill timeUnitToCountToPatterns from resource file
    // err is used to indicate wrong status except missing resource.
    // status is an error code used in resource lookup.
    // status does not affect "err".
    UErrorCode status = U_ZERO_ERROR;
    LocalUResourceBundlePointer rb(ures_open(U_ICUDATA_UNIT, getLocaleID(status), &status));

    LocalUResourceBundlePointer unitsRes(ures_getByKey(rb.getAlias(), key, NULL, &status));
    ures_getByKey(unitsRes.getAlias(), "duration", unitsRes.getAlias(), &status);
    if (U_FAILURE(status)) {
        return;
    }

    TimeUnitFormatReadSink sink(this, pluralCounts, style);
    ures_getAllItemsWithFallback(unitsRes.getAlias(), "", sink, status);
}

void
TimeUnitFormat::checkConsistency(UTimeUnitFormatStyle style, const char* key, UErrorCode& err) {
    if (U_FAILURE(err)) {
        return;
    }
    // there should be patterns for each plural rule in each time unit.
    // For each time unit,
    //     for each plural rule, following is unit pattern fall-back rule:
    //         ( for example: "one" hour )
    //         look for its unit pattern in its locale tree.
    //         if pattern is not found in its own locale, such as de_DE,
    //         look for the pattern in its parent, such as de,
    //         keep looking till found or till root.
    //         if the pattern is not found in root either,
    //         fallback to plural count "other",
    //         look for the pattern of "other" in the locale tree:
    //         "de_DE" to "de" to "root".
    //         If not found, fall back to value of
    //         static variable DEFAULT_PATTERN_FOR_xxx, such as "{0} h".
    //
    // Following is consistency check to create pattern for each
    // plural rule in each time unit using above fall-back rule.
    //
    LocalPointer<StringEnumeration> keywords(
            getPluralRules().getKeywords(err), err);
    const UnicodeString* pluralCount;
    while (U_SUCCESS(err) && (pluralCount = keywords->snext(err)) != NULL) {
        for (int32_t i = 0; i < TimeUnit::UTIMEUNIT_FIELD_COUNT; ++i) {
            // for each time unit,
            // get all the patterns for each plural rule in this locale.
            Hashtable* countToPatterns = fTimeUnitToCountToPatterns[i];
            if ( countToPatterns == NULL ) {
                fTimeUnitToCountToPatterns[i] = countToPatterns = initHash(err);
                if (U_FAILURE(err)) {
                    return;
                }
            }
            MessageFormat** formatters = (MessageFormat**)countToPatterns->get(*pluralCount);
            if( formatters == NULL || formatters[style] == NULL ) {
                // look through parents
                const char* localeName = getLocaleID(err);
                CharString pluralCountChars;
                pluralCountChars.appendInvariantChars(*pluralCount, err);
                searchInLocaleChain(style, key, localeName,
                                    (TimeUnit::UTimeUnitFields)i,
                                    *pluralCount, pluralCountChars.data(),
                                    countToPatterns, err);
            }
            // TODO: what to do with U_FAILURE(err) at this point.
            //       As is, the outer loop continues to run, but does nothing.
        }
    }
}



// srcPluralCount is the original plural count on which the pattern is
// searched for.
// searchPluralCount is the fallback plural count.
// For example, to search for pattern for ""one" hour",
// "one" is the srcPluralCount,
// if the pattern is not found even in root, fallback to
// using patterns of plural count "other",
// then, "other" is the searchPluralCount.
void
TimeUnitFormat::searchInLocaleChain(UTimeUnitFormatStyle style, const char* key, const char* localeName,
                                TimeUnit::UTimeUnitFields srcTimeUnitField,
                                const UnicodeString& srcPluralCount,
                                const char* searchPluralCount,
                                Hashtable* countToPatterns,
                                UErrorCode& err) {
    if (U_FAILURE(err)) {
        return;
    }
    UErrorCode status = U_ZERO_ERROR;
    char parentLocale[ULOC_FULLNAME_CAPACITY];
    uprv_strcpy(parentLocale, localeName);
    int32_t locNameLen;
    U_ASSERT(countToPatterns != NULL);
    while ((locNameLen = uloc_getParent(parentLocale, parentLocale,
                                        ULOC_FULLNAME_CAPACITY, &status)) >= 0){
        // look for pattern for srcPluralCount in locale tree
        LocalUResourceBundlePointer rb(ures_open(U_ICUDATA_UNIT, parentLocale, &status));
        LocalUResourceBundlePointer unitsRes(ures_getByKey(rb.getAlias(), key, NULL, &status));
        const char* timeUnitName = getTimeUnitName(srcTimeUnitField, status);
        LocalUResourceBundlePointer countsToPatternRB(ures_getByKey(unitsRes.getAlias(), timeUnitName, NULL, &status));
        const UChar* pattern;
        int32_t      ptLength;
        pattern = ures_getStringByKeyWithFallback(countsToPatternRB.getAlias(), searchPluralCount, &ptLength, &status);
        if (U_SUCCESS(status)) {
            //found
            LocalPointer<MessageFormat> messageFormat(
                new MessageFormat(UnicodeString(TRUE, pattern, ptLength), getLocale(err), err), err);
            if (U_FAILURE(err)) {
                return;
            }
            MessageFormat** formatters = (MessageFormat**)countToPatterns->get(srcPluralCount);
            if (formatters == NULL) {
                LocalMemory<MessageFormat *> localFormatters(
                        (MessageFormat**)uprv_malloc(UTMUTFMT_FORMAT_STYLE_COUNT*sizeof(MessageFormat*)));
                formatters = localFormatters.getAlias();
                localFormatters[UTMUTFMT_FULL_STYLE] = NULL;
                localFormatters[UTMUTFMT_ABBREVIATED_STYLE] = NULL;
                countToPatterns->put(srcPluralCount, localFormatters.orphan(), err);
                if (U_FAILURE(err)) {
                    return;
                }
            }
            //delete formatters[style];
            formatters[style] = messageFormat.orphan();
            return;
        }
        status = U_ZERO_ERROR;
        if (locNameLen == 0) {
            break;
        }
    }

    // if no unitsShort resource was found even after fallback to root locale
    // then search the units resource fallback from the current level to root
    if ( locNameLen == 0 && uprv_strcmp(key, gShortUnitsTag) == 0) {
#ifdef TMUTFMT_DEBUG
        std::cout << "loop into searchInLocaleChain since Short-Long-Alternative \n";
#endif
        CharString pLocale(localeName, -1, err);
        // Add an underscore at the tail of locale name,
        // so that searchInLocaleChain will check the current locale before falling back
        pLocale.append('_', err);
        searchInLocaleChain(style, gUnitsTag, pLocale.data(), srcTimeUnitField, srcPluralCount,
                             searchPluralCount, countToPatterns, err);
        if (U_FAILURE(err)) {
            return;
        }
        MessageFormat** formatters = (MessageFormat**)countToPatterns->get(srcPluralCount);
        if (formatters != NULL && formatters[style] != NULL) {
            return;
        }
    }

    // if not found the pattern for this plural count at all,
    // fall-back to plural count "other"
    if ( uprv_strcmp(searchPluralCount, gPluralCountOther) == 0 ) {
        // set default fall back the same as the resource in root
        LocalPointer<MessageFormat> messageFormat;
        const UChar *pattern = NULL;
        if ( srcTimeUnitField == TimeUnit::UTIMEUNIT_SECOND ) {
            pattern = DEFAULT_PATTERN_FOR_SECOND;
        } else if ( srcTimeUnitField == TimeUnit::UTIMEUNIT_MINUTE ) {
            pattern = DEFAULT_PATTERN_FOR_MINUTE;
        } else if ( srcTimeUnitField == TimeUnit::UTIMEUNIT_HOUR ) {
            pattern = DEFAULT_PATTERN_FOR_HOUR;
        } else if ( srcTimeUnitField == TimeUnit::UTIMEUNIT_WEEK ) {
            pattern = DEFAULT_PATTERN_FOR_WEEK;
        } else if ( srcTimeUnitField == TimeUnit::UTIMEUNIT_DAY ) {
            pattern = DEFAULT_PATTERN_FOR_DAY;
        } else if ( srcTimeUnitField == TimeUnit::UTIMEUNIT_MONTH ) {
            pattern = DEFAULT_PATTERN_FOR_MONTH;
        } else if ( srcTimeUnitField == TimeUnit::UTIMEUNIT_YEAR ) {
            pattern = DEFAULT_PATTERN_FOR_YEAR;
        }
        if (pattern != NULL) {
            messageFormat.adoptInsteadAndCheckErrorCode(
                     new MessageFormat(UnicodeString(TRUE, pattern, -1), getLocale(err), err), err);
        }
        if (U_FAILURE(err)) {
            return;
        }
        MessageFormat** formatters = (MessageFormat**)countToPatterns->get(srcPluralCount);
        if (formatters == NULL) {
            LocalMemory<MessageFormat *> localFormatters (
                    (MessageFormat**)uprv_malloc(UTMUTFMT_FORMAT_STYLE_COUNT*sizeof(MessageFormat*)));
            if (localFormatters.isNull()) {
                err = U_MEMORY_ALLOCATION_ERROR;
                return;
            }
            formatters = localFormatters.getAlias();
            formatters[UTMUTFMT_FULL_STYLE] = NULL;
            formatters[UTMUTFMT_ABBREVIATED_STYLE] = NULL;
            countToPatterns->put(srcPluralCount, localFormatters.orphan(), err);
        }
        if (U_SUCCESS(err)) {
            //delete formatters[style];
            formatters[style] = messageFormat.orphan();
        }
    } else {
        // fall back to rule "other", and search in parents
        searchInLocaleChain(style, key, localeName, srcTimeUnitField, srcPluralCount,
                            gPluralCountOther, countToPatterns, err);
    }
}

void
TimeUnitFormat::setLocale(const Locale& locale, UErrorCode& status) {
    if (setMeasureFormatLocale(locale, status)) {
        setup(status);
    }
}


void
TimeUnitFormat::setNumberFormat(const NumberFormat& format, UErrorCode& status){
    if (U_FAILURE(status)) {
        return;
    }
    adoptNumberFormat(format.clone(), status);
}


void
TimeUnitFormat::deleteHash(Hashtable* htable) {
    int32_t pos = UHASH_FIRST;
    const UHashElement* element = NULL;
    if ( htable ) {
        while ( (element = htable->nextElement(pos)) != NULL ) {
            const UHashTok valueTok = element->value;
            const MessageFormat** value = (const MessageFormat**)valueTok.pointer;
            delete value[UTMUTFMT_FULL_STYLE];
            delete value[UTMUTFMT_ABBREVIATED_STYLE];
            //delete[] value;
            uprv_free(value);
        }
    }
    delete htable;
}


void
TimeUnitFormat::copyHash(const Hashtable* source, Hashtable* target, UErrorCode& status) {
    if ( U_FAILURE(status) ) {
        return;
    }
    int32_t pos = UHASH_FIRST;
    const UHashElement* element = NULL;
    if ( source ) {
        while ( (element = source->nextElement(pos)) != NULL ) {
            const UHashTok keyTok = element->key;
            const UnicodeString* key = (UnicodeString*)keyTok.pointer;
            const UHashTok valueTok = element->value;
            const MessageFormat** value = (const MessageFormat**)valueTok.pointer;
            MessageFormat** newVal = (MessageFormat**)uprv_malloc(UTMUTFMT_FORMAT_STYLE_COUNT*sizeof(MessageFormat*));
            newVal[0] = value[0]->clone();
            newVal[1] = value[1]->clone();
            target->put(UnicodeString(*key), newVal, status);
            if ( U_FAILURE(status) ) {
                delete newVal[0];
                delete newVal[1];
                uprv_free(newVal);
                return;
            }
        }
    }
}


U_CDECL_BEGIN

/**
 * set hash table value comparator
 *
 * @param val1  one value in comparison
 * @param val2  the other value in comparison
 * @return      TRUE if 2 values are the same, FALSE otherwise
 */
static UBool U_CALLCONV tmutfmtHashTableValueComparator(UHashTok val1, UHashTok val2);

static UBool
U_CALLCONV tmutfmtHashTableValueComparator(UHashTok val1, UHashTok val2) {
    const MessageFormat** pattern1 = (const MessageFormat**)val1.pointer;
    const MessageFormat** pattern2 = (const MessageFormat**)val2.pointer;
    return *pattern1[0] == *pattern2[0] && *pattern1[1] == *pattern2[1];
}

U_CDECL_END

Hashtable*
TimeUnitFormat::initHash(UErrorCode& status) {
    if ( U_FAILURE(status) ) {
        return NULL;
    }
    Hashtable* hTable;
    if ( (hTable = new Hashtable(TRUE, status)) == NULL ) {
        status = U_MEMORY_ALLOCATION_ERROR;
        return NULL;
    }
    if ( U_FAILURE(status) ) {
        delete hTable;
        return NULL;
    }
    hTable->setValueComparator(tmutfmtHashTableValueComparator);
    return hTable;
}


const char*
TimeUnitFormat::getTimeUnitName(TimeUnit::UTimeUnitFields unitField,
                                UErrorCode& status) {
    if (U_FAILURE(status)) {
        return NULL;
    }
    switch (unitField) {
      case TimeUnit::UTIMEUNIT_YEAR:
        return gTimeUnitYear;
      case TimeUnit::UTIMEUNIT_MONTH:
        return gTimeUnitMonth;
      case TimeUnit::UTIMEUNIT_DAY:
        return gTimeUnitDay;
      case TimeUnit::UTIMEUNIT_WEEK:
        return gTimeUnitWeek;
      case TimeUnit::UTIMEUNIT_HOUR:
        return gTimeUnitHour;
      case TimeUnit::UTIMEUNIT_MINUTE:
        return gTimeUnitMinute;
      case TimeUnit::UTIMEUNIT_SECOND:
        return gTimeUnitSecond;
      default:
        status = U_ILLEGAL_ARGUMENT_ERROR;
        return NULL;
    }
}

U_NAMESPACE_END

#endif
