// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html

#include "unicode/utypes.h"

#if !UCONFIG_NO_FORMATTING

#include <set>

#include "unicode/formattedvalue.h"
#include "unicode/unum.h"
#include "unicode/udat.h"
#include "intltest.h"
#include "itformat.h"


class FormattedValueTest : public IntlTest {
public:
    void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par=0);
private:
    void testBasic();
    void testSetters();
    void testLocalPointer();

    void assertAllPartsEqual(
        UnicodeString messagePrefix,
        const ConstrainedFieldPosition& cfpos,
        int32_t matching,
        UFieldCategory category,
        int32_t field,
        int32_t start,
        int32_t limit,
        int64_t context);
};

void FormattedValueTest::runIndexedTest(int32_t index, UBool exec, const char *&name, char *) {
    if (exec) {
        logln("TestSuite FormattedValueTest: ");
    }
    TESTCASE_AUTO_BEGIN;
    TESTCASE_AUTO(testBasic);
    TESTCASE_AUTO(testSetters);
    TESTCASE_AUTO(testLocalPointer);
    TESTCASE_AUTO_END;
}


void FormattedValueTest::testBasic() {
    IcuTestErrorCode status(*this, "testBasic");
    ConstrainedFieldPosition cfpos;
    assertAllPartsEqual(
        u"basic",
        cfpos,
        7,
        UFIELD_CATEGORY_UNDEFINED,
        0,
        0,
        0,
        0LL);
}

void FormattedValueTest::testSetters() {
    IcuTestErrorCode status(*this, "testSetters");
    ConstrainedFieldPosition cfpos;

    cfpos.constrainCategory(UFIELD_CATEGORY_DATE);
    assertAllPartsEqual(
        u"setters 0",
        cfpos,
        4,
        UFIELD_CATEGORY_DATE,
        0,
        0,
        0,
        0LL);

    cfpos.constrainField(UFIELD_CATEGORY_NUMBER, UNUM_COMPACT_FIELD);
    assertAllPartsEqual(
        u"setters 1",
        cfpos,
        2,
        UFIELD_CATEGORY_NUMBER,
        UNUM_COMPACT_FIELD,
        0,
        0,
        0LL);

    cfpos.setInt64IterationContext(42424242424242LL);
    assertAllPartsEqual(
        u"setters 2",
        cfpos,
        2,
        UFIELD_CATEGORY_NUMBER,
        UNUM_COMPACT_FIELD,
        0,
        0,
        42424242424242LL);

    cfpos.setState(UFIELD_CATEGORY_NUMBER, UNUM_COMPACT_FIELD, 5, 10);
    assertAllPartsEqual(
        u"setters 3",
        cfpos,
        2,
        UFIELD_CATEGORY_NUMBER,
        UNUM_COMPACT_FIELD,
        5,
        10,
        42424242424242LL);

    cfpos.reset();
    assertAllPartsEqual(
        u"setters 4",
        cfpos,
        7,
        UFIELD_CATEGORY_UNDEFINED,
        0,
        0,
        0,
        0LL);
}

void FormattedValueTest::testLocalPointer() {
    UErrorCode status = U_ZERO_ERROR;
    LocalUConstrainedFieldPositionPointer ucfpos(ucfpos_open(&status));
    assertSuccess("Openining LocalUConstrainedFieldPositionPointer", status);
    assertEquals(u"Test that object is valid",
        0LL,
        ucfpos_getInt64IterationContext(ucfpos.getAlias(), &status));
    assertSuccess("Using LocalUConstrainedFieldPositionPointer", status);
}

/** For matching, turn on these bits:
 *
 * 1 = UNUM_INTEGER_FIELD
 * 2 = UNUM_COMPACT_FIELD
 * 4 = UDAT_AM_PM_FIELD
 */
