// © 2019 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 <fstream>
#include <iostream>
#include <vector>

#include "numbertest.h"
#include "ucbuf.h"
#include "unicode/numberformatter.h"

void NumberPermutationTest::runIndexedTest(int32_t index, UBool exec, const char*& name, char*) {
    if (exec) {
        logln("TestSuite NumberPermutationTest: ");
    }
    TESTCASE_AUTO_BEGIN;
    TESTCASE_AUTO(testPermutations);
    TESTCASE_AUTO_END;
}

static const char16_t* kSkeletonParts[] = {
    // Notation
    u"compact-short",
    u"scientific/+ee/sign-always",
    nullptr,
    // Unit
    u"percent",
    u"currency/EUR",
    u"measure-unit/length-furlong",
    nullptr,
    // Unit Width
    u"unit-width-narrow",
    u"unit-width-full-name",
    nullptr,
    // Precision
    u"precision-integer",
    u".000",
    u".##/@@@+",
    u"@@",
    nullptr,
    // Rounding Mode
    u"rounding-mode-floor",
    nullptr,
    // Integer Width
    u"integer-width/##00",
    nullptr,
    // Scale
    u"scale/0.5",
    nullptr,
    // Grouping
    u"group-on-aligned",
    nullptr,
    // Symbols
    u"latin",
    nullptr,
    // Sign Display
    u"sign-accounting-except-zero",
    nullptr,
    // Decimal Separator Display
    u"decimal-always",
    nullptr,
};

static const double kNumbersToTest[]{0, 91827.3645, -0.22222};

/**
 * Test permutations of 3 orthogonal skeleton parts from the list above.
 * Compare the results against the golden data file:
 *     numberpermutationtest.txt
 * To regenerate that file, run intltest with the -e and -G options.
 * On Linux, from icu4c/source:
 *     make -j8 tests && (cd test/intltest && LD_LIBRARY_PATH=../../lib:../../tools/ctestfw ./intltest -e -G format/NumberTest/NumberPermutationTest)
 * After re-generating the file, copy it into icu4j:
 *     cp test/testdata/numberpermutationtest.txt ../../icu4j/main/tests/core/src/com/ibm/icu/dev/data/numberpermutationtest.txt
 */
void NumberPermutationTest::testPermutations() {
    IcuTestErrorCode status(*this, "testPermutations");

    const struct LocaleData {
        Locale locale;
        const char16_t* ustring;
    } localesToTest[] = {
        {"es-MX", u"es-MX"},
        {"zh-TW", u"zh-TW"},
        {"bn-BD", u"bn-BD"},
    };

    // Convert kSkeletonParts to a more convenient data structure
    auto skeletonParts = std::vector<std::vector<const char16_t*>>();
    auto currentSection = std::vector<const char16_t*>();
    for (int32_t i = 0; i < UPRV_LENGTHOF(kSkeletonParts); i++) {
        const char16_t* skeletonPart = kSkeletonParts[i];
        if (skeletonPart == nullptr) {
            skeletonParts.push_back(currentSection);
            currentSection.clear();
        } else {
            currentSection.push_back(skeletonPart);
        }
    }

    // Build up the golden data string as we evaluate all permutations
    std::vector<UnicodeString> resultLines;
    resultLines.push_back(u"# © 2019 and later: Unicode, Inc. and others.");
    resultLines.push_back(u"# License & terms of use: http://www.unicode.org/copyright.html");
    resultLines.push_back(UnicodeString());

    // Take combinations of 3 orthogonal options
    for (size_t i = 0; i < skeletonParts.size() - 2; i++) {
        const auto& skeletons1 = skeletonParts[i];
        for (size_t j = i + 1; j < skeletonParts.size() - 1; j++) {
            const auto& skeletons2 = skeletonParts[j];
            for (size_t k = j + 1; k < skeletonParts.size(); k++) {
                const auto& skeletons3 = skeletonParts[k];

                // Evaluate all combinations of skeletons for these options
                for (const auto& skel1 : skeletons1) {
                    for (const auto& skel2 : skeletons2) {
                        for (const auto& skel3 : skeletons3) {
                            // Compute the skeleton
                            UnicodeString skeleton;
                            skeleton
                                .append(skel1)  //
                                .append(u' ')   //
                                .append(skel2)  //
                                .append(u' ')   //
                                .append(skel3);
                            resultLines.push_back(skeleton);

                            // Check several locales and several numbers in each locale
                            for (const auto& locData : localesToTest) {
                                auto lnf = NumberFormatter::forSkeleton(skeleton, status)
                                               .locale(locData.locale);
                                resultLines.push_back(UnicodeString(u"  ").append(locData.ustring));
                                for (const auto& input : kNumbersToTest) {
                                    resultLines.push_back(UnicodeString(u"    ").append(
                                        lnf.formatDouble(input, status).toTempString(status)));
                                }
                            }

                            resultLines.push_back(UnicodeString());
                        }
                    }
                }
            }

            // Quick mode: test all fields at least once but stop early.
            if (quick) {
                infoln(u"Quick mode: stopped after " + Int64ToUnicodeString(resultLines.size()) +
                       u" lines");
                goto outerEnd;
            }
        }
    }
outerEnd:
    void();

    CharString goldenFilePath(getSourceTestData(status), status);
    goldenFilePath.appendPathPart("numberpermutationtest.txt", status);

    // Compare it to the golden file
    const char* codePage = "UTF-8";
    LocalUCHARBUFPointer f(ucbuf_open(goldenFilePath.data(), &codePage, TRUE, FALSE, status));
    if (!assertSuccess("Can't open data file", status)) {
        return;
    }

    int32_t lineNumber = 1;
    int32_t lineLength;
    for (const auto& actualLine : resultLines) {
        const UChar* lineBuf = ucbuf_readline(f.getAlias(), &lineLength, status);
        if (lineBuf == nullptr) {
            errln("More lines generated than are in the data file!");
            break;
        }
        UnicodeString expectedLine(lineBuf, lineLength - 1);
        assertEquals(u"Line #" + Int64ToUnicodeString(lineNumber) + u" differs",  //
            expectedLine, actualLine);
        lineNumber++;
    }
    // Quick mode: test all fields at least once but stop early.
    if (!quick && ucbuf_readline(f.getAlias(), &lineLength, status) != nullptr) {
        errln("Fewer lines generated than are in the data file!");
    }

    // Overwrite the golden data if requested
    if (write_golden_data) {
        std::ofstream outFile;
        outFile.open(goldenFilePath.data());
        for (const auto& uniLine : resultLines) {
            std::string byteLine;
            uniLine.toUTF8String(byteLine);
            outFile << byteLine << std::endl;
        }
        outFile.close();
    }
}

#endif /* #if !UCONFIG_NO_FORMATTING */
