// © 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/dcfmtsym.h"

#include "cstr.h"
#include "numbertest.h"
#include "number_utils.h"
#include "number_skeletons.h"
#include "putilimp.h"

using namespace icu::number::impl;


void NumberSkeletonTest::runIndexedTest(int32_t index, UBool exec, const char*& name, char*) {
    if (exec) {
        logln("TestSuite AffixUtilsTest: ");
    }
    TESTCASE_AUTO_BEGIN;
        TESTCASE_AUTO(validTokens);
        TESTCASE_AUTO(invalidTokens);
        TESTCASE_AUTO(unknownTokens);
        TESTCASE_AUTO(unexpectedTokens);
        TESTCASE_AUTO(duplicateValues);
        TESTCASE_AUTO(stemsRequiringOption);
        TESTCASE_AUTO(defaultTokens);
        TESTCASE_AUTO(flexibleSeparators);
    TESTCASE_AUTO_END;
}

void NumberSkeletonTest::validTokens() {
    IcuTestErrorCode status(*this, "validTokens");

    // This tests only if the tokens are valid, not their behavior.
    // Most of these are from the design doc.
    static const char16_t* cases[] = {
            u"precision-integer",
            u"precision-unlimited",
            u"@@@##",
            u"@@+",
            u".000##",
            u".00+",
            u".",
            u".+",
            u".######",
            u".00/@@+",
            u".00/@##",
            u"precision-increment/3.14",
            u"precision-currency-standard",
            u"precision-integer rounding-mode-half-up",
            u".00# rounding-mode-ceiling",
            u".00/@@+ rounding-mode-floor",
            u"scientific",
            u"scientific/+ee",
            u"scientific/sign-always",
            u"scientific/+ee/sign-always",
            u"scientific/sign-always/+ee",
            u"scientific/sign-except-zero",
            u"engineering",
            u"engineering/+eee",
            u"compact-short",
            u"compact-long",
            u"notation-simple",
            u"percent",
            u"permille",
            u"measure-unit/length-meter",
            u"measure-unit/area-square-meter",
            u"measure-unit/energy-joule per-measure-unit/length-meter",
            u"unit/square-meter-per-square-meter",
            u"currency/XXX",
            u"currency/ZZZ",
            u"currency/usd",
            u"group-off",
            u"group-min2",
            u"group-auto",
            u"group-on-aligned",
            u"group-thousands",
            u"integer-width/00",
            u"integer-width/#0",
            u"integer-width/+00",
            u"sign-always",
            u"sign-auto",
            u"sign-never",
            u"sign-accounting",
            u"sign-accounting-always",
            u"sign-except-zero",
            u"sign-accounting-except-zero",
            u"unit-width-narrow",
            u"unit-width-short",
            u"unit-width-iso-code",
            u"unit-width-full-name",
            u"unit-width-hidden",
            u"decimal-auto",
            u"decimal-always",
            u"scale/5.2",
            u"scale/-5.2",
            u"scale/100",
            u"scale/1E2",
            u"scale/1",
            u"latin",
            u"numbering-system/arab",
            u"numbering-system/latn",
            u"precision-integer/@##",
            u"precision-integer rounding-mode-ceiling",
            u"precision-currency-cash rounding-mode-ceiling",
            u"0",
            u"00",
            u"000",
            u"E0",
            u"E00",
            u"E000",
            u"EE0",
            u"EE00",
            u"EE+?0",
            u"EE+?00",
            u"EE+!0",
            u"EE+!00",
    };

    for (auto& cas : cases) {
        UnicodeString skeletonString(cas);
        status.setScope(skeletonString);
        UParseError perror;
        NumberFormatter::forSkeleton(skeletonString, perror, status);
        assertSuccess(CStr(skeletonString)(), status, true);
        assertEquals(skeletonString, -1, perror.offset);
        status.errIfFailureAndReset();
    }
}

void NumberSkeletonTest::invalidTokens() {
    static const char16_t* cases[] = {
            u".00x",
            u".00##0",
            u".##+",
            u".00##+",
            u".0#+",
            u"@@x",
            u"@@##0",
            u"@#+",
            u".00/@",
            u".00/@@",
            u".00/@@x",
            u".00/@@#",
            u".00/@@#+",
            u".00/floor/@@+", // wrong order
            u"precision-increment/français", // non-invariant characters for C++
            u"scientific/ee",
            u"precision-increment/xxx",
            u"precision-increment/NaN",
            u"precision-increment/0.1.2",
            u"scale/xxx",
            u"scale/NaN",
            u"scale/0.1.2",
            u"scale/français", // non-invariant characters for C++
            u"currency/dummy",
            u"currency/ççç", // three characters but not ASCII
            u"measure-unit/foo",
            u"integer-width/xxx",
            u"integer-width/0+",
            u"integer-width/+0#",
            u"integer-width/+#",
            u"integer-width/+#0",
            u"scientific/foo",
            u"E",
            u"E1",
            u"E+",
            u"E+?",
            u"E+!",
            u"E+0",
            u"EE",
            u"EE+",
            u"EEE",
            u"EEE0",
            u"001",
            u"00+",
    };

    expectedErrorSkeleton(cases, UPRV_LENGTHOF(cases));
}

