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

#include "unicode/reldatefmt.h"

#if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_BREAK_ITERATION

#include <cmath>
#include <functional>
#include "unicode/dtfmtsym.h"
#include "unicode/ucasemap.h"
#include "unicode/ureldatefmt.h"
#include "unicode/udisplaycontext.h"
#include "unicode/unum.h"
#include "unicode/localpointer.h"
#include "unicode/plurrule.h"
#include "unicode/simpleformatter.h"
#include "unicode/decimfmt.h"
#include "unicode/numfmt.h"
#include "unicode/brkiter.h"
#include "unicode/simpleformatter.h"
#include "uresimp.h"
#include "unicode/ures.h"
#include "cstring.h"
#include "ucln_in.h"
#include "mutex.h"
#include "charstr.h"
#include "uassert.h"
#include "quantityformatter.h"
#include "resource.h"
#include "sharedbreakiterator.h"
#include "sharedpluralrules.h"
#include "sharednumberformat.h"
#include "standardplural.h"
#include "unifiedcache.h"
#include "util.h"
#include "number_stringbuilder.h"
#include "number_utypes.h"
#include "number_modifiers.h"
#include "formattedval_impl.h"
#include "number_utils.h"

// Copied from uscript_props.cpp

U_NAMESPACE_BEGIN

// RelativeDateTimeFormatter specific data for a single locale
class RelativeDateTimeCacheData: public SharedObject {
public:
    RelativeDateTimeCacheData() : combinedDateAndTime(nullptr) {
        // Initialize the cache arrays
        for (int32_t style = 0; style < UDAT_STYLE_COUNT; ++style) {
            for (int32_t relUnit = 0; relUnit < UDAT_REL_UNIT_COUNT; ++relUnit) {
                for (int32_t pl = 0; pl < StandardPlural::COUNT; ++pl) {
                    relativeUnitsFormatters[style][relUnit][0][pl] = nullptr;
                    relativeUnitsFormatters[style][relUnit][1][pl] = nullptr;
                }
            }
        }
        for (int32_t i = 0; i < UDAT_STYLE_COUNT; ++i) {
          fallBackCache[i] = -1;
        }
    }
    virtual ~RelativeDateTimeCacheData();

    // no numbers: e.g Next Tuesday; Yesterday; etc.
    UnicodeString absoluteUnits[UDAT_STYLE_COUNT][UDAT_ABSOLUTE_UNIT_COUNT][UDAT_DIRECTION_COUNT];

    // SimpleFormatter pointers for relative unit format,
    // e.g., Next Tuesday; Yesterday; etc. For third index, 0
    // means past, e.g., 5 days ago; 1 means future, e.g., in 5 days.
    SimpleFormatter *relativeUnitsFormatters[UDAT_STYLE_COUNT]
        [UDAT_REL_UNIT_COUNT][2][StandardPlural::COUNT];

    const UnicodeString& getAbsoluteUnitString(int32_t fStyle,
                                               UDateAbsoluteUnit unit,
                                               UDateDirection direction) const;
    const SimpleFormatter* getRelativeUnitFormatter(int32_t fStyle,
                                                    UDateRelativeUnit unit,
                                                    int32_t pastFutureIndex,
                                                    int32_t pluralUnit) const;
    const SimpleFormatter* getRelativeDateTimeUnitFormatter(int32_t fStyle,
                                                    URelativeDateTimeUnit unit,
                                                    int32_t pastFutureIndex,
                                                    int32_t pluralUnit) const;

    const UnicodeString emptyString;

    // Mappping from source to target styles for alias fallback.
    int32_t fallBackCache[UDAT_STYLE_COUNT];

    void adoptCombinedDateAndTime(SimpleFormatter *fmtToAdopt) {
        delete combinedDateAndTime;
        combinedDateAndTime = fmtToAdopt;
    }
    const SimpleFormatter *getCombinedDateAndTime() const {
        return combinedDateAndTime;
    }

private:
    SimpleFormatter *combinedDateAndTime;
    RelativeDateTimeCacheData(const RelativeDateTimeCacheData &other);
    RelativeDateTimeCacheData& operator=(
            const RelativeDateTimeCacheData &other);
};

RelativeDateTimeCacheData::~RelativeDateTimeCacheData() {
    // clear out the cache arrays
    for (int32_t style = 0; style < UDAT_STYLE_COUNT; ++style) {
        for (int32_t relUnit = 0; relUnit < UDAT_REL_UNIT_COUNT; ++relUnit) {
            for (int32_t pl = 0; pl < StandardPlural::COUNT; ++pl) {
                delete relativeUnitsFormatters[style][relUnit][0][pl];
                delete relativeUnitsFormatters[style][relUnit][1][pl];
            }
        }
    }
    delete combinedDateAndTime;
}


// Use fallback cache for absolute units.
const UnicodeString& RelativeDateTimeCacheData::getAbsoluteUnitString(
        int32_t fStyle, UDateAbsoluteUnit unit, UDateDirection direction) const {
    int32_t style = fStyle;
    do {
        if (!absoluteUnits[style][unit][direction].isEmpty()) {
            return absoluteUnits[style][unit][direction];
        }
        style = fallBackCache[style];
    } while (style != -1);
    return emptyString;
}

 const SimpleFormatter* RelativeDateTimeCacheData::getRelativeUnitFormatter(
        int32_t fStyle,
        UDateRelativeUnit unit,
        int32_t pastFutureIndex,
        int32_t pluralUnit) const {
   URelativeDateTimeUnit rdtunit = UDAT_REL_UNIT_COUNT;
   switch (unit) {
       case UDAT_RELATIVE_YEARS:   rdtunit = UDAT_REL_UNIT_YEAR; break;
       case UDAT_RELATIVE_MONTHS:  rdtunit = UDAT_REL_UNIT_MONTH; break;
       case UDAT_RELATIVE_WEEKS:   rdtunit = UDAT_REL_UNIT_WEEK; break;
       case UDAT_RELATIVE_DAYS:    rdtunit = UDAT_REL_UNIT_DAY; break;
       case UDAT_RELATIVE_HOURS:   rdtunit = UDAT_REL_UNIT_HOUR; break;
       case UDAT_RELATIVE_MINUTES: rdtunit = UDAT_REL_UNIT_MINUTE; break;
       case UDAT_RELATIVE_SECONDS: rdtunit = UDAT_REL_UNIT_SECOND; break;
       default: // a unit that the above method does not handle
            return nullptr;
   }

   return getRelativeDateTimeUnitFormatter(fStyle, rdtunit, pastFutureIndex, pluralUnit);
 }

 // Use fallback cache for SimpleFormatter relativeUnits.
 const SimpleFormatter* RelativeDateTimeCacheData::getRelativeDateTimeUnitFormatter(
        int32_t fStyle,
        URelativeDateTimeUnit unit,
        int32_t pastFutureIndex,
        int32_t pluralUnit) const {
    while (true) {
        int32_t style = fStyle;
        do {
            if (relativeUnitsFormatters[style][unit][pastFutureIndex][pluralUnit] != nullptr) {
                return relativeUnitsFormatters[style][unit][pastFutureIndex][pluralUnit];
            }
            style = fallBackCache[style];
        } while (style != -1);

        if (pluralUnit == StandardPlural::OTHER) {
            break;
        }
        pluralUnit = StandardPlural::OTHER;
    }
    return nullptr;  // No formatter found.
 }

