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

#include "unicode/utypes.h"

#if !UCONFIG_NO_FORMATTING

// Allow implicit conversion from char16_t* to UnicodeString for this file:
// Helpful in toString methods and elsewhere.
#define UNISTR_FROM_STRING_EXPLICIT

#include <stdio.h>
#include "unicode/unumberformatter.h"
#include "unicode/umisc.h"
#include "unicode/unum.h"
#include "unicode/ustring.h"
#include "cformtst.h"
#include "cintltst.h"
#include "cmemory.h"

static void TestSkeletonFormatToString(void);

static void TestSkeletonFormatToFields(void);

static void TestExampleCode(void);

static void TestFormattedValue(void);

static void TestSkeletonParseError(void);

static void TestToDecimalNumber(void);

static void TestPerUnitInArabic(void);

void addUNumberFormatterTest(TestNode** root);

#define TESTCASE(x) addTest(root, &x, "tsformat/unumberformatter/" #x)

void addUNumberFormatterTest(TestNode** root) {
    TESTCASE(TestSkeletonFormatToString);
    TESTCASE(TestSkeletonFormatToFields);
    TESTCASE(TestExampleCode);
    TESTCASE(TestFormattedValue);
    TESTCASE(TestSkeletonParseError);
    TESTCASE(TestToDecimalNumber);
    TESTCASE(TestPerUnitInArabic);
}


#define CAPACITY 30

static void TestSkeletonFormatToString() {
    UErrorCode ec = U_ZERO_ERROR;
    UChar buffer[CAPACITY];
    UFormattedNumber* result = NULL;

    // setup:
    UNumberFormatter* f = unumf_openForSkeletonAndLocale(
                              u"precision-integer currency/USD sign-accounting", -1, "en", &ec);
    assertSuccessCheck("Should create without error", &ec, TRUE);
    result = unumf_openResult(&ec);
    assertSuccess("Should create result without error", &ec);

    // int64 test:
    unumf_formatInt(f, -444444, result, &ec);
    // Missing data will give a U_MISSING_RESOURCE_ERROR here.
    if (assertSuccessCheck("Should format integer without error", &ec, TRUE)) {
        unumf_resultToString(result, buffer, CAPACITY, &ec);
        assertSuccess("Should print string to buffer without error", &ec);
        assertUEquals("Should produce expected string result", u"($444,444)", buffer);

        // double test:
        unumf_formatDouble(f, -5142.3, result, &ec);
        assertSuccess("Should format double without error", &ec);
        unumf_resultToString(result, buffer, CAPACITY, &ec);
        assertSuccess("Should print string to buffer without error", &ec);
        assertUEquals("Should produce expected string result", u"($5,142)", buffer);

        // decnumber test:
        unumf_formatDecimal(f, "9.876E2", -1, result, &ec);
        assertSuccess("Should format decimal without error", &ec);
        unumf_resultToString(result, buffer, CAPACITY, &ec);
        assertSuccess("Should print string to buffer without error", &ec);
        assertUEquals("Should produce expected string result", u"$988", buffer);
    }

    // cleanup:
    unumf_closeResult(result);
    unumf_close(f);
}


