// © 2017 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 "unicode/utf16.h"
#include "putilimp.h"
#include "intltest.h"
#include "formatted_string_builder.h"
#include "formattedval_impl.h"
#include "unicode/unum.h"


class FormattedStringBuilderTest : public IntlTest {
  public:
    void testInsertAppendUnicodeString();
    void testSplice();
    void testInsertAppendCodePoint();
    void testCopy();
    void testFields();
    void testUnlimitedCapacity();
    void testCodePoints();

    void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0);

  private:
    void assertEqualsImpl(const UnicodeString &a, const FormattedStringBuilder &b);
};

static const char16_t *EXAMPLE_STRINGS[] = {
        u"",
        u"xyz",
        u"The quick brown fox jumps over the lazy dog",
        u"😁",
        u"mixed 😇 and ASCII",
        u"with combining characters like 🇦🇧🇨🇩",
        u"A very very very very very very very very very very long string to force heap"};

void FormattedStringBuilderTest::runIndexedTest(int32_t index, UBool exec, const char *&name, char *) {
    if (exec) {
        logln("TestSuite FormattedStringBuilderTest: ");
    }
    TESTCASE_AUTO_BEGIN;
        TESTCASE_AUTO(testInsertAppendUnicodeString);
        TESTCASE_AUTO(testSplice);
        TESTCASE_AUTO(testInsertAppendCodePoint);
        TESTCASE_AUTO(testCopy);
        TESTCASE_AUTO(testFields);
        TESTCASE_AUTO(testUnlimitedCapacity);
        TESTCASE_AUTO(testCodePoints);
    TESTCASE_AUTO_END;
}

void FormattedStringBuilderTest::testInsertAppendUnicodeString() {
    UErrorCode status = U_ZERO_ERROR;
    UnicodeString sb1;
    FormattedStringBuilder sb2;
    for (const char16_t* strPtr : EXAMPLE_STRINGS) {
        UnicodeString str(strPtr);

        FormattedStringBuilder sb3;
        sb1.append(str);
        sb2.append(str, kUndefinedField, status);
        assertSuccess("Appending to sb2", status);
        sb3.append(str, kUndefinedField, status);
        assertSuccess("Appending to sb3", status);
        assertEqualsImpl(sb1, sb2);
        assertEqualsImpl(str, sb3);

        UnicodeString sb4;
        FormattedStringBuilder sb5;
        sb4.append(u"😇");
        sb4.append(str);
        sb4.append(u"xx");
        sb5.append(u"😇xx", kUndefinedField, status);
        assertSuccess("Appending to sb5", status);
        sb5.insert(2, str, kUndefinedField, status);
        assertSuccess("Inserting into sb5", status);
        assertEqualsImpl(sb4, sb5);

        int start = uprv_min(1, str.length());
        int end = uprv_min(10, str.length());
        sb4.insert(3, str, start, end - start); // UnicodeString uses length instead of end index
        sb5.insert(3, str, start, end, kUndefinedField, status);
        assertSuccess("Inserting into sb5 again", status);
        assertEqualsImpl(sb4, sb5);

        UnicodeString sb4cp(sb4);
        FormattedStringBuilder sb5cp(sb5);
        sb4.append(sb4cp);
        sb5.append(sb5cp, status);
        assertSuccess("Appending again to sb5", status);
        assertEqualsImpl(sb4, sb5);
    }
}

void FormattedStringBuilderTest::testSplice() {
    static const struct TestCase {
        const char16_t* input;
        const int32_t startThis;
        const int32_t endThis;
    } cases[] = {
            { u"", 0, 0 },
            { u"abc", 0, 0 },
            { u"abc", 1, 1 },
            { u"abc", 1, 2 },
            { u"abc", 0, 2 },
            { u"abc", 0, 3 },
            { u"lorem ipsum dolor sit amet", 8, 8 },
            { u"lorem ipsum dolor sit amet", 8, 11 }, // 3 chars, equal to replacement "xyz"
            { u"lorem ipsum dolor sit amet", 8, 18 } }; // 10 chars, larger than several replacements

    UErrorCode status = U_ZERO_ERROR;
    UnicodeString sb1;
    FormattedStringBuilder sb2;
    for (auto cas : cases) {
        for (const char16_t* replacementPtr : EXAMPLE_STRINGS) {
            UnicodeString replacement(replacementPtr);

            // Test replacement with full string
            sb1.remove();
            sb1.append(cas.input);
            sb1.replace(cas.startThis, cas.endThis - cas.startThis, replacement);
            sb2.clear();
            sb2.append(cas.input, kUndefinedField, status);
            sb2.splice(cas.startThis, cas.endThis, replacement, 0, replacement.length(), kUndefinedField, status);
            assertSuccess("Splicing into sb2 first time", status);
            assertEqualsImpl(sb1, sb2);

            // Test replacement with partial string
            if (replacement.length() <= 2) {
                continue;
            }
            sb1.remove();
            sb1.append(cas.input);
            sb1.replace(cas.startThis, cas.endThis - cas.startThis, UnicodeString(replacement, 1, 2));
            sb2.clear();
            sb2.append(cas.input, kUndefinedField, status);
            sb2.splice(cas.startThis, cas.endThis, replacement, 1, 3, kUndefinedField, status);
            assertSuccess("Splicing into sb2 second time", status);
            assertEqualsImpl(sb1, sb2);
        }
    }
}