static UBool getStringWithFallback(
        const UResourceBundle *resource,
        const char *key,
        UnicodeString &result,
        UErrorCode &status) {
    int32_t len = 0;
    const UChar *resStr = ures_getStringByKeyWithFallback(
        resource, key, &len, &status);
    if (U_FAILURE(status)) {
        return FALSE;
    }
    result.setTo(TRUE, resStr, len);
    return TRUE;
}


static UBool getStringByIndex(
        const UResourceBundle *resource,
        int32_t idx,
        UnicodeString &result,
        UErrorCode &status) {
    int32_t len = 0;
    const UChar *resStr = ures_getStringByIndex(
            resource, idx, &len, &status);
    if (U_FAILURE(status)) {
        return FALSE;
    }
    result.setTo(TRUE, resStr, len);
    return TRUE;
}

namespace {

/**
 * Sink for enumerating all of the measurement unit display names.
 *
 * More specific bundles (en_GB) are enumerated before their parents (en_001, en, root):
 * Only store a value if it is still missing, that is, it has not been overridden.
 */
struct RelDateTimeFmtDataSink : public ResourceSink {

    /**
     * Sink for patterns for relative dates and times. For example,
     * fields/relative/...
     */

    // Generic unit enum for storing Unit info.
    typedef enum RelAbsUnit {
        INVALID_UNIT = -1,
        SECOND,
        MINUTE,
        HOUR,
        DAY,
        WEEK,
        MONTH,
        QUARTER,
        YEAR,
        SUNDAY,
        MONDAY,
        TUESDAY,
        WEDNESDAY,
        THURSDAY,
        FRIDAY,
        SATURDAY
    } RelAbsUnit;

    static int32_t relUnitFromGeneric(RelAbsUnit genUnit) {
        // Converts the generic units to UDAT_RELATIVE version.
        switch (genUnit) {
            case SECOND:
                return UDAT_REL_UNIT_SECOND;
            case MINUTE:
                return UDAT_REL_UNIT_MINUTE;
            case HOUR:
                return UDAT_REL_UNIT_HOUR;
            case DAY:
                return UDAT_REL_UNIT_DAY;
            case WEEK:
                return UDAT_REL_UNIT_WEEK;
            case MONTH:
                return UDAT_REL_UNIT_MONTH;
            case QUARTER:
                return UDAT_REL_UNIT_QUARTER;
            case YEAR:
                return UDAT_REL_UNIT_YEAR;
            case SUNDAY:
                return UDAT_REL_UNIT_SUNDAY;
            case MONDAY:
                return UDAT_REL_UNIT_MONDAY;
            case TUESDAY:
                return UDAT_REL_UNIT_TUESDAY;
            case WEDNESDAY:
                return UDAT_REL_UNIT_WEDNESDAY;
            case THURSDAY:
                return UDAT_REL_UNIT_THURSDAY;
            case FRIDAY:
                return UDAT_REL_UNIT_FRIDAY;
            case SATURDAY:
                return UDAT_REL_UNIT_SATURDAY;
            default:
                return -1;
        }
    }

    static int32_t absUnitFromGeneric(RelAbsUnit genUnit) {
        // Converts the generic units to UDAT_RELATIVE version.
        switch (genUnit) {
            case DAY:
                return UDAT_ABSOLUTE_DAY;
            case WEEK:
                return UDAT_ABSOLUTE_WEEK;
            case MONTH:
                return UDAT_ABSOLUTE_MONTH;
            case QUARTER:
                return UDAT_ABSOLUTE_QUARTER;
            case YEAR:
                return UDAT_ABSOLUTE_YEAR;
            case SUNDAY:
                return UDAT_ABSOLUTE_SUNDAY;
            case MONDAY:
                return UDAT_ABSOLUTE_MONDAY;
            case TUESDAY:
                return UDAT_ABSOLUTE_TUESDAY;
            case WEDNESDAY:
                return UDAT_ABSOLUTE_WEDNESDAY;
            case THURSDAY:
                return UDAT_ABSOLUTE_THURSDAY;
            case FRIDAY:
                return UDAT_ABSOLUTE_FRIDAY;
            case SATURDAY:
                return UDAT_ABSOLUTE_SATURDAY;
            default:
                return -1;
        }
    }

    static int32_t keyToDirection(const char* key) {
        if (uprv_strcmp(key, "-2") == 0) {
            return UDAT_DIRECTION_LAST_2;
        }
        if (uprv_strcmp(key, "-1") == 0) {
            return UDAT_DIRECTION_LAST;
        }
        if (uprv_strcmp(key, "0") == 0) {
            return UDAT_DIRECTION_THIS;
        }
        if (uprv_strcmp(key, "1") == 0) {
            return UDAT_DIRECTION_NEXT;
        }
        if (uprv_strcmp(key, "2") == 0) {
            return UDAT_DIRECTION_NEXT_2;
        }
        return -1;
    }

    // Values kept between levels of parsing the CLDR data.
    int32_t pastFutureIndex;  // 0 == past or 1 ==  future
    UDateRelativeDateTimeFormatterStyle style;  // {LONG, SHORT, NARROW}
    RelAbsUnit genericUnit;

    RelativeDateTimeCacheData &outputData;

    // Constructor
    RelDateTimeFmtDataSink(RelativeDateTimeCacheData& cacheData)
        : outputData(cacheData) {
        // Clear cacheData.fallBackCache
        cacheData.fallBackCache[UDAT_STYLE_LONG] = -1;
        cacheData.fallBackCache[UDAT_STYLE_SHORT] = -1;
        cacheData.fallBackCache[UDAT_STYLE_NARROW] = -1;
    }

    ~RelDateTimeFmtDataSink();

    // Utility functions
    static UDateRelativeDateTimeFormatterStyle styleFromString(const char *s) {
        int32_t len = static_cast<int32_t>(uprv_strlen(s));
        if (len >= 7 && uprv_strcmp(s + len - 7, "-narrow") == 0) {
            return UDAT_STYLE_NARROW;
        }
        if (len >= 6 && uprv_strcmp(s + len - 6, "-short") == 0) {
            return UDAT_STYLE_SHORT;
        }
        return UDAT_STYLE_LONG;
    }

