// © 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/unumberrangeformatter.h"
#include "unicode/umisc.h"
#include "unicode/unum.h"
#include "unicode/ustring.h"
#include "cformtst.h"
#include "cintltst.h"
#include "cmemory.h"

static void TestExampleCode(void);

static void TestFormattedValue(void);

static void TestSkeletonParseError(void);

static void TestGetDecimalNumbers(void);

void addUNumberRangeFormatterTest(TestNode** root);

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

void addUNumberRangeFormatterTest(TestNode** root) {
    TESTCASE(TestExampleCode);
    TESTCASE(TestFormattedValue);
    TESTCASE(TestSkeletonParseError);
    TESTCASE(TestGetDecimalNumbers);
}


#define CAPACITY 30


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

    // Setup:
    UErrorCode ec = U_ZERO_ERROR;
    UNumberRangeFormatter* uformatter = unumrf_openForSkeletonWithCollapseAndIdentityFallback(
        u"currency/USD precision-integer",
        -1,
        UNUM_RANGE_COLLAPSE_AUTO,
        UNUM_IDENTITY_FALLBACK_APPROXIMATELY,
        "en-US",
        NULL,
        &ec);
    UFormattedNumberRange* uresult = unumrf_openResult(&ec);
    assertSuccessCheck("There should not be a failure in the example code", &ec, TRUE);

    // Format a double range:
    unumrf_formatDoubleRange(uformatter, 3.0, 5.0, uresult, &ec);
    assertSuccessCheck("There should not be a failure in the example code", &ec, TRUE);

    // Get the result string:
    int32_t len;
    const UChar* str = ufmtval_getString(unumrf_resultAsValue(uresult, &ec), &len, &ec);
    assertSuccessCheck("There should not be a failure in the example code", &ec, TRUE);
    assertUEquals("Should produce expected string result", u"$3 – $5", str);
    int32_t resultLength = str != NULL ? u_strlen(str) : 0;
    assertIntEquals("Length should be as expected", resultLength, len);

    // Cleanup:
    unumrf_close(uformatter);
    unumrf_closeResult(uresult);
}


static void TestFormattedValue() {
    UErrorCode ec = U_ZERO_ERROR;
    UNumberRangeFormatter* uformatter = unumrf_openForSkeletonWithCollapseAndIdentityFallback(
        u"K",
        -1,
        UNUM_RANGE_COLLAPSE_AUTO,
        UNUM_IDENTITY_FALLBACK_APPROXIMATELY,
        "en-US",
        NULL,
        &ec);
    assertSuccessCheck("Should create without error", &ec, TRUE);
    UFormattedNumberRange* uresult = unumrf_openResult(&ec);
    assertSuccess("Should create result without error", &ec);

    // Test the decimal number code path, too
    unumrf_formatDecimalRange(uformatter, "5.5e4", -1, "1.5e5", -1, uresult, &ec);

    if (assertSuccessCheck("Should format without error", &ec, TRUE)) {
        const UFormattedValue* fv = unumrf_resultAsValue(uresult, &ec);
        assertSuccess("Should convert without error", &ec);
        static const UFieldPosition expectedFieldPositions[] = {
            // field, begin index, end index
            {UNUM_INTEGER_FIELD, 0, 2},
            {UNUM_COMPACT_FIELD, 2, 3},
            {UNUM_INTEGER_FIELD, 6, 9},
            {UNUM_COMPACT_FIELD, 9, 10}};
        checkFormattedValue(
            "FormattedNumber as FormattedValue",
            fv,
            u"55K – 150K",
            UFIELD_CATEGORY_NUMBER,
            expectedFieldPositions,
            UPRV_LENGTHOF(expectedFieldPositions));
    }

    assertIntEquals("Identity result should match",
        UNUM_IDENTITY_RESULT_NOT_EQUAL,
        unumrf_resultGetIdentityResult(uresult, &ec));

    // cleanup:
    unumrf_closeResult(uresult);
    unumrf_close(uformatter);
}


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

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

    // Now test the behavior.
    ec = U_ZERO_ERROR;
    uformatter = unumrf_openForSkeletonWithCollapseAndIdentityFallback(
        u".00 measure-unit/typo",
        -1, 
        UNUM_RANGE_COLLAPSE_AUTO,
        UNUM_IDENTITY_FALLBACK_APPROXIMATELY,
        "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:
    unumrf_close(uformatter);
}


static void TestGetDecimalNumbers() {
    UErrorCode ec = U_ZERO_ERROR;
    UNumberRangeFormatter* uformatter = unumrf_openForSkeletonWithCollapseAndIdentityFallback(
        u"currency/USD",
        -1,
        UNUM_RANGE_COLLAPSE_AUTO,
        UNUM_IDENTITY_FALLBACK_APPROXIMATELY,
        "en-US",
        NULL,
        &ec);
    assertSuccessCheck("Should create without error", &ec, TRUE);
    UFormattedNumberRange* uresult = unumrf_openResult(&ec);
    assertSuccess("Should create result without error", &ec);

    unumrf_formatDoubleRange(uformatter, 3.0, 5.0, uresult, &ec);
    const UChar* str = ufmtval_getString(unumrf_resultAsValue(uresult, &ec), NULL, &ec);
    assertSuccessCheck("Formatting should succeed", &ec, TRUE);
    assertUEquals("Should produce expected string result", u"$3.00 \u2013 $5.00", str);

    char buffer[CAPACITY];

    int32_t len = unumrf_resultGetFirstDecimalNumber(uresult, buffer, CAPACITY, &ec);
    assertIntEquals("First len should be as expected", strlen(buffer), len);
    assertEquals("First decimal should be as expected", "3", buffer);

    len = unumrf_resultGetSecondDecimalNumber(uresult, buffer, CAPACITY, &ec);
    assertIntEquals("Second len should be as expected", strlen(buffer), len);
    assertEquals("Second decimal should be as expected", "5", buffer);

    // cleanup:
    unumrf_closeResult(uresult);
    unumrf_close(uformatter);
}

#endif /* #if !UCONFIG_NO_FORMATTING */
