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

#include "unicode/utypes.h"

#if !UCONFIG_NO_FORMATTING

#include "unicode/ulistformatter.h"
#include "unicode/listformatter.h"
#include "unicode/localpointer.h"
#include "cmemory.h"
#include "formattedval_impl.h"

U_NAMESPACE_USE

U_CAPI UListFormatter* U_EXPORT2
ulistfmt_open(const char*  locale,
              UErrorCode*  status)
{
    if (U_FAILURE(*status)) {
        return NULL;
    }
    LocalPointer<ListFormatter> listfmt(ListFormatter::createInstance(Locale(locale), *status));
    if (U_FAILURE(*status)) {
        return NULL;
    }
    return (UListFormatter*)listfmt.orphan();
}


U_CAPI void U_EXPORT2
ulistfmt_close(UListFormatter *listfmt)
{
    delete (ListFormatter*)listfmt;
}


// Magic number: FLST in ASCII
UPRV_FORMATTED_VALUE_CAPI_AUTO_IMPL(
    FormattedList,
    UFormattedList,
    UFormattedListImpl,
    UFormattedListApiHelper,
    ulistfmt,
    0x464C5354)


static UnicodeString* getUnicodeStrings(
        const UChar* const strings[],
        const int32_t* stringLengths,
        int32_t stringCount,
        UnicodeString* length4StackBuffer,
        LocalArray<UnicodeString>& maybeOwner,
        UErrorCode& status) {
    U_ASSERT(U_SUCCESS(status));
    if (stringCount < 0 || (strings == NULL && stringCount > 0)) {
        status = U_ILLEGAL_ARGUMENT_ERROR;
        return nullptr;
    }
    UnicodeString* ustrings = length4StackBuffer;
    if (stringCount > 4) {
        maybeOwner.adoptInsteadAndCheckErrorCode(new UnicodeString[stringCount], status);
        if (U_FAILURE(status)) {
            return nullptr;
        }
        ustrings = maybeOwner.getAlias();
    }
    if (stringLengths == NULL) {
        for (int32_t stringIndex = 0; stringIndex < stringCount; stringIndex++) {
            ustrings[stringIndex].setTo(TRUE, strings[stringIndex], -1);
        }
    } else {
        for (int32_t stringIndex = 0; stringIndex < stringCount; stringIndex++) {
            ustrings[stringIndex].setTo(stringLengths[stringIndex] < 0, strings[stringIndex], stringLengths[stringIndex]);
        }
    }
    return ustrings;
}


U_CAPI int32_t U_EXPORT2
ulistfmt_format(const UListFormatter* listfmt,
                const UChar* const strings[],
                const int32_t *    stringLengths,
                int32_t            stringCount,
                UChar*             result,
                int32_t            resultCapacity,
                UErrorCode*        status)
{
    if (U_FAILURE(*status)) {
        return -1;
    }
    if ((result == NULL) ? resultCapacity != 0 : resultCapacity < 0) {
        *status = U_ILLEGAL_ARGUMENT_ERROR;
        return -1;
    }
    UnicodeString length4StackBuffer[4];
    LocalArray<UnicodeString> maybeOwner;
    UnicodeString* ustrings = getUnicodeStrings(
        strings, stringLengths, stringCount, length4StackBuffer, maybeOwner, *status);
    if (U_FAILURE(*status)) {
        return -1;
    }
    UnicodeString res;
    if (result != NULL) {
        // NULL destination for pure preflighting: empty dummy string
        // otherwise, alias the destination buffer (copied from udat_format)
        res.setTo(result, 0, resultCapacity);
    }
    reinterpret_cast<const ListFormatter*>(listfmt)->format( ustrings, stringCount, res, *status );
    return res.extract(result, resultCapacity, *status);
}


U_CAPI void U_EXPORT2
ulistfmt_formatStringsToResult(
                const UListFormatter* listfmt,
                const UChar* const strings[],
                const int32_t *    stringLengths,
                int32_t            stringCount,
                UFormattedList*    uresult,
                UErrorCode*        status) {
    auto* result = UFormattedListApiHelper::validate(uresult, *status);
    if (U_FAILURE(*status)) {
        return;
    }
    UnicodeString length4StackBuffer[4];
    LocalArray<UnicodeString> maybeOwner;
    UnicodeString* ustrings = getUnicodeStrings(
        strings, stringLengths, stringCount, length4StackBuffer, maybeOwner, *status);
    if (U_FAILURE(*status)) {
        return;
    }
    result->fImpl = reinterpret_cast<const ListFormatter*>(listfmt)
        ->formatStringsToValue(ustrings, stringCount, *status);
}


#endif /* #if !UCONFIG_NO_FORMATTING */