    static int32_t styleSuffixLength(UDateRelativeDateTimeFormatterStyle style) {
        switch (style) {
            case UDAT_STYLE_NARROW:
                return 7;
            case UDAT_STYLE_SHORT:
                return 6;
            default:
                return 0;
        }
    }

    // Utility functions
    static UDateRelativeDateTimeFormatterStyle styleFromAliasUnicodeString(UnicodeString s) {
        static const UChar narrow[7] = {0x002D, 0x006E, 0x0061, 0x0072, 0x0072, 0x006F, 0x0077};
        static const UChar sshort[6] = {0x002D, 0x0073, 0x0068, 0x006F, 0x0072, 0x0074,};
        if (s.endsWith(narrow, 7)) {
            return UDAT_STYLE_NARROW;
        }
        if (s.endsWith(sshort, 6)) {
            return UDAT_STYLE_SHORT;
        }
        return UDAT_STYLE_LONG;
    }

    static RelAbsUnit unitOrNegativeFromString(const char* keyword, int32_t length) {
        // Quick check from string to enum.
        switch (length) {
            case 3:
                if (uprv_strncmp(keyword, "day", length) == 0) {
                    return DAY;
                } else if (uprv_strncmp(keyword, "sun", length) == 0) {
                    return SUNDAY;
                } else if (uprv_strncmp(keyword, "mon", length) == 0) {
                    return MONDAY;
                } else if (uprv_strncmp(keyword, "tue", length) == 0) {
                    return TUESDAY;
                } else if (uprv_strncmp(keyword, "wed", length) == 0) {
                    return WEDNESDAY;
                } else if (uprv_strncmp(keyword, "thu", length) == 0) {
                    return THURSDAY;
                } else if (uprv_strncmp(keyword, "fri", length) == 0) {
                    return FRIDAY;
                } else if (uprv_strncmp(keyword, "sat", length) == 0) {
                    return SATURDAY;
                }
                break;
            case 4:
                if (uprv_strncmp(keyword, "hour", length) == 0) {
                    return HOUR;
                } else if (uprv_strncmp(keyword, "week", length) == 0) {
                    return WEEK;
                } else if (uprv_strncmp(keyword, "year", length) == 0) {
                    return YEAR;
                }
                break;
            case 5:
                if (uprv_strncmp(keyword, "month", length) == 0) {
                    return MONTH;
                }
                break;
            case 6:
                if (uprv_strncmp(keyword, "minute", length) == 0) {
                    return MINUTE;
                } else if (uprv_strncmp(keyword, "second", length) == 0) {
                    return SECOND;
                }
                break;
            case 7:
                if (uprv_strncmp(keyword, "quarter", length) == 0) {
                    return QUARTER;  // TODO: Check @provisional
                  }
                break;
            default:
                break;
        }
        return INVALID_UNIT;
    }

    void handlePlainDirection(ResourceValue &value, UErrorCode &errorCode) {
        // Handle Display Name for PLAIN direction for some units.
        if (U_FAILURE(errorCode)) { return; }

        int32_t absUnit = absUnitFromGeneric(genericUnit);
        if (absUnit < 0) {
          return;  // Not interesting.
        }

        // Store displayname if not set.
        if (outputData.absoluteUnits[style]
            [absUnit][UDAT_DIRECTION_PLAIN].isEmpty()) {
            outputData.absoluteUnits[style]
                [absUnit][UDAT_DIRECTION_PLAIN].fastCopyFrom(value.getUnicodeString(errorCode));
            return;
        }
    }

    void consumeTableRelative(const char *key, ResourceValue &value, UErrorCode &errorCode) {
        ResourceTable unitTypesTable = value.getTable(errorCode);
        if (U_FAILURE(errorCode)) { return; }

        for (int32_t i = 0; unitTypesTable.getKeyAndValue(i, key, value); ++i) {
            if (value.getType() == URES_STRING) {
                int32_t direction = keyToDirection(key);
                if (direction < 0) {
                  continue;
                }

                int32_t relUnitIndex = relUnitFromGeneric(genericUnit);
                if (relUnitIndex == UDAT_REL_UNIT_SECOND && uprv_strcmp(key, "0") == 0 &&
                    outputData.absoluteUnits[style][UDAT_ABSOLUTE_NOW][UDAT_DIRECTION_PLAIN].isEmpty()) {
                    // Handle "NOW"
                    outputData.absoluteUnits[style][UDAT_ABSOLUTE_NOW]
                        [UDAT_DIRECTION_PLAIN].fastCopyFrom(value.getUnicodeString(errorCode));
                }

                int32_t absUnitIndex = absUnitFromGeneric(genericUnit);
                if (absUnitIndex < 0) {
                    continue;
                }
                // Only reset if slot is empty.
                if (outputData.absoluteUnits[style][absUnitIndex][direction].isEmpty()) {
                    outputData.absoluteUnits[style][absUnitIndex]
                        [direction].fastCopyFrom(value.getUnicodeString(errorCode));
                }
            }
        }
    }

    void consumeTimeDetail(int32_t relUnitIndex,
                           const char *key, ResourceValue &value, UErrorCode &errorCode) {
        ResourceTable unitTypesTable = value.getTable(errorCode);
        if (U_FAILURE(errorCode)) { return; }

          for (int32_t i = 0; unitTypesTable.getKeyAndValue(i, key, value); ++i) {
            if (value.getType() == URES_STRING) {
                int32_t pluralIndex = StandardPlural::indexOrNegativeFromString(key);
                if (pluralIndex >= 0) {
                    SimpleFormatter **patterns =
                        outputData.relativeUnitsFormatters[style][relUnitIndex]
                        [pastFutureIndex];
                    // Only set if not already established.
                    if (patterns[pluralIndex] == nullptr) {
                        patterns[pluralIndex] = new SimpleFormatter(
                            value.getUnicodeString(errorCode), 0, 1, errorCode);
                        if (patterns[pluralIndex] == nullptr) {
                            errorCode = U_MEMORY_ALLOCATION_ERROR;
                        }
                    }
                }
            }
        }
    }

