// © 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);

void addUNumberRangeFormatterTest(TestNode** root);

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

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


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);

    // 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);
}

#endif /* #if !UCONFIG_NO_FORMATTING */
