// © 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 "putilimp.h"
#include "unicode/dcfmtsym.h"
#include "numbertest.h"
#include "number_utils.h"

using namespace icu::number::impl;

class DefaultSymbolProvider : public SymbolProvider {
    DecimalFormatSymbols fSymbols;

  public:
    DefaultSymbolProvider(UErrorCode &status) : fSymbols(Locale("ar_SA"), status) {}

    UnicodeString getSymbol(AffixPatternType type) const U_OVERRIDE {
        switch (type) {
            case TYPE_MINUS_SIGN:
                return u"−";
            case TYPE_PLUS_SIGN:
                return fSymbols.getConstSymbol(DecimalFormatSymbols::ENumberFormatSymbol::kPlusSignSymbol);
            case TYPE_PERCENT:
                return fSymbols.getConstSymbol(DecimalFormatSymbols::ENumberFormatSymbol::kPercentSymbol);
            case TYPE_PERMILLE:
                return fSymbols.getConstSymbol(DecimalFormatSymbols::ENumberFormatSymbol::kPerMillSymbol);
            case TYPE_CURRENCY_SINGLE:
                return u"$";
            case TYPE_CURRENCY_DOUBLE:
                return u"XXX";
            case TYPE_CURRENCY_TRIPLE:
                return u"long name";
            case TYPE_CURRENCY_QUAD:
                return u"\uFFFD";
            case TYPE_CURRENCY_QUINT:
                // TODO: Add support for narrow currency symbols here.
                return u"\uFFFD";
            case TYPE_CURRENCY_OVERFLOW:
                return u"\uFFFD";
            default:
                UPRV_UNREACHABLE;
        }
    }
};

void AffixUtilsTest::runIndexedTest(int32_t index, UBool exec, const char *&name, char *) {
    if (exec) {
        logln("TestSuite AffixUtilsTest: ");
    }
    TESTCASE_AUTO_BEGIN;
        TESTCASE_AUTO(testEscape);
        TESTCASE_AUTO(testUnescape);
        TESTCASE_AUTO(testContainsReplaceType);
        TESTCASE_AUTO(testInvalid);
        TESTCASE_AUTO(testUnescapeWithSymbolProvider);
    TESTCASE_AUTO_END;
}

void AffixUtilsTest::testEscape() {
    static const char16_t *cases[][2] = {{u"", u""},
                                         {u"abc", u"abc"},
                                         {u"-", u"'-'"},
                                         {u"-!", u"'-'!"},
                                         {u"−", u"−"},
                                         {u"---", u"'---'"},
                                         {u"-%-", u"'-%-'"},
                                         {u"'", u"''"},
                                         {u"-'", u"'-'''"},
                                         {u"-'-", u"'-''-'"},
                                         {u"a-'-", u"a'-''-'"}};

    for (auto &cas : cases) {
        UnicodeString input(cas[0]);
        UnicodeString expected(cas[1]);
        UnicodeString result = AffixUtils::escape(input);
        assertEquals(input, expected, result);
    }
}

void AffixUtilsTest::testUnescape() {
    static struct TestCase {
        const char16_t *input;
        bool currency;
        int32_t expectedLength;
        const char16_t *output;
    } cases[] = {{u"", false, 0, u""},
                 {u"abc", false, 3, u"abc"},
                 {u"-", false, 1, u"−"},
                 {u"-!", false, 2, u"−!"},
                 {u"+", false, 1, u"\u061C+"},
                 {u"+!", false, 2, u"\u061C+!"},
                 {u"‰", false, 1, u"؉"},
                 {u"‰!", false, 2, u"؉!"},
                 {u"-x", false, 2, u"−x"},
                 {u"'-'x", false, 2, u"-x"},
                 {u"'--''-'-x", false, 6, u"--'-−x"},
                 {u"''", false, 1, u"'"},
                 {u"''''", false, 2, u"''"},
                 {u"''''''", false, 3, u"'''"},
                 {u"''x''", false, 3, u"'x'"},
                 {u"¤", true, 1, u"$"},
                 {u"¤¤", true, 2, u"XXX"},
                 {u"¤¤¤", true, 3, u"long name"},
                 {u"¤¤¤¤", true, 4, u"\uFFFD"},
                 {u"¤¤¤¤¤", true, 5, u"\uFFFD"},
                 {u"¤¤¤¤¤¤", true, 6, u"\uFFFD"},
                 {u"¤¤¤a¤¤¤¤", true, 8, u"long namea\uFFFD"},
                 {u"a¤¤¤¤b¤¤¤¤¤c", true, 12, u"a\uFFFDb\uFFFDc"},
                 {u"¤!", true, 2, u"$!"},
                 {u"¤¤!", true, 3, u"XXX!"},
                 {u"¤¤¤!", true, 4, u"long name!"},
                 {u"-¤¤", true, 3, u"−XXX"},
                 {u"¤¤-", true, 3, u"XXX−"},
                 {u"'¤'", false, 1, u"¤"},
                 {u"%", false, 1, u"٪\u061C"},
                 {u"'%'", false, 1, u"%"},
                 {u"¤'-'%", true, 3, u"$-٪\u061C"},
                 {u"#0#@#*#;#", false, 9, u"#0#@#*#;#"}};

    UErrorCode status = U_ZERO_ERROR;
    DefaultSymbolProvider defaultProvider(status);
    assertSuccess("Constructing DefaultSymbolProvider", status);

    for (TestCase cas : cases) {
        UnicodeString input(cas.input);
        UnicodeString output(cas.output);

        assertEquals(input, cas.currency, AffixUtils::hasCurrencySymbols(input, status));
        assertSuccess("Spot 1", status);
        assertEquals(input, cas.expectedLength, AffixUtils::estimateLength(input, status));
        assertSuccess("Spot 2", status);

        UnicodeString actual = unescapeWithDefaults(defaultProvider, input, status);
        assertSuccess("Spot 3", status);
        assertEquals(input, output, actual);

        int32_t ulength = AffixUtils::unescapedCodePointCount(input, defaultProvider, status);
        assertSuccess("Spot 4", status);
        assertEquals(input, output.countChar32(), ulength);
    }
}