    void consumeTableRelativeTime(const char *key, ResourceValue &value, UErrorCode &errorCode) {
        ResourceTable relativeTimeTable = value.getTable(errorCode);
        if (U_FAILURE(errorCode)) { return; }

        int32_t relUnitIndex = relUnitFromGeneric(genericUnit);
        if (relUnitIndex < 0) {
            return;
        }
        for (int32_t i = 0; relativeTimeTable.getKeyAndValue(i, key, value); ++i) {
            if (uprv_strcmp(key, "past") == 0) {
                pastFutureIndex = 0;
            } else if (uprv_strcmp(key, "future") == 0) {
                pastFutureIndex = 1;
            } else {
                // Unknown key.
                continue;
            }
            consumeTimeDetail(relUnitIndex, key, value, errorCode);
        }
    }

    void consumeAlias(const char *key, const ResourceValue &value, UErrorCode &errorCode) {

        UDateRelativeDateTimeFormatterStyle sourceStyle = styleFromString(key);
        const UnicodeString valueStr = value.getAliasUnicodeString(errorCode);
        if (U_FAILURE(errorCode)) { return; }

        UDateRelativeDateTimeFormatterStyle targetStyle =
            styleFromAliasUnicodeString(valueStr);

        if (sourceStyle == targetStyle) {
            errorCode = U_INVALID_FORMAT_ERROR;
            return;
        }
        if (outputData.fallBackCache[sourceStyle] != -1 &&
            outputData.fallBackCache[sourceStyle] != targetStyle) {
            errorCode = U_INVALID_FORMAT_ERROR;
            return;
        }
        outputData.fallBackCache[sourceStyle] = targetStyle;
    }

    void consumeTimeUnit(const char *key, ResourceValue &value, UErrorCode &errorCode) {
        ResourceTable unitTypesTable = value.getTable(errorCode);
        if (U_FAILURE(errorCode)) { return; }

        for (int32_t i = 0; unitTypesTable.getKeyAndValue(i, key, value); ++i) {
            // Handle display name.
            if (uprv_strcmp(key, "dn") == 0 && value.getType() == URES_STRING) {
                handlePlainDirection(value, errorCode);
            }
            if (value.getType() == URES_TABLE) {
                if (uprv_strcmp(key, "relative") == 0) {
                    consumeTableRelative(key, value, errorCode);
                } else if (uprv_strcmp(key, "relativeTime") == 0) {
                    consumeTableRelativeTime(key, value, errorCode);
                }
            }
        }
    }

    virtual void put(const char *key, ResourceValue &value,
                     UBool /*noFallback*/, UErrorCode &errorCode) {
        // Main entry point to sink
        ResourceTable table = value.getTable(errorCode);
        if (U_FAILURE(errorCode)) { return; }
        for (int32_t i = 0; table.getKeyAndValue(i, key, value); ++i) {
            if (value.getType() == URES_ALIAS) {
                consumeAlias(key, value, errorCode);
            } else {
                style = styleFromString(key);
                int32_t unitSize = static_cast<int32_t>(uprv_strlen(key)) - styleSuffixLength(style);
                genericUnit = unitOrNegativeFromString(key, unitSize);
                if (style >= 0 && genericUnit != INVALID_UNIT) {
                    consumeTimeUnit(key, value, errorCode);
                }
            }
        }
    }

};

// Virtual destructors must be defined out of line.
RelDateTimeFmtDataSink::~RelDateTimeFmtDataSink() {}
} // namespace

static const DateFormatSymbols::DtWidthType styleToDateFormatSymbolWidth[UDAT_STYLE_COUNT] = {
  DateFormatSymbols::WIDE, DateFormatSymbols::SHORT, DateFormatSymbols::NARROW
};

// Get days of weeks from the DateFormatSymbols class.
static void loadWeekdayNames(UnicodeString absoluteUnits[UDAT_STYLE_COUNT]
                                 [UDAT_ABSOLUTE_UNIT_COUNT][UDAT_DIRECTION_COUNT],
                             const char* localeId,
                             UErrorCode& status) {
    if (U_FAILURE(status)) {
        return;
    }
    Locale locale(localeId);
    DateFormatSymbols dfSym(locale, status);
    if (U_FAILURE(status)) {
        return;
    }
    for (int32_t style = 0; style < UDAT_STYLE_COUNT; ++style) {
        DateFormatSymbols::DtWidthType dtfmtWidth = styleToDateFormatSymbolWidth[style];
        int32_t count;
        const UnicodeString* weekdayNames =
            dfSym.getWeekdays(count, DateFormatSymbols::STANDALONE, dtfmtWidth);
        for (int32_t dayIndex = UDAT_ABSOLUTE_SUNDAY;
                dayIndex <= UDAT_ABSOLUTE_SATURDAY; ++ dayIndex) {
            int32_t dateSymbolIndex = (dayIndex - UDAT_ABSOLUTE_SUNDAY) + UCAL_SUNDAY;
            absoluteUnits[style][dayIndex][UDAT_DIRECTION_PLAIN].fastCopyFrom(
                weekdayNames[dateSymbolIndex]);
        }
    }
}

static UBool loadUnitData(
        const UResourceBundle *resource,
        RelativeDateTimeCacheData &cacheData,
        const char* localeId,
        UErrorCode &status) {

    RelDateTimeFmtDataSink sink(cacheData);

    ures_getAllItemsWithFallback(resource, "fields", sink, status);
    if (U_FAILURE(status)) {
        return false;
    }

    // Get the weekday names from DateFormatSymbols.
    loadWeekdayNames(cacheData.absoluteUnits, localeId, status);
    return U_SUCCESS(status);
}

static UBool getDateTimePattern(
        const UResourceBundle *resource,
        UnicodeString &result,
        UErrorCode &status) {
    UnicodeString defaultCalendarName;
    if (!getStringWithFallback(
            resource,
            "calendar/default",
            defaultCalendarName,
            status)) {
        return FALSE;
    }
    CharString pathBuffer;
    pathBuffer.append("calendar/", status)
            .appendInvariantChars(defaultCalendarName, status)
            .append("/DateTimePatterns", status);
    LocalUResourceBundlePointer topLevel(
            ures_getByKeyWithFallback(
                    resource, pathBuffer.data(), nullptr, &status));
    if (U_FAILURE(status)) {
        return FALSE;
    }
    int32_t size = ures_getSize(topLevel.getAlias());
    if (size <= 8) {
        // Oops, size is too small to access the index that we want, fallback
        // to a hard-coded value.
        result = UNICODE_STRING_SIMPLE("{1} {0}");
        return TRUE;
    }
    return getStringByIndex(topLevel.getAlias(), 8, result, status);
}