static void TestSkeletonFormatToFields() {
    UErrorCode ec = U_ZERO_ERROR;
    UFieldPositionIterator* ufpositer = NULL;

    // setup:
    UNumberFormatter* uformatter = unumf_openForSkeletonAndLocale(
            u".00 measure-unit/length-meter sign-always", -1, "en", &ec);
    assertSuccessCheck("Should create without error", &ec, TRUE);
    UFormattedNumber* uresult = unumf_openResult(&ec);
    assertSuccess("Should create result without error", &ec);
    unumf_formatInt(uformatter, 9876543210L, uresult, &ec); // "+9,876,543,210.00 m"
    if (assertSuccessCheck("unumf_formatInt() failed", &ec, TRUE)) {

        // field position test:
        UFieldPosition ufpos = {UNUM_DECIMAL_SEPARATOR_FIELD, 0, 0};
        unumf_resultNextFieldPosition(uresult, &ufpos, &ec);
        assertIntEquals("Field position should be correct", 14, ufpos.beginIndex);
        assertIntEquals("Field position should be correct", 15, ufpos.endIndex);

        // field position iterator test:
        ufpositer = ufieldpositer_open(&ec);
        if (assertSuccessCheck("Should create iterator without error", &ec, TRUE)) {

            unumf_resultGetAllFieldPositions(uresult, ufpositer, &ec);
            static const UFieldPosition expectedFields[] = {
                // Field, begin index, end index
                {UNUM_SIGN_FIELD, 0, 1},
                {UNUM_GROUPING_SEPARATOR_FIELD, 2, 3},
                {UNUM_GROUPING_SEPARATOR_FIELD, 6, 7},
                {UNUM_GROUPING_SEPARATOR_FIELD, 10, 11},
                {UNUM_INTEGER_FIELD, 1, 14},
                {UNUM_DECIMAL_SEPARATOR_FIELD, 14, 15},
                {UNUM_FRACTION_FIELD, 15, 17},
                {UNUM_MEASURE_UNIT_FIELD, 18, 19}
            };
            UFieldPosition actual;
            for (int32_t i = 0; i < (int32_t)(sizeof(expectedFields) / sizeof(*expectedFields)); i++) {
                // Iterate using the UFieldPosition to hold state...
                UFieldPosition expected = expectedFields[i];
                actual.field = ufieldpositer_next(ufpositer, &actual.beginIndex, &actual.endIndex);
                assertTrue("Should not return a negative index yet", actual.field >= 0);
                if (expected.field != actual.field) {
                    log_err(
                        "FAIL: iteration %d; expected field %d; got %d\n", i, expected.field, actual.field);
                }
                if (expected.beginIndex != actual.beginIndex) {
                    log_err(
                        "FAIL: iteration %d; expected beginIndex %d; got %d\n",
                        i,
                        expected.beginIndex,
                        actual.beginIndex);
                }
                if (expected.endIndex != actual.endIndex) {
                    log_err(
                        "FAIL: iteration %d; expected endIndex %d; got %d\n",
                        i,
                        expected.endIndex,
                        actual.endIndex);
                }
            }
            actual.field = ufieldpositer_next(ufpositer, &actual.beginIndex, &actual.endIndex);
            assertTrue("No more fields; should return a negative index", actual.field < 0);

            // next field iteration:
            actual.field = UNUM_GROUPING_SEPARATOR_FIELD;
            actual.beginIndex = 0;
            actual.endIndex = 0;
            int32_t i = 1;
            while (unumf_resultNextFieldPosition(uresult, &actual, &ec)) {
                UFieldPosition expected = expectedFields[i++];
                assertIntEquals("Grouping separator begin index", expected.beginIndex, actual.beginIndex);
                assertIntEquals("Grouping separator end index", expected.endIndex, actual.endIndex);
            }
            assertIntEquals("Should have seen all grouping separators", 4, i);
        }
    }

    // cleanup:
    unumf_closeResult(uresult);
    unumf_close(uformatter);
    ufieldpositer_close(ufpositer);
}


static void TestExampleCode() {
    // This is the example code given in unumberformatter.h.

    // Setup:
    UErrorCode ec = U_ZERO_ERROR;
    UNumberFormatter* uformatter = unumf_openForSkeletonAndLocale(u"precision-integer", -1, "en", &ec);
    UFormattedNumber* uresult = unumf_openResult(&ec);
    UChar* buffer = NULL;
    assertSuccessCheck("There should not be a failure in the example code", &ec, TRUE);

    // Format a double:
    unumf_formatDouble(uformatter, 5142.3, uresult, &ec);
    if (assertSuccessCheck("There should not be a failure in the example code", &ec, TRUE)) {

        // Export the string to a malloc'd buffer:
        int32_t len = unumf_resultToString(uresult, NULL, 0, &ec);
        assertTrue("No buffer yet", ec == U_BUFFER_OVERFLOW_ERROR);
        ec = U_ZERO_ERROR;
        buffer = (UChar*) uprv_malloc((len+1)*sizeof(UChar));
        unumf_resultToString(uresult, buffer, len+1, &ec);
        assertSuccess("There should not be a failure in the example code", &ec);
        assertUEquals("Should produce expected string result", u"5,142", buffer);
    }

    // Cleanup:
    unumf_close(uformatter);
    unumf_closeResult(uresult);
    uprv_free(buffer);
}


static void TestFormattedValue() {
    UErrorCode ec = U_ZERO_ERROR;
    UNumberFormatter* uformatter = unumf_openForSkeletonAndLocale(
            u".00 compact-short", -1, "en", &ec);
    assertSuccessCheck("Should create without error", &ec, TRUE);
    UFormattedNumber* uresult = unumf_openResult(&ec);
    assertSuccess("Should create result without error", &ec);

    unumf_formatInt(uformatter, 55000, uresult, &ec); // "55.00 K"
    if (assertSuccessCheck("Should format without error", &ec, TRUE)) {
        const UFormattedValue* fv = unumf_resultAsValue(uresult, &ec);
        assertSuccess("Should convert without error", &ec);
        static const UFieldPosition expectedFieldPositions[] = {
            // field, begin index, end index
            {UNUM_INTEGER_FIELD, 0, 2},
            {UNUM_DECIMAL_SEPARATOR_FIELD, 2, 3},
            {UNUM_FRACTION_FIELD, 3, 5},
            {UNUM_COMPACT_FIELD, 5, 6}};
        checkFormattedValue(
            "FormattedNumber as FormattedValue",
            fv,
            u"55.00K",
            UFIELD_CATEGORY_NUMBER,
            expectedFieldPositions,
            UPRV_LENGTHOF(expectedFieldPositions));
    }

    // cleanup:
    unumf_closeResult(uresult);
    unumf_close(uformatter);
}


