// © 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 "numberformattesttuple.h"

#if !UCONFIG_NO_FORMATTING

#include "unicode/testlog.h"
#include "ustrfmt.h"
#include "charstr.h"
#include "cstring.h"
#include "cmemory.h"

static NumberFormatTestTuple emptyObject;

static NumberFormatTestTuple *gNullPtr = &emptyObject;

#define FIELD_OFFSET(fieldName) ((int32_t) (((char *) &gNullPtr->fieldName) - ((char *) gNullPtr)))
#define FIELD_FLAG_OFFSET(fieldName) ((int32_t) (((char *) &gNullPtr->fieldName##Flag) - ((char *) gNullPtr)))

#define FIELD_INIT(fieldName, fieldType) {#fieldName, FIELD_OFFSET(fieldName), FIELD_FLAG_OFFSET(fieldName), fieldType}

struct Numberformattesttuple_EnumConversion {
    const char *str;
    int32_t value;
};

static Numberformattesttuple_EnumConversion gRoundingEnum[] = {
    {"ceiling", DecimalFormat::kRoundCeiling},
    {"floor", DecimalFormat::kRoundFloor},
    {"down", DecimalFormat::kRoundDown},
    {"up", DecimalFormat::kRoundUp},
    {"halfEven", DecimalFormat::kRoundHalfEven},
    {"halfDown", DecimalFormat::kRoundHalfDown},
    {"halfUp", DecimalFormat::kRoundHalfUp},
    {"unnecessary", DecimalFormat::kRoundUnnecessary}};

static Numberformattesttuple_EnumConversion gCurrencyUsageEnum[] = {
    {"standard", UCURR_USAGE_STANDARD},
    {"cash", UCURR_USAGE_CASH}};

static Numberformattesttuple_EnumConversion gPadPositionEnum[] = {
    {"beforePrefix", DecimalFormat::kPadBeforePrefix},
    {"afterPrefix", DecimalFormat::kPadAfterPrefix},
    {"beforeSuffix", DecimalFormat::kPadBeforeSuffix},
    {"afterSuffix", DecimalFormat::kPadAfterSuffix}};

static Numberformattesttuple_EnumConversion gFormatStyleEnum[] = {
    {"patternDecimal", UNUM_PATTERN_DECIMAL},
    {"decimal", UNUM_DECIMAL},
    {"currency", UNUM_CURRENCY},
    {"percent", UNUM_PERCENT},
    {"scientific", UNUM_SCIENTIFIC},
    {"spellout", UNUM_SPELLOUT},
    {"ordinal", UNUM_ORDINAL},
    {"duration", UNUM_DURATION},
    {"numberingSystem", UNUM_NUMBERING_SYSTEM},
    {"patternRuleBased", UNUM_PATTERN_RULEBASED},
    {"currencyIso", UNUM_CURRENCY_ISO},
    {"currencyPlural", UNUM_CURRENCY_PLURAL},
    {"currencyAccounting", UNUM_CURRENCY_ACCOUNTING},
    {"cashCurrency", UNUM_CASH_CURRENCY},
    {"default", UNUM_DEFAULT},
    {"ignore", UNUM_IGNORE}};

static int32_t toEnum(
        const Numberformattesttuple_EnumConversion *table,
        int32_t tableLength,
        const UnicodeString &str,
        UErrorCode &status) {
    if (U_FAILURE(status)) {
        return 0;
    }
    CharString cstr;
    cstr.appendInvariantChars(str, status);
    if (U_FAILURE(status)) {
        return 0;
    }
    for (int32_t i = 0; i < tableLength; ++i) {
        if (uprv_strcmp(cstr.data(), table[i].str) == 0) {
            return table[i].value;
        }
    }
    status = U_ILLEGAL_ARGUMENT_ERROR;
    return 0;
}

static void fromEnum(
        const Numberformattesttuple_EnumConversion *table,
        int32_t tableLength,
        int32_t val,
        UnicodeString &appendTo) {
    for (int32_t i = 0; i < tableLength; ++i) {
        if (table[i].value == val) {
            appendTo.append(table[i].str);
        }
    }
}

static void identVal(
        const UnicodeString &str, void *strPtr, UErrorCode & /*status*/) {
    *static_cast<UnicodeString *>(strPtr) = str;
}
 
static void identStr(
        const void *strPtr, UnicodeString &appendTo) {
    appendTo.append(*static_cast<const UnicodeString *>(strPtr));
}