template<> U_I18N_API
const RelativeDateTimeCacheData *LocaleCacheKey<RelativeDateTimeCacheData>::createObject(const void * /*unused*/, UErrorCode &status) const {
    const char *localeId = fLoc.getName();
    LocalUResourceBundlePointer topLevel(ures_open(nullptr, localeId, &status));
    if (U_FAILURE(status)) {
        return nullptr;
    }
    LocalPointer<RelativeDateTimeCacheData> result(
            new RelativeDateTimeCacheData());
    if (result.isNull()) {
        status = U_MEMORY_ALLOCATION_ERROR;
        return nullptr;
    }
    if (!loadUnitData(
            topLevel.getAlias(),
            *result,
            localeId,
            status)) {
        return nullptr;
    }
    UnicodeString dateTimePattern;
    if (!getDateTimePattern(topLevel.getAlias(), dateTimePattern, status)) {
        return nullptr;
    }
    result->adoptCombinedDateAndTime(
            new SimpleFormatter(dateTimePattern, 2, 2, status));
    if (U_FAILURE(status)) {
        return nullptr;
    }
    result->addRef();
    return result.orphan();
}



static constexpr number::impl::Field kRDTNumericField
    = number::impl::NumFieldUtils::compress<UFIELD_CATEGORY_RELATIVE_DATETIME, UDAT_REL_NUMERIC_FIELD>();

static constexpr number::impl::Field kRDTLiteralField
    = number::impl::NumFieldUtils::compress<UFIELD_CATEGORY_RELATIVE_DATETIME, UDAT_REL_LITERAL_FIELD>();

class FormattedRelativeDateTimeData : public FormattedValueNumberStringBuilderImpl {
public:
    FormattedRelativeDateTimeData() : FormattedValueNumberStringBuilderImpl(kRDTNumericField) {}
    virtual ~FormattedRelativeDateTimeData();
};

FormattedRelativeDateTimeData::~FormattedRelativeDateTimeData() = default;


UPRV_FORMATTED_VALUE_SUBCLASS_AUTO_IMPL(FormattedRelativeDateTime)


RelativeDateTimeFormatter::RelativeDateTimeFormatter(UErrorCode& status) :
        fCache(nullptr),
        fNumberFormat(nullptr),
        fPluralRules(nullptr),
        fStyle(UDAT_STYLE_LONG),
        fContext(UDISPCTX_CAPITALIZATION_NONE),
        fOptBreakIterator(nullptr) {
    init(nullptr, nullptr, status);
}

RelativeDateTimeFormatter::RelativeDateTimeFormatter(
        const Locale& locale, UErrorCode& status) :
        fCache(nullptr),
        fNumberFormat(nullptr),
        fPluralRules(nullptr),
        fStyle(UDAT_STYLE_LONG),
        fContext(UDISPCTX_CAPITALIZATION_NONE),
        fOptBreakIterator(nullptr),
        fLocale(locale) {
    init(nullptr, nullptr, status);
}

RelativeDateTimeFormatter::RelativeDateTimeFormatter(
        const Locale& locale, NumberFormat *nfToAdopt, UErrorCode& status) :
        fCache(nullptr),
        fNumberFormat(nullptr),
        fPluralRules(nullptr),
        fStyle(UDAT_STYLE_LONG),
        fContext(UDISPCTX_CAPITALIZATION_NONE),
        fOptBreakIterator(nullptr),
        fLocale(locale) {
    init(nfToAdopt, nullptr, status);
}

RelativeDateTimeFormatter::RelativeDateTimeFormatter(
        const Locale& locale,
        NumberFormat *nfToAdopt,
        UDateRelativeDateTimeFormatterStyle styl,
        UDisplayContext capitalizationContext,
        UErrorCode& status) :
        fCache(nullptr),
        fNumberFormat(nullptr),
        fPluralRules(nullptr),
        fStyle(styl),
        fContext(capitalizationContext),
        fOptBreakIterator(nullptr),
        fLocale(locale) {
    if (U_FAILURE(status)) {
        return;
    }
    if ((capitalizationContext >> 8) != UDISPCTX_TYPE_CAPITALIZATION) {
        status = U_ILLEGAL_ARGUMENT_ERROR;
        return;
    }
    if (capitalizationContext == UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE) {
        BreakIterator *bi = BreakIterator::createSentenceInstance(locale, status);
        if (U_FAILURE(status)) {
            return;
        }
        init(nfToAdopt, bi, status);
    } else {
        init(nfToAdopt, nullptr, status);
    }
}

RelativeDateTimeFormatter::RelativeDateTimeFormatter(
        const RelativeDateTimeFormatter& other)
        : UObject(other),
          fCache(other.fCache),
          fNumberFormat(other.fNumberFormat),
          fPluralRules(other.fPluralRules),
          fStyle(other.fStyle),
          fContext(other.fContext),
          fOptBreakIterator(other.fOptBreakIterator),
          fLocale(other.fLocale) {
    fCache->addRef();
    fNumberFormat->addRef();
    fPluralRules->addRef();
    if (fOptBreakIterator != nullptr) {
      fOptBreakIterator->addRef();
    }
}

RelativeDateTimeFormatter& RelativeDateTimeFormatter::operator=(
        const RelativeDateTimeFormatter& other) {
    if (this != &other) {
        SharedObject::copyPtr(other.fCache, fCache);
        SharedObject::copyPtr(other.fNumberFormat, fNumberFormat);
        SharedObject::copyPtr(other.fPluralRules, fPluralRules);
        SharedObject::copyPtr(other.fOptBreakIterator, fOptBreakIterator);
        fStyle = other.fStyle;
        fContext = other.fContext;
        fLocale = other.fLocale;
    }
    return *this;
}

RelativeDateTimeFormatter::~RelativeDateTimeFormatter() {
    if (fCache != nullptr) {
        fCache->removeRef();
    }
    if (fNumberFormat != nullptr) {
        fNumberFormat->removeRef();
    }
    if (fPluralRules != nullptr) {
        fPluralRules->removeRef();
    }
    if (fOptBreakIterator != nullptr) {
        fOptBreakIterator->removeRef();
    }
}

const NumberFormat& RelativeDateTimeFormatter::getNumberFormat() const {
    return **fNumberFormat;
}

UDisplayContext RelativeDateTimeFormatter::getCapitalizationContext() const {
    return fContext;
}

UDateRelativeDateTimeFormatterStyle RelativeDateTimeFormatter::getFormatStyle() const {
    return fStyle;
}


// To reduce boilerplate code, we use a helper function that forwards variadic
// arguments to the formatImpl function.

template<typename F, typename... Args>
UnicodeString& RelativeDateTimeFormatter::doFormat(
        F callback,
        UnicodeString& appendTo,
        UErrorCode& status,
        Args... args) const {
    FormattedRelativeDateTimeData output;
    (this->*callback)(std::forward<Args>(args)..., output, status);
    if (U_FAILURE(status)) {
        return appendTo;
    }
    UnicodeString result = output.getStringRef().toUnicodeString();
    return appendTo.append(adjustForContext(result));
}