void FormattedStringBuilderTest::testInsertAppendCodePoint() {
    static const UChar32 cases[] = {
            0, 1, 60, 127, 128, 0x7fff, 0x8000, 0xffff, 0x10000, 0x1f000, 0x10ffff};
    UErrorCode status = U_ZERO_ERROR;
    UnicodeString sb1;
    FormattedStringBuilder sb2;
    for (UChar32 cas : cases) {
        FormattedStringBuilder sb3;
        sb1.append(cas);
        sb2.appendCodePoint(cas, kUndefinedField, status);
        assertSuccess("Appending to sb2", status);
        sb3.appendCodePoint(cas, kUndefinedField, status);
        assertSuccess("Appending to sb3", status);
        assertEqualsImpl(sb1, sb2);
        assertEquals("Length of sb3", U16_LENGTH(cas), sb3.length());
        assertEquals("Code point count of sb3", 1, sb3.codePointCount());
        assertEquals(
                "First code unit in sb3",
                !U_IS_SUPPLEMENTARY(cas) ? (char16_t) cas : U16_LEAD(cas),
                sb3.charAt(0));

        UnicodeString sb4;
        FormattedStringBuilder sb5;
        sb4.append(u"😇xx");
        sb4.insert(2, cas);
        sb5.append(u"😇xx", kUndefinedField, status);
        assertSuccess("Appending to sb5", status);
        sb5.insertCodePoint(2, cas, kUndefinedField, status);
        assertSuccess("Inserting into sb5", status);
        assertEqualsImpl(sb4, sb5);

        UnicodeString sb6;
        FormattedStringBuilder sb7;
        sb6.append(cas);
        if (U_IS_SUPPLEMENTARY(cas)) {
            sb7.appendChar16(U16_TRAIL(cas), kUndefinedField, status);
            sb7.insertChar16(0, U16_LEAD(cas), kUndefinedField, status);
        } else {
            sb7.insertChar16(0, cas, kUndefinedField, status);
        }
        assertSuccess("Insert/append into sb7", status);
        assertEqualsImpl(sb6, sb7);
    }
}

void FormattedStringBuilderTest::testCopy() {
    UErrorCode status = U_ZERO_ERROR;
    for (UnicodeString str : EXAMPLE_STRINGS) {
        FormattedStringBuilder sb1;
        sb1.append(str, kUndefinedField, status);
        assertSuccess("Appending to sb1 first time", status);
        FormattedStringBuilder sb2(sb1);
        assertTrue("Content should equal itself", sb1.contentEquals(sb2));

        sb1.append("12345", kUndefinedField, status);
        assertSuccess("Appending to sb1 second time", status);
        assertFalse("Content should no longer equal itself", sb1.contentEquals(sb2));
    }
}