void FormattedValueTest::assertAllPartsEqual(
        UnicodeString messagePrefix,
        const ConstrainedFieldPosition& cfpos,
        int32_t matching,
        UFieldCategory category,
        int32_t field,
        int32_t start,
        int32_t limit,
        int64_t context) {
    assertEquals(messagePrefix + u": category",
        category, cfpos.getCategory());
    assertEquals(messagePrefix + u": field",
        field, cfpos.getField());
    assertEquals(messagePrefix + u": start",
        start, cfpos.getStart());
    assertEquals(messagePrefix + u": limit",
        limit, cfpos.getLimit());
    assertEquals(messagePrefix + u": context",
        context, cfpos.getInt64IterationContext());

    assertEquals(messagePrefix + u": integer field",
        (UBool) ((matching & 1) != 0), cfpos.matchesField(UFIELD_CATEGORY_NUMBER, UNUM_INTEGER_FIELD));
    assertEquals(messagePrefix + u": compact field",
        (UBool) ((matching & 2) != 0), cfpos.matchesField(UFIELD_CATEGORY_NUMBER, UNUM_COMPACT_FIELD));
    assertEquals(messagePrefix + u": date field",
        (UBool) ((matching & 4) != 0), cfpos.matchesField(UFIELD_CATEGORY_DATE, UDAT_AM_PM_FIELD));
}


void IntlTestWithFieldPosition::checkFormattedValue(
        const char16_t* message,
        const FormattedValue& fv,
        UnicodeString expectedString,
        UFieldCategory expectedCategory,
        const UFieldPosition* expectedFieldPositions,
        int32_t length) {
    LocalArray<UFieldPositionWithCategory> converted(new UFieldPositionWithCategory[length]);
    for (int32_t i=0; i<length; i++) {
        converted[i].category = expectedCategory;
        converted[i].field = expectedFieldPositions[i].field;
        converted[i].beginIndex = expectedFieldPositions[i].beginIndex;
        converted[i].endIndex = expectedFieldPositions[i].endIndex;
    }
    checkMixedFormattedValue(message, fv, expectedString, converted.getAlias(), length);
}


UnicodeString CFPosToUnicodeString(const ConstrainedFieldPosition& cfpos) {
    UnicodeString sb;
    sb.append(u"CFPos[");
    sb.append(Int64ToUnicodeString(cfpos.getStart()));
    sb.append(u'-');
    sb.append(Int64ToUnicodeString(cfpos.getLimit()));
    sb.append(u' ');
    sb.append(Int64ToUnicodeString(cfpos.getCategory()));
    sb.append(u':');
    sb.append(Int64ToUnicodeString(cfpos.getField()));
    sb.append(u']');
    return sb;
}