template<typename F, typename... Args>
FormattedRelativeDateTime RelativeDateTimeFormatter::doFormatToValue(
        F callback,
        UErrorCode& status,
        Args... args) const {
    if (!checkNoAdjustForContext(status)) {
        return FormattedRelativeDateTime(status);
    }
    LocalPointer<FormattedRelativeDateTimeData> output(
        new FormattedRelativeDateTimeData(), status);
    if (U_FAILURE(status)) {
        return FormattedRelativeDateTime(status);
    }
    (this->*callback)(std::forward<Args>(args)..., *output, status);
    output->getStringRef().writeTerminator(status);
    return FormattedRelativeDateTime(output.orphan());
}

UnicodeString& RelativeDateTimeFormatter::format(
        double quantity,
        UDateDirection direction,
        UDateRelativeUnit unit,
        UnicodeString& appendTo,
        UErrorCode& status) const {
    return doFormat(
        &RelativeDateTimeFormatter::formatImpl,
        appendTo,
        status,
        quantity,
        direction,
        unit);
}

FormattedRelativeDateTime RelativeDateTimeFormatter::formatToValue(
        double quantity,
        UDateDirection direction,
        UDateRelativeUnit unit,
        UErrorCode& status) const {
    return doFormatToValue(
        &RelativeDateTimeFormatter::formatImpl,
        status,
        quantity,
        direction,
        unit);
}

void RelativeDateTimeFormatter::formatImpl(
        double quantity,
        UDateDirection direction,
        UDateRelativeUnit unit,
        FormattedRelativeDateTimeData& output,
        UErrorCode& status) const {
    if (U_FAILURE(status)) {
        return;
    }
    if (direction != UDAT_DIRECTION_LAST && direction != UDAT_DIRECTION_NEXT) {
        status = U_ILLEGAL_ARGUMENT_ERROR;
        return;
    }
    int32_t bFuture = direction == UDAT_DIRECTION_NEXT ? 1 : 0;

    StandardPlural::Form pluralForm;
    QuantityFormatter::formatAndSelect(
        quantity,
        **fNumberFormat,
        **fPluralRules,
        output.getStringRef(),
        pluralForm,
        status);
    if (U_FAILURE(status)) {
        return;
    }

    const SimpleFormatter* formatter =
        fCache->getRelativeUnitFormatter(fStyle, unit, bFuture, pluralForm);
    if (formatter == nullptr) {
        // TODO: WARN - look at quantity formatter's action with an error.
        status = U_INVALID_FORMAT_ERROR;
        return;
    }

    number::impl::SimpleModifier modifier(*formatter, kRDTLiteralField, false);
    modifier.formatAsPrefixSuffix(
        output.getStringRef(), 0, output.getStringRef().length(), status);
}

UnicodeString& RelativeDateTimeFormatter::formatNumeric(
        double offset,
        URelativeDateTimeUnit unit,
        UnicodeString& appendTo,
        UErrorCode& status) const {
    return doFormat(
        &RelativeDateTimeFormatter::formatNumericImpl,
        appendTo,
        status,
        offset,
        unit);
}

FormattedRelativeDateTime RelativeDateTimeFormatter::formatNumericToValue(
        double offset,
        URelativeDateTimeUnit unit,
        UErrorCode& status) const {
    return doFormatToValue(
        &RelativeDateTimeFormatter::formatNumericImpl,
        status,
        offset,
        unit);
}

void RelativeDateTimeFormatter::formatNumericImpl(
        double offset,
        URelativeDateTimeUnit unit,
        FormattedRelativeDateTimeData& output,
        UErrorCode& status) const {
    if (U_FAILURE(status)) {
        return;
    }
    UDateDirection direction = UDAT_DIRECTION_NEXT;
    if (std::signbit(offset)) { // needed to handle -0.0
        direction = UDAT_DIRECTION_LAST;
        offset = -offset;
    }
    if (direction != UDAT_DIRECTION_LAST && direction != UDAT_DIRECTION_NEXT) {
        status = U_ILLEGAL_ARGUMENT_ERROR;
        return;
    }
    int32_t bFuture = direction == UDAT_DIRECTION_NEXT ? 1 : 0;

    StandardPlural::Form pluralForm;
    QuantityFormatter::formatAndSelect(
        offset,
        **fNumberFormat,
        **fPluralRules,
        output.getStringRef(),
        pluralForm,
        status);
    if (U_FAILURE(status)) {
        return;
    }

    const SimpleFormatter* formatter =
        fCache->getRelativeDateTimeUnitFormatter(fStyle, unit, bFuture, pluralForm);
    if (formatter == nullptr) {
        // TODO: WARN - look at quantity formatter's action with an error.
        status = U_INVALID_FORMAT_ERROR;
        return;
    }

    number::impl::SimpleModifier modifier(*formatter, kRDTLiteralField, false);
    modifier.formatAsPrefixSuffix(
        output.getStringRef(), 0, output.getStringRef().length(), status);
}

UnicodeString& RelativeDateTimeFormatter::format(
        UDateDirection direction,
        UDateAbsoluteUnit unit,
        UnicodeString& appendTo,
        UErrorCode& status) const {
    return doFormat(
        &RelativeDateTimeFormatter::formatAbsoluteImpl,
        appendTo,
        status,
        direction,
        unit);
}

FormattedRelativeDateTime RelativeDateTimeFormatter::formatToValue(
        UDateDirection direction,
        UDateAbsoluteUnit unit,
        UErrorCode& status) const {
    return doFormatToValue(
        &RelativeDateTimeFormatter::formatAbsoluteImpl,
        status,
        direction,
        unit);
}

void RelativeDateTimeFormatter::formatAbsoluteImpl(
        UDateDirection direction,
        UDateAbsoluteUnit unit,
        FormattedRelativeDateTimeData& output,
        UErrorCode& status) const {
    if (U_FAILURE(status)) {
        return;
    }
    if (unit == UDAT_ABSOLUTE_NOW && direction != UDAT_DIRECTION_PLAIN) {
        status = U_ILLEGAL_ARGUMENT_ERROR;
        return;
    }

    // Get string using fallback.
    output.getStringRef().append(
        fCache->getAbsoluteUnitString(fStyle, unit, direction),
        kRDTLiteralField,
        status);
}

UnicodeString& RelativeDateTimeFormatter::format(
        double offset,
        URelativeDateTimeUnit unit,
        UnicodeString& appendTo,
        UErrorCode& status) const {
    return doFormat(
        &RelativeDateTimeFormatter::formatRelativeImpl,
        appendTo,
        status,
        offset,
        unit);
}