static void strToLocale(
        const UnicodeString &str, void *localePtr, UErrorCode &status) {
    if (U_FAILURE(status)) {
        return;
    }
    CharString localeStr;
    localeStr.appendInvariantChars(str, status);
    *static_cast<Locale *>(localePtr) = Locale(localeStr.data());
}

static void localeToStr(
        const void *localePtr, UnicodeString &appendTo) {
    appendTo.append(
            UnicodeString(
                    static_cast<const Locale *>(localePtr)->getName()));
}

static void strToInt(
        const UnicodeString &str, void *intPtr, UErrorCode &status) {
    if (U_FAILURE(status)) {
        return;
    }
    int32_t len = str.length();
    int32_t start = 0;
    UBool neg = FALSE;
    if (len > 0 && str[0] == 0x2D) { // negative
        neg = TRUE;
        start = 1;
    }
    if (start == len) {
        status = U_ILLEGAL_ARGUMENT_ERROR;
        return;
    }
    int64_t value = 0;
    for (int32_t i = start; i < len; ++i) {
        UChar ch = str[i];
        if (ch < 0x30 || ch > 0x39) {
            status = U_ILLEGAL_ARGUMENT_ERROR;
            return;
        }
        value = value * 10 - 0x30 + (int32_t) ch;
    }
    int32_t signedValue = neg ? static_cast<int32_t>(-value) : static_cast<int32_t>(value);
    *static_cast<int32_t *>(intPtr) = signedValue;
}

static void intToStr(
        const void *intPtr, UnicodeString &appendTo) {
    UChar buffer[20];
    // int64_t such that all int32_t values can be negated
    int64_t xSigned = *static_cast<const int32_t *>(intPtr);
    uint32_t x;
    if (xSigned < 0) {
        appendTo.append((UChar)0x2D);
        x = static_cast<uint32_t>(-xSigned);
    } else {
        x = static_cast<uint32_t>(xSigned);
    }
    int32_t len = uprv_itou(buffer, UPRV_LENGTHOF(buffer), x, 10, 1);
    appendTo.append(buffer, 0, len);
}

static void strToDouble(
        const UnicodeString &str, void *doublePtr, UErrorCode &status) {
    if (U_FAILURE(status)) {
        return;
    }
    CharString buffer;
    buffer.appendInvariantChars(str, status);
    if (U_FAILURE(status)) {
        return;
    }
    *static_cast<double *>(doublePtr) = atof(buffer.data());
}

static void doubleToStr(
        const void *doublePtr, UnicodeString &appendTo) {
    char buffer[256];
    double x = *static_cast<const double *>(doublePtr);
    sprintf(buffer, "%f", x);
    appendTo.append(buffer);
}

static void strToERounding(
        const UnicodeString &str, void *roundPtr, UErrorCode &status) {
    int32_t val = toEnum(
            gRoundingEnum, UPRV_LENGTHOF(gRoundingEnum), str, status);
    *static_cast<DecimalFormat::ERoundingMode *>(roundPtr) = (DecimalFormat::ERoundingMode) val;
}

static void eRoundingToStr(
        const void *roundPtr, UnicodeString &appendTo) {
    DecimalFormat::ERoundingMode rounding = 
            *static_cast<const DecimalFormat::ERoundingMode *>(roundPtr);
    fromEnum(
            gRoundingEnum,
            UPRV_LENGTHOF(gRoundingEnum),
            rounding,
            appendTo);
}

static void strToCurrencyUsage(
        const UnicodeString &str, void *currencyUsagePtr, UErrorCode &status) {
    int32_t val = toEnum(
            gCurrencyUsageEnum, UPRV_LENGTHOF(gCurrencyUsageEnum), str, status);
    *static_cast<UCurrencyUsage *>(currencyUsagePtr) = (UCurrencyUsage) val;
}

static void currencyUsageToStr(
        const void *currencyUsagePtr, UnicodeString &appendTo) {
    UCurrencyUsage currencyUsage = 
            *static_cast<const UCurrencyUsage *>(currencyUsagePtr);
    fromEnum(
            gCurrencyUsageEnum,
            UPRV_LENGTHOF(gCurrencyUsageEnum),
            currencyUsage,
            appendTo);
}

static void strToEPadPosition(
        const UnicodeString &str, void *padPositionPtr, UErrorCode &status) {
    int32_t val = toEnum(
            gPadPositionEnum, UPRV_LENGTHOF(gPadPositionEnum), str, status);
    *static_cast<DecimalFormat::EPadPosition *>(padPositionPtr) =
            (DecimalFormat::EPadPosition) val;
}