void IntlTestWithFieldPosition::checkMixedFormattedValue(
        const char16_t* message,
        const FormattedValue& fv,
        UnicodeString expectedString,
        const UFieldPositionWithCategory* expectedFieldPositions,
        int32_t length) {
    IcuTestErrorCode status(*this, "checkMixedFormattedValue");
    UnicodeString baseMessage = UnicodeString(message) + u": " + fv.toString(status) + u": ";

    // Check string values
    assertEquals(baseMessage + u"string", expectedString, fv.toString(status));
    assertEquals(baseMessage + u"temp string", expectedString, fv.toTempString(status));

    // The temp string is guaranteed to be NUL-terminated
    UnicodeString readOnlyAlias = fv.toTempString(status);
    if (!status.errIfFailureAndReset()) {
        assertEquals(baseMessage + u"NUL-terminated",
            0, readOnlyAlias.getBuffer()[readOnlyAlias.length()]);
    }

    // Check nextPosition over all fields
    ConstrainedFieldPosition cfpos;
    for (int32_t i = 0; i < length; i++) {
        assertTrue(baseMessage + u"A has next position @ " + Int64ToUnicodeString(i),
            fv.nextPosition(cfpos, status));
        int32_t expectedCategory = expectedFieldPositions[i].category;
        int32_t expectedField = expectedFieldPositions[i].field;
        int32_t expectedStart = expectedFieldPositions[i].beginIndex;
        int32_t expectedLimit = expectedFieldPositions[i].endIndex;
        assertEquals(baseMessage + u"A category @ " + Int64ToUnicodeString(i),
            expectedCategory, cfpos.getCategory());
        assertEquals(baseMessage + u"A field @ " + Int64ToUnicodeString(i),
            expectedField, cfpos.getField());
        assertEquals(baseMessage + u"A start @ " + Int64ToUnicodeString(i),
            expectedStart, cfpos.getStart());
        assertEquals(baseMessage + u"A limit @ " + Int64ToUnicodeString(i),
            expectedLimit, cfpos.getLimit());
    }
    UBool afterLoopResult = fv.nextPosition(cfpos, status);
    assertFalse(baseMessage + u"A after loop: " + CFPosToUnicodeString(cfpos), afterLoopResult);
    afterLoopResult = fv.nextPosition(cfpos, status);
    assertFalse(baseMessage + u"A after loop again: " + CFPosToUnicodeString(cfpos), afterLoopResult);

    // Check nextPosition constrained over each category one at a time
    for (int32_t category=0; category<UFIELD_CATEGORY_COUNT+1; category++) {
        if (category == UFIELD_CATEGORY_COUNT+1) {
            category = UFIELD_CATEGORY_LIST_SPAN;
        }
        cfpos.reset();
        cfpos.constrainCategory(static_cast<UFieldCategory>(category));
        for (int32_t i = 0; i < length; i++) {
            if (expectedFieldPositions[i].category != category) {
                continue;
            }
            assertTrue(baseMessage + u"B has next position @ " + Int64ToUnicodeString(i),
                fv.nextPosition(cfpos, status));
            int32_t expectedCategory = expectedFieldPositions[i].category;
            int32_t expectedField = expectedFieldPositions[i].field;
            int32_t expectedStart = expectedFieldPositions[i].beginIndex;
            int32_t expectedLimit = expectedFieldPositions[i].endIndex;
            assertEquals(baseMessage + u"B category @ " + Int64ToUnicodeString(i),
                expectedCategory, cfpos.getCategory());
            assertEquals(baseMessage + u"B field @ " + Int64ToUnicodeString(i),
                expectedField, cfpos.getField());
            assertEquals(baseMessage + u"B start @ " + Int64ToUnicodeString(i),
                expectedStart, cfpos.getStart());
            assertEquals(baseMessage + u"B limit @ " + Int64ToUnicodeString(i),
                expectedLimit, cfpos.getLimit());
        }
        UBool afterLoopResult = fv.nextPosition(cfpos, status);
        assertFalse(baseMessage + u"B after loop @ " + CFPosToUnicodeString(cfpos), afterLoopResult);
        afterLoopResult = fv.nextPosition(cfpos, status);
        assertFalse(baseMessage + u"B after loop again @ " + CFPosToUnicodeString(cfpos), afterLoopResult);
    }

    // Check nextPosition constrained over each field one at a time
    std::set<std::pair<UFieldCategory, int32_t>> uniqueFields;
    for (int32_t i = 0; i < length; i++) {
        uniqueFields.insert({expectedFieldPositions[i].category, expectedFieldPositions[i].field});
    }
    for (std::pair<UFieldCategory, int32_t> categoryAndField : uniqueFields) {
        cfpos.reset();
        cfpos.constrainField(categoryAndField.first, categoryAndField.second);
        for (int32_t i = 0; i < length; i++) {
            if (expectedFieldPositions[i].category != categoryAndField.first) {
                continue;
            }
            if (expectedFieldPositions[i].field != categoryAndField.second) {
                continue;
            }
            assertTrue(baseMessage + u"C has next position @ " + Int64ToUnicodeString(i),
                fv.nextPosition(cfpos, status));
            int32_t expectedCategory = expectedFieldPositions[i].category;
            int32_t expectedField = expectedFieldPositions[i].field;
            int32_t expectedStart = expectedFieldPositions[i].beginIndex;
            int32_t expectedLimit = expectedFieldPositions[i].endIndex;
            assertEquals(baseMessage + u"C category @ " + Int64ToUnicodeString(i),
                expectedCategory, cfpos.getCategory());
            assertEquals(baseMessage + u"C field @ " + Int64ToUnicodeString(i),
                expectedField, cfpos.getField());
            assertEquals(baseMessage + u"C start @ " + Int64ToUnicodeString(i),
                expectedStart, cfpos.getStart());
            assertEquals(baseMessage + u"C limit @ " + Int64ToUnicodeString(i),
                expectedLimit, cfpos.getLimit());
        }
        UBool afterLoopResult = fv.nextPosition(cfpos, status);
        assertFalse(baseMessage + u"C after loop: " + CFPosToUnicodeString(cfpos), afterLoopResult);
        afterLoopResult = fv.nextPosition(cfpos, status);
        assertFalse(baseMessage + u"C after loop again: " + CFPosToUnicodeString(cfpos), afterLoopResult);
    }
}


extern IntlTest *createFormattedValueTest() {
    return new FormattedValueTest();
}

#endif /* !UCONFIG_NO_FORMATTING */