void NumberSkeletonTest::unknownTokens() {
    static const char16_t* cases[] = {
            u"maesure-unit",
            u"measure-unit/foo-bar",
            u"numbering-system/dummy",
            u"français",
            u"measure-unit/français-français", // non-invariant characters for C++
            u"numbering-system/français", // non-invariant characters for C++
            u"currency-USD"};

    expectedErrorSkeleton(cases, UPRV_LENGTHOF(cases));
}

void NumberSkeletonTest::unexpectedTokens() {
    static const char16_t* cases[] = {
            u"group-thousands/foo",
            u"precision-integer//@## group-off",
            u"precision-integer//@##  group-off",
            u"precision-integer/ group-off",
            u"precision-integer// group-off"};

    expectedErrorSkeleton(cases, UPRV_LENGTHOF(cases));
}

void NumberSkeletonTest::duplicateValues() {
    static const char16_t* cases[] = {
            u"precision-integer precision-integer",
            u"precision-integer .00+",
            u"precision-integer precision-unlimited",
            u"precision-integer @@@",
            u"scientific engineering",
            u"engineering compact-long",
            u"sign-auto sign-always"};

    expectedErrorSkeleton(cases, UPRV_LENGTHOF(cases));
}

void NumberSkeletonTest::stemsRequiringOption() {
    static const char16_t* stems[] = {
            u"precision-increment",
            u"measure-unit",
            u"per-measure-unit",
            u"currency",
            u"integer-width",
            u"numbering-system",
            u"scale"};
    static const char16_t* suffixes[] = {u"", u"/@##", u" scientific", u"/@## scientific"};

    for (auto& stem : stems) {
        for (auto& suffix : suffixes) {
            UnicodeString skeletonString = UnicodeString(stem) + suffix;
            UErrorCode status = U_ZERO_ERROR;
            UParseError perror;
            NumberFormatter::forSkeleton(skeletonString, perror, status);
            assertEquals(skeletonString, U_NUMBER_SKELETON_SYNTAX_ERROR, status);

            // Check the UParseError for integrity.
            // If an option is present, the option is wrong; error offset is at the start of the option
            // If an option is not present, the error offset is at the token separator (end of stem)
            int32_t expectedOffset = u_strlen(stem) + ((suffix[0] == u'/') ? 1 : 0);
            assertEquals(skeletonString, expectedOffset, perror.offset);
            UnicodeString expectedPreContext = skeletonString.tempSubString(0, expectedOffset);
            if (expectedPreContext.length() >= U_PARSE_CONTEXT_LEN - 1) {
                expectedPreContext = expectedPreContext.tempSubString(expectedOffset - U_PARSE_CONTEXT_LEN + 1);
            }
            assertEquals(skeletonString, expectedPreContext, perror.preContext);
            UnicodeString expectedPostContext = skeletonString.tempSubString(expectedOffset);
            // None of the postContext strings in this test exceed U_PARSE_CONTEXT_LEN
            assertEquals(skeletonString, expectedPostContext, perror.postContext);
        }
    }
}

void NumberSkeletonTest::defaultTokens() {
    IcuTestErrorCode status(*this, "defaultTokens");

    static const char16_t* cases[] = {
            u"notation-simple",
            u"base-unit",
            u"group-auto",
            u"integer-width/+0",
            u"sign-auto",
            u"unit-width-short",
            u"decimal-auto"};

    for (auto& cas : cases) {
        UnicodeString skeletonString(cas);
        status.setScope(skeletonString);
        UnicodeString normalized = NumberFormatter::forSkeleton(
                skeletonString, status).toSkeleton(status);
        // Skeleton should become empty when normalized
        assertEquals(skeletonString, u"", normalized);
        status.errIfFailureAndReset();
    }
}

void NumberSkeletonTest::flexibleSeparators() {
    IcuTestErrorCode status(*this, "flexibleSeparators");

    static struct TestCase {
        const char16_t* skeleton;
        const char16_t* expected;
    } cases[] = {{u"precision-integer group-off", u"5142"},
                 {u"precision-integer  group-off", u"5142"},
                 {u"precision-integer/@## group-off", u"5140"},
                 {u"precision-integer/@##  group-off", u"5140"}};

    for (auto& cas : cases) {
        UnicodeString skeletonString(cas.skeleton);
        UnicodeString expected(cas.expected);
        status.setScope(skeletonString);
        UnicodeString actual = NumberFormatter::forSkeleton(skeletonString, status).locale("en")
                               .formatDouble(5142.3, status)
                               .toString(status);
        if (!status.errDataIfFailureAndReset()) {
            assertEquals(skeletonString, expected, actual);
        }
        status.errIfFailureAndReset();
    }
}

// In C++, there is no distinguishing between "invalid", "unknown", and "unexpected" tokens.
void NumberSkeletonTest::expectedErrorSkeleton(const char16_t** cases, int32_t casesLen) {
    for (int32_t i = 0; i < casesLen; i++) {
        UnicodeString skeletonString(cases[i]);
        UErrorCode status = U_ZERO_ERROR;
        NumberFormatter::forSkeleton(skeletonString, status);
        assertEquals(skeletonString, U_NUMBER_SKELETON_SYNTAX_ERROR, status);
    }
}


#endif /* #if !UCONFIG_NO_FORMATTING */