static void ePadPositionToStr(
        const void *padPositionPtr, UnicodeString &appendTo) {
    DecimalFormat::EPadPosition padPosition = 
            *static_cast<const DecimalFormat::EPadPosition *>(padPositionPtr);
    fromEnum(
            gPadPositionEnum,
            UPRV_LENGTHOF(gPadPositionEnum),
            padPosition,
            appendTo);
}

static void strToFormatStyle(
        const UnicodeString &str, void *formatStylePtr, UErrorCode &status) {
    int32_t val = toEnum(
            gFormatStyleEnum, UPRV_LENGTHOF(gFormatStyleEnum), str, status);
    *static_cast<UNumberFormatStyle *>(formatStylePtr) = (UNumberFormatStyle) val;
}

static void formatStyleToStr(
        const void *formatStylePtr, UnicodeString &appendTo) {
    UNumberFormatStyle formatStyle = 
            *static_cast<const UNumberFormatStyle *>(formatStylePtr);
    fromEnum(
            gFormatStyleEnum,
            UPRV_LENGTHOF(gFormatStyleEnum),
            formatStyle,
            appendTo);
}

struct NumberFormatTestTupleFieldOps {
    void (*toValue)(const UnicodeString &str, void *valPtr, UErrorCode &);
    void (*toString)(const void *valPtr, UnicodeString &appendTo);
};

const NumberFormatTestTupleFieldOps gStrOps = {identVal, identStr};
const NumberFormatTestTupleFieldOps gIntOps = {strToInt, intToStr};
const NumberFormatTestTupleFieldOps gLocaleOps = {strToLocale, localeToStr};
const NumberFormatTestTupleFieldOps gDoubleOps = {strToDouble, doubleToStr};
const NumberFormatTestTupleFieldOps gERoundingOps = {strToERounding, eRoundingToStr};
const NumberFormatTestTupleFieldOps gCurrencyUsageOps = {strToCurrencyUsage, currencyUsageToStr};
const NumberFormatTestTupleFieldOps gEPadPositionOps = {strToEPadPosition, ePadPositionToStr};
const NumberFormatTestTupleFieldOps gFormatStyleOps = {strToFormatStyle, formatStyleToStr};

struct NumberFormatTestTupleFieldData {
    const char *name;
    int32_t offset;
    int32_t flagOffset;
    const NumberFormatTestTupleFieldOps *ops;
};

// Order must correspond to ENumberFormatTestTupleField
const NumberFormatTestTupleFieldData gFieldData[] = {
    FIELD_INIT(locale, &gLocaleOps),
    FIELD_INIT(currency, &gStrOps),
    FIELD_INIT(pattern, &gStrOps),
    FIELD_INIT(format, &gStrOps),
    FIELD_INIT(output, &gStrOps),
    FIELD_INIT(comment, &gStrOps),
    FIELD_INIT(minIntegerDigits, &gIntOps),
    FIELD_INIT(maxIntegerDigits, &gIntOps),
    FIELD_INIT(minFractionDigits, &gIntOps),
    FIELD_INIT(maxFractionDigits, &gIntOps),
    FIELD_INIT(minGroupingDigits, &gIntOps),
    FIELD_INIT(breaks, &gStrOps),
    FIELD_INIT(useSigDigits, &gIntOps),
    FIELD_INIT(minSigDigits, &gIntOps),
    FIELD_INIT(maxSigDigits, &gIntOps),
    FIELD_INIT(useGrouping, &gIntOps),
    FIELD_INIT(multiplier, &gIntOps),
    FIELD_INIT(roundingIncrement, &gDoubleOps),
    FIELD_INIT(formatWidth, &gIntOps),
    FIELD_INIT(padCharacter, &gStrOps),
    FIELD_INIT(useScientific, &gIntOps),
    FIELD_INIT(grouping, &gIntOps),
    FIELD_INIT(grouping2, &gIntOps),
    FIELD_INIT(roundingMode, &gERoundingOps),
    FIELD_INIT(currencyUsage, &gCurrencyUsageOps),
    FIELD_INIT(minimumExponentDigits, &gIntOps),
    FIELD_INIT(exponentSignAlwaysShown, &gIntOps),
    FIELD_INIT(decimalSeparatorAlwaysShown, &gIntOps),
    FIELD_INIT(padPosition, &gEPadPositionOps),
    FIELD_INIT(positivePrefix, &gStrOps),
    FIELD_INIT(positiveSuffix, &gStrOps),
    FIELD_INIT(negativePrefix, &gStrOps),
    FIELD_INIT(negativeSuffix, &gStrOps),
    FIELD_INIT(signAlwaysShown, &gIntOps),
    FIELD_INIT(localizedPattern, &gStrOps),
    FIELD_INIT(toPattern, &gStrOps),
    FIELD_INIT(toLocalizedPattern, &gStrOps),
    FIELD_INIT(style, &gFormatStyleOps),
    FIELD_INIT(parse, &gStrOps),
    FIELD_INIT(lenient, &gIntOps),
    FIELD_INIT(plural, &gStrOps),
    FIELD_INIT(parseIntegerOnly, &gIntOps),
    FIELD_INIT(decimalPatternMatchRequired, &gIntOps),
    FIELD_INIT(parseNoExponent, &gIntOps),
    FIELD_INIT(parseCaseSensitive, &gIntOps),
    FIELD_INIT(outputCurrency, &gStrOps)
};