static void TestSkeletonParseError() {
    UErrorCode ec = U_ZERO_ERROR;
    UNumberFormatter* uformatter;
    UParseError perror;

    // The UParseError can be null. The following should not segfault.
    uformatter = unumf_openForSkeletonAndLocaleWithError(
            u".00 measure-unit/typo", -1, "en", NULL, &ec);
    unumf_close(uformatter);

    // Now test the behavior.
    ec = U_ZERO_ERROR;
    uformatter = unumf_openForSkeletonAndLocaleWithError(
            u".00 measure-unit/typo", -1, "en", &perror, &ec);

    assertIntEquals("Should have set error code", U_NUMBER_SKELETON_SYNTAX_ERROR, ec);
    assertIntEquals("Should have correct skeleton error offset", 17, perror.offset);
    assertUEquals("Should have correct pre context", u"0 measure-unit/", perror.preContext);
    assertUEquals("Should have correct post context", u"typo", perror.postContext);

    // cleanup:
    unumf_close(uformatter);
}


static void TestToDecimalNumber() {
    UErrorCode ec = U_ZERO_ERROR;
    UNumberFormatter* uformatter = unumf_openForSkeletonAndLocale(
        u"currency/USD",
        -1,
        "en-US",
        &ec);
    assertSuccessCheck("Should create without error", &ec, TRUE);
    UFormattedNumber* uresult = unumf_openResult(&ec);
    assertSuccess("Should create result without error", &ec);

    unumf_formatDouble(uformatter, 3.0, uresult, &ec);
    const UChar* str = ufmtval_getString(unumf_resultAsValue(uresult, &ec), NULL, &ec);
    assertSuccessCheck("Formatting should succeed", &ec, TRUE);
    assertUEquals("Should produce expected string result", u"$3.00", str);

    char buffer[CAPACITY];

    int32_t len = unumf_resultToDecimalNumber(uresult, buffer, CAPACITY, &ec);
    assertIntEquals("Length should be as expected", strlen(buffer), len);
    assertEquals("Decimal should be as expected", "3", buffer);

    // cleanup:
    unumf_closeResult(uresult);
    unumf_close(uformatter);
}


static void TestPerUnitInArabic() {
    const char* simpleMeasureUnits[] = {
        "area-acre",
        "digital-bit",
        "digital-byte",
        "temperature-celsius",
        "length-centimeter",
        "duration-day",
        "angle-degree",
        "temperature-fahrenheit",
        "volume-fluid-ounce",
        "length-foot",
        "volume-gallon",
        "digital-gigabit",
        "digital-gigabyte",
        "mass-gram",
        "area-hectare",
        "duration-hour",
        "length-inch",
        "digital-kilobit",
        "digital-kilobyte",
        "mass-kilogram",
        "length-kilometer",
        "volume-liter",
        "digital-megabit",
        "digital-megabyte",
        "length-meter",
        "length-mile",
        "length-mile-scandinavian",
        "volume-milliliter",
        "length-millimeter",
        "duration-millisecond",
        "duration-minute",
        "duration-month",
        "mass-ounce",
        "concentr-percent",
        "digital-petabyte",
        "mass-pound",
        "duration-second",
        "mass-stone",
        "digital-terabit",
        "digital-terabyte",
        "duration-week",
        "length-yard",
        "duration-year"
    };
#define BUFFER_LEN 256
    char buffer[BUFFER_LEN];
    UChar ubuffer[BUFFER_LEN];
    const char* locale = "ar";
    UErrorCode status = U_ZERO_ERROR;
    UFormattedNumber* formatted = unumf_openResult(&status);
    if (U_FAILURE(status)) {
        log_err("FAIL: unumf_openResult failed");
        return;
    }
    for(int32_t i=0; i < UPRV_LENGTHOF(simpleMeasureUnits); ++i) {
        for(int32_t j=0; j < UPRV_LENGTHOF(simpleMeasureUnits); ++j) {
            status = U_ZERO_ERROR;
            sprintf(buffer, "measure-unit/%s per-measure-unit/%s",
                    simpleMeasureUnits[i], simpleMeasureUnits[j]);
            int32_t outputlen = 0;
            u_strFromUTF8(ubuffer, BUFFER_LEN, &outputlen, buffer, (int32_t)strlen(buffer), &status);
            if (U_FAILURE(status)) {
                log_err("FAIL u_strFromUTF8: %s = %s ( %s )\n", locale, buffer,
                        u_errorName(status));
            }
            UNumberFormatter* nf = unumf_openForSkeletonAndLocale(
                ubuffer, outputlen, locale, &status);
            if (U_FAILURE(status)) {
                log_err("FAIL unumf_openForSkeletonAndLocale: %s = %s ( %s )\n",
                        locale, buffer, u_errorName(status));
            } else {
                unumf_formatDouble(nf, 1, formatted, &status);
                if (U_FAILURE(status)) {
                    log_err("FAIL unumf_formatDouble: %s = %s ( %s )\n",
                            locale, buffer, u_errorName(status));
                }
            }
            unumf_close(nf);
        }
    }
    unumf_closeResult(formatted);
}
#endif /* #if !UCONFIG_NO_FORMATTING */