FormattedRelativeDateTime RelativeDateTimeFormatter::formatToValue(
        double offset,
        URelativeDateTimeUnit unit,
        UErrorCode& status) const {
    return doFormatToValue(
        &RelativeDateTimeFormatter::formatRelativeImpl,
        status,
        offset,
        unit);
}

void RelativeDateTimeFormatter::formatRelativeImpl(
        double offset,
        URelativeDateTimeUnit unit,
        FormattedRelativeDateTimeData& output,
        UErrorCode& status) const {
    if (U_FAILURE(status)) {
        return;
    }
    // TODO:
    // The full implementation of this depends on CLDR data that is not yet available,
    // see: http://unicode.org/cldr/trac/ticket/9165 Add more relative field data.
    // In the meantime do a quick bring-up by calling the old format method; this
    // leaves some holes (even for data that is currently available, such as quarter).
    // When the new CLDR data is available, update the data storage accordingly,
    // rewrite this to use it directly, and rewrite the old format method to call this
    // new one; that is covered by http://bugs.icu-project.org/trac/ticket/12171.
    UDateDirection direction = UDAT_DIRECTION_COUNT;
    if (offset > -2.1 && offset < 2.1) {
        // Allow a 1% epsilon, so offsets in -1.01..-0.99 map to LAST
        double offsetx100 = offset * 100.0;
        int32_t intoffset = (offsetx100 < 0)? (int32_t)(offsetx100-0.5) : (int32_t)(offsetx100+0.5);
        switch (intoffset) {
            case -200/*-2*/: direction = UDAT_DIRECTION_LAST_2; break;
            case -100/*-1*/: direction = UDAT_DIRECTION_LAST; break;
            case    0/* 0*/: direction = UDAT_DIRECTION_THIS; break;
            case  100/* 1*/: direction = UDAT_DIRECTION_NEXT; break;
            case  200/* 2*/: direction = UDAT_DIRECTION_NEXT_2; break;
            default: break;
    	}
    }
    UDateAbsoluteUnit absunit = UDAT_ABSOLUTE_UNIT_COUNT;
    switch (unit) {
        case UDAT_REL_UNIT_YEAR:    absunit = UDAT_ABSOLUTE_YEAR; break;
        case UDAT_REL_UNIT_QUARTER: absunit = UDAT_ABSOLUTE_QUARTER; break;
        case UDAT_REL_UNIT_MONTH:   absunit = UDAT_ABSOLUTE_MONTH; break;
        case UDAT_REL_UNIT_WEEK:    absunit = UDAT_ABSOLUTE_WEEK; break;
        case UDAT_REL_UNIT_DAY:     absunit = UDAT_ABSOLUTE_DAY; break;
        case UDAT_REL_UNIT_SECOND:
            if (direction == UDAT_DIRECTION_THIS) {
                absunit = UDAT_ABSOLUTE_NOW;
                direction = UDAT_DIRECTION_PLAIN;
            }
            break;
        case UDAT_REL_UNIT_SUNDAY:  absunit = UDAT_ABSOLUTE_SUNDAY; break;
        case UDAT_REL_UNIT_MONDAY:  absunit = UDAT_ABSOLUTE_MONDAY; break;
        case UDAT_REL_UNIT_TUESDAY:  absunit = UDAT_ABSOLUTE_TUESDAY; break;
        case UDAT_REL_UNIT_WEDNESDAY:  absunit = UDAT_ABSOLUTE_WEDNESDAY; break;
        case UDAT_REL_UNIT_THURSDAY:  absunit = UDAT_ABSOLUTE_THURSDAY; break;
        case UDAT_REL_UNIT_FRIDAY:  absunit = UDAT_ABSOLUTE_FRIDAY; break;
        case UDAT_REL_UNIT_SATURDAY:  absunit = UDAT_ABSOLUTE_SATURDAY; break;
        default: break;
    }
    if (direction != UDAT_DIRECTION_COUNT && absunit != UDAT_ABSOLUTE_UNIT_COUNT) {
        formatAbsoluteImpl(direction, absunit, output, status);
        if (output.getStringRef().length() != 0) {
            return;
        }
    }
    // otherwise fallback to formatNumeric
    formatNumericImpl(offset, unit, output, status);
}

UnicodeString& RelativeDateTimeFormatter::combineDateAndTime(
        const UnicodeString& relativeDateString, const UnicodeString& timeString,
        UnicodeString& appendTo, UErrorCode& status) const {
    return fCache->getCombinedDateAndTime()->format(
            timeString, relativeDateString, appendTo, status);
}

UnicodeString& RelativeDateTimeFormatter::adjustForContext(UnicodeString &str) const {
    if (fOptBreakIterator == nullptr
        || str.length() == 0 || !u_islower(str.char32At(0))) {
        return str;
    }

    // Must guarantee that one thread at a time accesses the shared break
    // iterator.
    static icu::UMutex gBrkIterMutex = U_MUTEX_INITIALIZER;
    Mutex lock(&gBrkIterMutex);
    str.toTitle(
            fOptBreakIterator->get(),
            fLocale,
            U_TITLECASE_NO_LOWERCASE | U_TITLECASE_NO_BREAK_ADJUSTMENT);
    return str;
}

UBool RelativeDateTimeFormatter::checkNoAdjustForContext(UErrorCode& status) const {
    // This is unsupported because it's hard to keep fields in sync with title
    // casing. The code could be written and tested if there is demand.
    if (fOptBreakIterator != nullptr) {
        status = U_UNSUPPORTED_ERROR;
        return FALSE;
    }
    return TRUE;
}

void RelativeDateTimeFormatter::init(
        NumberFormat *nfToAdopt,
        BreakIterator *biToAdopt,
        UErrorCode &status) {
    LocalPointer<NumberFormat> nf(nfToAdopt);
    LocalPointer<BreakIterator> bi(biToAdopt);
    UnifiedCache::getByLocale(fLocale, fCache, status);
    if (U_FAILURE(status)) {
        return;
    }
    const SharedPluralRules *pr = PluralRules::createSharedInstance(
            fLocale, UPLURAL_TYPE_CARDINAL, status);
    if (U_FAILURE(status)) {
        return;
    }
    SharedObject::copyPtr(pr, fPluralRules);
    pr->removeRef();
    if (nf.isNull()) {
       const SharedNumberFormat *shared = NumberFormat::createSharedInstance(
               fLocale, UNUM_DECIMAL, status);
        if (U_FAILURE(status)) {
            return;
        }
        SharedObject::copyPtr(shared, fNumberFormat);
        shared->removeRef();
    } else {
        SharedNumberFormat *shared = new SharedNumberFormat(nf.getAlias());
        if (shared == nullptr) {
            status = U_MEMORY_ALLOCATION_ERROR;
            return;
        }
        nf.orphan();
        SharedObject::copyPtr(shared, fNumberFormat);
    }
    if (bi.isNull()) {
        SharedObject::clearPtr(fOptBreakIterator);
    } else {
        SharedBreakIterator *shared = new SharedBreakIterator(bi.getAlias());
        if (shared == nullptr) {
            status = U_MEMORY_ALLOCATION_ERROR;
            return;
        }
        bi.orphan();
        SharedObject::copyPtr(shared, fOptBreakIterator);
    }
}