UBool
NumberFormatTestTuple::setField(
        ENumberFormatTestTupleField fieldId, 
        const UnicodeString &fieldValue,
        UErrorCode &status) {
    if (U_FAILURE(status)) {
        return FALSE;
    }
    if (fieldId == kNumberFormatTestTupleFieldCount) {
        status = U_ILLEGAL_ARGUMENT_ERROR;
        return FALSE;
    }
    gFieldData[fieldId].ops->toValue(
            fieldValue, getMutableFieldAddress(fieldId), status);
    if (U_FAILURE(status)) {
        return FALSE;
    }
    setFlag(fieldId, TRUE);
    return TRUE;
}

UBool
NumberFormatTestTuple::clearField(
        ENumberFormatTestTupleField fieldId, 
        UErrorCode &status) {
    if (U_FAILURE(status)) {
        return FALSE;
    }
    if (fieldId == kNumberFormatTestTupleFieldCount) {
        status = U_ILLEGAL_ARGUMENT_ERROR;
        return FALSE;
    }
    setFlag(fieldId, FALSE);
    return TRUE;
}

void
NumberFormatTestTuple::clear() {
    for (int32_t i = 0; i < kNumberFormatTestTupleFieldCount; ++i) {
        setFlag(i, FALSE);
    }
}

UnicodeString &
NumberFormatTestTuple::toString(
        UnicodeString &appendTo) const {
    appendTo.append("{");
    UBool first = TRUE;
    for (int32_t i = 0; i < kNumberFormatTestTupleFieldCount; ++i) {
        if (!isFlag(i)) {
            continue;
        }
        if (!first) {
            appendTo.append(", ");
        }
        first = FALSE;
        appendTo.append(gFieldData[i].name);
        appendTo.append(": ");
        gFieldData[i].ops->toString(getFieldAddress(i), appendTo);
    }
    appendTo.append("}");
    return appendTo;
}

ENumberFormatTestTupleField
NumberFormatTestTuple::getFieldByName(
        const UnicodeString &name) {
    CharString buffer;
    UErrorCode status = U_ZERO_ERROR;
    buffer.appendInvariantChars(name, status);
    if (U_FAILURE(status)) {
        return kNumberFormatTestTupleFieldCount;
    }
    int32_t result = -1;
    for (int32_t i = 0; i < UPRV_LENGTHOF(gFieldData); ++i) {
        if (uprv_strcmp(gFieldData[i].name, buffer.data()) == 0) {
            result = i;
            break;
        }
    }
    if (result == -1) {
        return kNumberFormatTestTupleFieldCount;
    }
    return (ENumberFormatTestTupleField) result;
}

const void *
NumberFormatTestTuple::getFieldAddress(int32_t fieldId) const {
    return reinterpret_cast<const char *>(this) + gFieldData[fieldId].offset;
}

void *
NumberFormatTestTuple::getMutableFieldAddress(int32_t fieldId) {
    return reinterpret_cast<char *>(this) + gFieldData[fieldId].offset;
}

void 
NumberFormatTestTuple::setFlag(int32_t fieldId, UBool value) {
    void *flagAddr = reinterpret_cast<char *>(this) + gFieldData[fieldId].flagOffset;
    *static_cast<UBool *>(flagAddr) = value;
}

UBool
NumberFormatTestTuple::isFlag(int32_t fieldId) const {
    const void *flagAddr = reinterpret_cast<const char *>(this) + gFieldData[fieldId].flagOffset;
    return *static_cast<const UBool *>(flagAddr);
}

#endif /* !UCONFIG_NO_FORMATTING */