void FormattedStringBuilderTest::testFields() {
    typedef FormattedStringBuilder::Field Field;
    UErrorCode status = U_ZERO_ERROR;
    // Note: This is a C++11 for loop that calls the UnicodeString constructor on each iteration.
    for (UnicodeString str : EXAMPLE_STRINGS) {
        FormattedValueStringBuilderImpl sbi(kUndefinedField);
        FormattedStringBuilder& sb = sbi.getStringRef();
        sb.append(str, kUndefinedField, status);
        assertSuccess("Appending to sb", status);
        sb.append(str, {UFIELD_CATEGORY_NUMBER, UNUM_CURRENCY_FIELD}, status);
        assertSuccess("Appending to sb", status);
        assertEquals("Reference string copied twice", str.length() * 2, sb.length());
        for (int32_t i = 0; i < str.length(); i++) {
            assertEquals("Null field first",
                kUndefinedField.bits, sb.fieldAt(i).bits);
            assertEquals("Currency field second",
                Field(UFIELD_CATEGORY_NUMBER, UNUM_CURRENCY_FIELD).bits,
                sb.fieldAt(i + str.length()).bits);
        }

        // Very basic FieldPosition test. More robust tests happen in NumberFormatTest.
        // Let NumberFormatTest also take care of FieldPositionIterator material.
        FieldPosition fp(UNUM_CURRENCY_FIELD);
        sbi.nextFieldPosition(fp, status);
        assertSuccess("Populating the FieldPosition", status);
        assertEquals("Currency start position", str.length(), fp.getBeginIndex());
        assertEquals("Currency end position", str.length() * 2, fp.getEndIndex());

        if (str.length() > 0) {
            sb.insertCodePoint(2, 100, {UFIELD_CATEGORY_NUMBER, UNUM_INTEGER_FIELD}, status);
            assertSuccess("Inserting code point into sb", status);
            assertEquals("New length", str.length() * 2 + 1, sb.length());
            assertEquals("Integer field",
                Field(UFIELD_CATEGORY_NUMBER, UNUM_INTEGER_FIELD).bits,
                sb.fieldAt(2).bits);
        }

        FormattedStringBuilder old(sb);
        sb.append(old, status);
        assertSuccess("Appending to myself", status);
        int32_t numNull = 0;
        int32_t numCurr = 0;
        int32_t numInt = 0;
        for (int32_t i = 0; i < sb.length(); i++) {
            auto field = sb.fieldAt(i);
            assertEquals("Field should equal location in old",
                old.fieldAt(i % old.length()).bits, field.bits);
            if (field == kUndefinedField) {
                numNull++;
            } else if (field == Field(UFIELD_CATEGORY_NUMBER, UNUM_CURRENCY_FIELD)) {
                numCurr++;
            } else if (field == Field(UFIELD_CATEGORY_NUMBER, UNUM_INTEGER_FIELD)) {
                numInt++;
            } else {
                errln("Encountered unknown field");
            }
        }
        assertEquals("Number of null fields", str.length() * 2, numNull);
        assertEquals("Number of currency fields", numNull, numCurr);
        assertEquals("Number of integer fields", str.length() > 0 ? 2 : 0, numInt);
    }
}

void FormattedStringBuilderTest::testUnlimitedCapacity() {
    UErrorCode status = U_ZERO_ERROR;
    FormattedStringBuilder builder;
    // The builder should never fail upon repeated appends.
    for (int i = 0; i < 1000; i++) {
        UnicodeString message("Iteration #");
        message += Int64ToUnicodeString(i);
        assertEquals(message, builder.length(), i);
        builder.appendCodePoint(u'x', kUndefinedField, status);
        assertSuccess(message, status);
        assertEquals(message, builder.length(), i + 1);
    }
}

void FormattedStringBuilderTest::testCodePoints() {
    UErrorCode status = U_ZERO_ERROR;
    FormattedStringBuilder nsb;
    assertEquals("First is -1 on empty string", -1, nsb.getFirstCodePoint());
    assertEquals("Last is -1 on empty string", -1, nsb.getLastCodePoint());
    assertEquals("Length is 0 on empty string", 0, nsb.codePointCount());

    nsb.append(u"q", kUndefinedField, status);
    assertSuccess("Spot 1", status);
    assertEquals("First is q", u'q', nsb.getFirstCodePoint());
    assertEquals("Last is q", u'q', nsb.getLastCodePoint());
    assertEquals("0th is q", u'q', nsb.codePointAt(0));
    assertEquals("Before 1st is q", u'q', nsb.codePointBefore(1));
    assertEquals("Code point count is 1", 1, nsb.codePointCount());

    // 🚀 is two char16s
    nsb.append(u"🚀", kUndefinedField, status);
    assertSuccess("Spot 2" ,status);
    assertEquals("First is still q", u'q', nsb.getFirstCodePoint());
    assertEquals("Last is space ship", 128640, nsb.getLastCodePoint());
    assertEquals("1st is space ship", 128640, nsb.codePointAt(1));
    assertEquals("Before 1st is q", u'q', nsb.codePointBefore(1));
    assertEquals("Before 3rd is space ship", 128640, nsb.codePointBefore(3));
    assertEquals("Code point count is 2", 2, nsb.codePointCount());
}

void FormattedStringBuilderTest::assertEqualsImpl(const UnicodeString &a, const FormattedStringBuilder &b) {
    // TODO: Why won't this compile without the IntlTest:: qualifier?
    IntlTest::assertEquals("Lengths should be the same", a.length(), b.length());
    IntlTest::assertEquals("Code point counts should be the same", a.countChar32(), b.codePointCount());

    if (a.length() != b.length()) {
        return;
    }

    for (int32_t i = 0; i < a.length(); i++) {
        IntlTest::assertEquals(
                UnicodeString(u"Char at position ") + Int64ToUnicodeString(i) +
                UnicodeString(u" in \"") + a + UnicodeString("\" versus \"") +
                b.toUnicodeString() + UnicodeString("\""), a.charAt(i), b.charAt(i));
    }
}


extern IntlTest *createFormattedStringBuilderTest() {
    return new FormattedStringBuilderTest();
}

#endif /* #if !UCONFIG_NO_FORMATTING */