void AffixUtilsTest::testContainsReplaceType() {
    static struct TestCase {
        const char16_t *input;
        bool hasMinusSign;
        const char16_t *output;
    } cases[] = {{u"", false, u""},
                 {u"-", true, u"+"},
                 {u"-a", true, u"+a"},
                 {u"a-", true, u"a+"},
                 {u"a-b", true, u"a+b"},
                 {u"--", true, u"++"},
                 {u"x", false, u"x"}};

    UErrorCode status = U_ZERO_ERROR;
    for (TestCase cas : cases) {
        UnicodeString input(cas.input);
        bool hasMinusSign = cas.hasMinusSign;
        UnicodeString output(cas.output);

        assertEquals(
                input, hasMinusSign, AffixUtils::containsType(input, TYPE_MINUS_SIGN, status));
        assertSuccess("Spot 1", status);
        assertEquals(
                input, output, AffixUtils::replaceType(input, TYPE_MINUS_SIGN, u'+', status));
        assertSuccess("Spot 2", status);
    }
}

void AffixUtilsTest::testInvalid() {
    static const char16_t *invalidExamples[] = {
            u"'", u"x'", u"'x", u"'x''", u"''x'"};

    UErrorCode status = U_ZERO_ERROR;
    DefaultSymbolProvider defaultProvider(status);
    assertSuccess("Constructing DefaultSymbolProvider", status);

    for (const char16_t *strPtr : invalidExamples) {
        UnicodeString str(strPtr);

        status = U_ZERO_ERROR;
        AffixUtils::hasCurrencySymbols(str, status);
        assertEquals("Should set error code spot 1", status, U_ILLEGAL_ARGUMENT_ERROR);

        status = U_ZERO_ERROR;
        AffixUtils::estimateLength(str, status);
        assertEquals("Should set error code spot 2", status, U_ILLEGAL_ARGUMENT_ERROR);

        status = U_ZERO_ERROR;
        unescapeWithDefaults(defaultProvider, str, status);
        assertEquals("Should set error code spot 3", status, U_ILLEGAL_ARGUMENT_ERROR);
    }
}

class NumericSymbolProvider : public SymbolProvider {
  public:
    virtual UnicodeString getSymbol(AffixPatternType type) const {
        return Int64ToUnicodeString(type < 0 ? -type : type);
    }
};

void AffixUtilsTest::testUnescapeWithSymbolProvider() {
    static const char16_t* cases[][2] = {
            {u"", u""},
            {u"-", u"1"},
            {u"'-'", u"-"},
            {u"- + % ‰ ¤ ¤¤ ¤¤¤ ¤¤¤¤ ¤¤¤¤¤", u"1 2 3 4 5 6 7 8 9"},
            {u"'¤¤¤¤¤¤'", u"¤¤¤¤¤¤"},
            {u"¤¤¤¤¤¤", u"\uFFFD"}
    };

    NumericSymbolProvider provider;

    UErrorCode status = U_ZERO_ERROR;
    FormattedStringBuilder sb;
    for (auto& cas : cases) {
        UnicodeString input(cas[0]);
        UnicodeString expected(cas[1]);
        sb.clear();
        AffixUtils::unescape(input, sb, 0, provider, kUndefinedField, status);
        assertSuccess("Spot 1", status);
        assertEquals(input, expected, sb.toUnicodeString());
        assertEquals(input, expected, sb.toTempUnicodeString());
    }

    // Test insertion position
    sb.clear();
    sb.append(u"abcdefg", kUndefinedField, status);
    assertSuccess("Spot 2", status);
    AffixUtils::unescape(u"-+%", sb, 4, provider, kUndefinedField, status);
    assertSuccess("Spot 3", status);
    assertEquals(u"Symbol provider into middle", u"abcd123efg", sb.toUnicodeString());
}

UnicodeString AffixUtilsTest::unescapeWithDefaults(const SymbolProvider &defaultProvider,
                                                          UnicodeString input, UErrorCode &status) {
    FormattedStringBuilder nsb;
    int32_t length = AffixUtils::unescape(input, nsb, 0, defaultProvider, kUndefinedField, status);
    assertEquals("Return value of unescape", nsb.length(), length);
    return nsb.toUnicodeString();
}

#endif /* #if !UCONFIG_NO_FORMATTING */