U_NAMESPACE_END

// Plain C API

U_NAMESPACE_USE


// Magic number: "FRDT" (FormattedRelativeDateTime) in ASCII
UPRV_FORMATTED_VALUE_CAPI_AUTO_IMPL(
    FormattedRelativeDateTime,
    UFormattedRelativeDateTime,
    UFormattedRelativeDateTimeImpl,
    UFormattedRelativeDateTimeApiHelper,
    ureldatefmt,
    0x46524454)


U_CAPI URelativeDateTimeFormatter* U_EXPORT2
ureldatefmt_open( const char*          locale,
                  UNumberFormat*       nfToAdopt,
                  UDateRelativeDateTimeFormatterStyle width,
                  UDisplayContext      capitalizationContext,
                  UErrorCode*          status )
{
    if (U_FAILURE(*status)) {
        return nullptr;
    }
    LocalPointer<RelativeDateTimeFormatter> formatter(new RelativeDateTimeFormatter(Locale(locale),
                                                              (NumberFormat*)nfToAdopt, width,
                                                              capitalizationContext, *status), *status);
    if (U_FAILURE(*status)) {
        return nullptr;
    }
    return (URelativeDateTimeFormatter*)formatter.orphan();
}

U_CAPI void U_EXPORT2
ureldatefmt_close(URelativeDateTimeFormatter *reldatefmt)
{
    delete (RelativeDateTimeFormatter*)reldatefmt;
}

U_CAPI int32_t U_EXPORT2
ureldatefmt_formatNumeric( const URelativeDateTimeFormatter* reldatefmt,
                    double                offset,
                    URelativeDateTimeUnit unit,
                    UChar*                result,
                    int32_t               resultCapacity,
                    UErrorCode*           status)
{
    if (U_FAILURE(*status)) {
        return 0;
    }
    if (result == nullptr ? resultCapacity != 0 : resultCapacity < 0) {
        *status = U_ILLEGAL_ARGUMENT_ERROR;
        return 0;
    }
    UnicodeString res;
    if (result != nullptr) {
        // nullptr destination for pure preflighting: empty dummy string
        // otherwise, alias the destination buffer (copied from udat_format)
        res.setTo(result, 0, resultCapacity);
    }
    ((RelativeDateTimeFormatter*)reldatefmt)->formatNumeric(offset, unit, res, *status);
    if (U_FAILURE(*status)) {
        return 0;
    }
    return res.extract(result, resultCapacity, *status);
}

U_STABLE void U_EXPORT2
ureldatefmt_formatNumericToResult(
        const URelativeDateTimeFormatter* reldatefmt,
        double                            offset,
        URelativeDateTimeUnit             unit,
        UFormattedRelativeDateTime*       result,
        UErrorCode*                       status) {
    if (U_FAILURE(*status)) {
        return;
    }
    auto* fmt = reinterpret_cast<const RelativeDateTimeFormatter*>(reldatefmt);
    auto* resultImpl = UFormattedRelativeDateTimeApiHelper::validate(result, *status);
    resultImpl->fImpl = fmt->formatNumericToValue(offset, unit, *status);
}

U_CAPI int32_t U_EXPORT2
ureldatefmt_format( const URelativeDateTimeFormatter* reldatefmt,
                    double                offset,
                    URelativeDateTimeUnit unit,
                    UChar*                result,
                    int32_t               resultCapacity,
                    UErrorCode*           status)
{
    if (U_FAILURE(*status)) {
        return 0;
    }
    if (result == nullptr ? resultCapacity != 0 : resultCapacity < 0) {
        *status = U_ILLEGAL_ARGUMENT_ERROR;
        return 0;
    }
    UnicodeString res;
    if (result != nullptr) {
        // nullptr destination for pure preflighting: empty dummy string
        // otherwise, alias the destination buffer (copied from udat_format)
        res.setTo(result, 0, resultCapacity);
    }
    ((RelativeDateTimeFormatter*)reldatefmt)->format(offset, unit, res, *status);
    if (U_FAILURE(*status)) {
        return 0;
    }
    return res.extract(result, resultCapacity, *status);
}

U_DRAFT void U_EXPORT2
ureldatefmt_formatToResult(
        const URelativeDateTimeFormatter* reldatefmt,
        double                            offset,
        URelativeDateTimeUnit             unit,
        UFormattedRelativeDateTime*       result,
        UErrorCode*                       status) {
    if (U_FAILURE(*status)) {
        return;
    }
    auto* fmt = reinterpret_cast<const RelativeDateTimeFormatter*>(reldatefmt);
    auto* resultImpl = UFormattedRelativeDateTimeApiHelper::validate(result, *status);
    resultImpl->fImpl = fmt->formatToValue(offset, unit, *status);
}

U_CAPI int32_t U_EXPORT2
ureldatefmt_combineDateAndTime( const URelativeDateTimeFormatter* reldatefmt,
                    const UChar *     relativeDateString,
                    int32_t           relativeDateStringLen,
                    const UChar *     timeString,
                    int32_t           timeStringLen,
                    UChar*            result,
                    int32_t           resultCapacity,
                    UErrorCode*       status )
{
    if (U_FAILURE(*status)) {
        return 0;
    }
    if (result == nullptr ? resultCapacity != 0 : resultCapacity < 0 ||
            (relativeDateString == nullptr ? relativeDateStringLen != 0 : relativeDateStringLen < -1) ||
            (timeString == nullptr ? timeStringLen != 0 : timeStringLen < -1)) {
        *status = U_ILLEGAL_ARGUMENT_ERROR;
        return 0;
    }
    UnicodeString relDateStr((UBool)(relativeDateStringLen == -1), relativeDateString, relativeDateStringLen);
    UnicodeString timeStr((UBool)(timeStringLen == -1), timeString, timeStringLen);
    UnicodeString res(result, 0, resultCapacity);
    ((RelativeDateTimeFormatter*)reldatefmt)->combineDateAndTime(relDateStr, timeStr, res, *status);
    if (U_FAILURE(*status)) {
        return 0;
    }
    return res.extract(result, resultCapacity, *status);
}

#endif /* !UCONFIG_NO_FORMATTING */
