// © 2019 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html#License

// localematchertest.cpp
// created: 2019jul04 Markus W. Scherer

#include <string>
#include <vector>

#include "unicode/utypes.h"
#include "unicode/localematcher.h"
#include "unicode/locid.h"
#include "charstr.h"
#include "cmemory.h"
#include "intltest.h"
#include "localeprioritylist.h"
#include "ucbuf.h"

#define ARRAY_RANGE(array) (array), ((array) + UPRV_LENGTHOF(array))

namespace {

const char *locString(const Locale *loc) {
    return loc != nullptr ? loc->getName() : "(null)";
}

struct TestCase {
    int32_t lineNr = 0;

    CharString supported;
    CharString def;
    UnicodeString favor;
    UnicodeString threshold;
    CharString desired;
    CharString expMatch;
    CharString expDesired;
    CharString expCombined;

    void reset() {
        supported.clear();
        def.clear();
        favor.remove();
        threshold.remove();
    }
};

}  // namespace

class LocaleMatcherTest : public IntlTest {
public:
    LocaleMatcherTest() {}

    void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par=NULL);

    void testEmpty();
    void testCopyErrorTo();
    void testBasics();
    void testSupportedDefault();
    void testUnsupportedDefault();
    void testDemotion();
    void testDirection();
    void testMatch();
    void testResolvedLocale();
    void testDataDriven();

private:
    UBool dataDriven(const TestCase &test, IcuTestErrorCode &errorCode);
};

extern IntlTest *createLocaleMatcherTest() {
    return new LocaleMatcherTest();
}

void LocaleMatcherTest::runIndexedTest(int32_t index, UBool exec, const char *&name, char * /*par*/) {
    if(exec) {
        logln("TestSuite LocaleMatcherTest: ");
    }
    TESTCASE_AUTO_BEGIN;
    TESTCASE_AUTO(testEmpty);
    TESTCASE_AUTO(testCopyErrorTo);
    TESTCASE_AUTO(testBasics);
    TESTCASE_AUTO(testSupportedDefault);
    TESTCASE_AUTO(testUnsupportedDefault);
    TESTCASE_AUTO(testDemotion);
    TESTCASE_AUTO(testDirection);
    TESTCASE_AUTO(testMatch);
    TESTCASE_AUTO(testResolvedLocale);
    TESTCASE_AUTO(testDataDriven);
    TESTCASE_AUTO_END;
}

void LocaleMatcherTest::testEmpty() {
    IcuTestErrorCode errorCode(*this, "testEmpty");
    LocaleMatcher matcher = LocaleMatcher::Builder().build(errorCode);
    const Locale *best = matcher.getBestMatch(Locale::getFrench(), errorCode);
    assertEquals("getBestMatch(fr)", "(null)", locString(best));
    LocaleMatcher::Result result = matcher.getBestMatchResult("fr", errorCode);
    assertEquals("getBestMatchResult(fr).des", "(null)", locString(result.getDesiredLocale()));
    assertEquals("getBestMatchResult(fr).desIndex", -1, result.getDesiredIndex());
    assertEquals("getBestMatchResult(fr).supp",
                 "(null)", locString(result.getSupportedLocale()));
    assertEquals("getBestMatchResult(fr).suppIndex",
                 -1, result.getSupportedIndex());
}

void LocaleMatcherTest::testCopyErrorTo() {
    IcuTestErrorCode errorCode(*this, "testCopyErrorTo");
    // The builder does not set any errors except out-of-memory.
    // Test what we can.
    LocaleMatcher::Builder builder;
    UErrorCode success = U_ZERO_ERROR;
    assertFalse("no error", builder.copyErrorTo(success));
    assertTrue("still success", U_SUCCESS(success));
    UErrorCode failure = U_INVALID_FORMAT_ERROR;
    assertTrue("failure passed in", builder.copyErrorTo(failure));
    assertEquals("same failure", U_INVALID_FORMAT_ERROR, failure);
}

void LocaleMatcherTest::testBasics() {
    IcuTestErrorCode errorCode(*this, "testBasics");
    Locale locales[] = { "fr", "en_GB", "en" };
    {
        LocaleMatcher matcher = LocaleMatcher::Builder().
            setSupportedLocales(ARRAY_RANGE(locales)).build(errorCode);
        const Locale *best = matcher.getBestMatch("en_GB", errorCode);
        assertEquals("fromRange.getBestMatch(en_GB)", "en_GB", locString(best));
        best = matcher.getBestMatch("en_US", errorCode);
        assertEquals("fromRange.getBestMatch(en_US)", "en", locString(best));
        best = matcher.getBestMatch("fr_FR", errorCode);
        assertEquals("fromRange.getBestMatch(fr_FR)", "fr", locString(best));
        best = matcher.getBestMatch("ja_JP", errorCode);
        assertEquals("fromRange.getBestMatch(ja_JP)", "fr", locString(best));
    }
    // Code coverage: Variations of setting supported locales.
    {
        std::vector<Locale> locales{ "fr", "en_GB", "en" };
        LocaleMatcher matcher = LocaleMatcher::Builder().
            setSupportedLocales(locales.begin(), locales.end()).build(errorCode);
        const Locale *best = matcher.getBestMatch("en_GB", errorCode);
        assertEquals("fromRange.getBestMatch(en_GB)", "en_GB", locString(best));
        best = matcher.getBestMatch("en_US", errorCode);
        assertEquals("fromRange.getBestMatch(en_US)", "en", locString(best));
        best = matcher.getBestMatch("fr_FR", errorCode);
        assertEquals("fromRange.getBestMatch(fr_FR)", "fr", locString(best));
        best = matcher.getBestMatch("ja_JP", errorCode);
        assertEquals("fromRange.getBestMatch(ja_JP)", "fr", locString(best));
    }
    {
        Locale::RangeIterator<Locale *> iter(ARRAY_RANGE(locales));
        LocaleMatcher matcher = LocaleMatcher::Builder().
            setSupportedLocales(iter).build(errorCode);
        const Locale *best = matcher.getBestMatch("en_GB", errorCode);
        assertEquals("fromIter.getBestMatch(en_GB)", "en_GB", locString(best));
        best = matcher.getBestMatch("en_US", errorCode);
        assertEquals("fromIter.getBestMatch(en_US)", "en", locString(best));
        best = matcher.getBestMatch("fr_FR", errorCode);
        assertEquals("fromIter.getBestMatch(fr_FR)", "fr", locString(best));
        best = matcher.getBestMatch("ja_JP", errorCode);
        assertEquals("fromIter.getBestMatch(ja_JP)", "fr", locString(best));
    }
    {
        Locale *pointers[] = { locales, locales + 1, locales + 2 };
        // Lambda with explicit reference return type to prevent copy-constructing a temporary
        // which would be destructed right away.
        LocaleMatcher matcher = LocaleMatcher::Builder().
            setSupportedLocalesViaConverter(
                ARRAY_RANGE(pointers), [](const Locale *p) -> const Locale & { return *p; }).
            build(errorCode);
        const Locale *best = matcher.getBestMatch("en_GB", errorCode);
        assertEquals("viaConverter.getBestMatch(en_GB)", "en_GB", locString(best));
        best = matcher.getBestMatch("en_US", errorCode);
        assertEquals("viaConverter.getBestMatch(en_US)", "en", locString(best));
        best = matcher.getBestMatch("fr_FR", errorCode);
        assertEquals("viaConverter.getBestMatch(fr_FR)", "fr", locString(best));
        best = matcher.getBestMatch("ja_JP", errorCode);
        assertEquals("viaConverter.getBestMatch(ja_JP)", "fr", locString(best));
    }
    {
        LocaleMatcher matcher = LocaleMatcher::Builder().
            addSupportedLocale(locales[0]).
            addSupportedLocale(locales[1]).
            addSupportedLocale(locales[2]).
            build(errorCode);
        const Locale *best = matcher.getBestMatch("en_GB", errorCode);
        assertEquals("added.getBestMatch(en_GB)", "en_GB", locString(best));
        best = matcher.getBestMatch("en_US", errorCode);
        assertEquals("added.getBestMatch(en_US)", "en", locString(best));
        best = matcher.getBestMatch("fr_FR", errorCode);
        assertEquals("added.getBestMatch(fr_FR)", "fr", locString(best));
        best = matcher.getBestMatch("ja_JP", errorCode);
        assertEquals("added.getBestMatch(ja_JP)", "fr", locString(best));
    }
    {
        LocaleMatcher matcher = LocaleMatcher::Builder().
            setSupportedLocalesFromListString(
                " el, fr;q=0.555555, en-GB ; q = 0.88  , el; q =0, en;q=0.88 , fr ").
            build(errorCode);
        const Locale *best = matcher.getBestMatchForListString("el, fr, fr;q=0, en-GB", errorCode);
        assertEquals("fromList.getBestMatch(en_GB)", "en_GB", locString(best));
        best = matcher.getBestMatch("en_US", errorCode);
        assertEquals("fromList.getBestMatch(en_US)", "en", locString(best));
        best = matcher.getBestMatch("fr_FR", errorCode);
        assertEquals("fromList.getBestMatch(fr_FR)", "fr", locString(best));
        best = matcher.getBestMatch("ja_JP", errorCode);
        assertEquals("fromList.getBestMatch(ja_JP)", "fr", locString(best));
    }
    // more API coverage
    {
        LocalePriorityList list("fr, en-GB", errorCode);
        LocalePriorityList::Iterator iter(list.iterator());
        LocaleMatcher matcher = LocaleMatcher::Builder().
            setSupportedLocales(iter).
            addSupportedLocale(Locale::getEnglish()).
            setDefaultLocale(&Locale::getGerman()).
            build(errorCode);
        const Locale *best = matcher.getBestMatch("en_GB", errorCode);
        assertEquals("withDefault.getBestMatch(en_GB)", "en_GB", locString(best));
        best = matcher.getBestMatch("en_US", errorCode);
        assertEquals("withDefault.getBestMatch(en_US)", "en", locString(best));
        best = matcher.getBestMatch("fr_FR", errorCode);
        assertEquals("withDefault.getBestMatch(fr_FR)", "fr", locString(best));
        best = matcher.getBestMatch("ja_JP", errorCode);
        assertEquals("withDefault.getBestMatch(ja_JP)", "de", locString(best));

        Locale desired("en_GB");  // distinct object from Locale.UK
        LocaleMatcher::Result result = matcher.getBestMatchResult(desired, errorCode);
        assertTrue("withDefault: exactly desired en-GB object",
                   &desired == result.getDesiredLocale());
        assertEquals("withDefault: en-GB desired index", 0, result.getDesiredIndex());
        assertEquals("withDefault: en-GB supported",
                     "en_GB", locString(result.getSupportedLocale()));
        assertEquals("withDefault: en-GB supported index", 1, result.getSupportedIndex());

        LocalePriorityList list2("ja-JP, en-US", errorCode);
        LocalePriorityList::Iterator iter2(list2.iterator());
        result = matcher.getBestMatchResult(iter2, errorCode);
        assertEquals("withDefault: ja-JP, en-US desired index", 1, result.getDesiredIndex());
        assertEquals("withDefault: ja-JP, en-US desired",
                     "en_US", locString(result.getDesiredLocale()));

        desired = Locale("en", "US");  // distinct object from Locale.US
        result = matcher.getBestMatchResult(desired, errorCode);
        assertTrue("withDefault: exactly desired en-US object",
                   &desired == result.getDesiredLocale());
        assertEquals("withDefault: en-US desired index", 0, result.getDesiredIndex());
        assertEquals("withDefault: en-US supported", "en", locString(result.getSupportedLocale()));
        assertEquals("withDefault: en-US supported index", 2, result.getSupportedIndex());

        result = matcher.getBestMatchResult("ja_JP", errorCode);
        assertEquals("withDefault: ja-JP desired", "(null)", locString(result.getDesiredLocale()));
        assertEquals("withDefault: ja-JP desired index", -1, result.getDesiredIndex());
        assertEquals("withDefault: ja-JP supported", "de", locString(result.getSupportedLocale()));
        assertEquals("withDefault: ja-JP supported index", -1, result.getSupportedIndex());
    }
}

void LocaleMatcherTest::testSupportedDefault() {
    // The default locale is one of the supported locales.
    IcuTestErrorCode errorCode(*this, "testSupportedDefault");
    Locale locales[] = { "fr", "en_GB", "en" };
    LocaleMatcher matcher = LocaleMatcher::Builder().
        setSupportedLocales(ARRAY_RANGE(locales)).
        setDefaultLocale(&locales[1]).
        build(errorCode);
    const Locale *best = matcher.getBestMatch("en_GB", errorCode);
    assertEquals("getBestMatch(en_GB)", "en_GB", locString(best));
    best = matcher.getBestMatch("en_US", errorCode);
    assertEquals("getBestMatch(en_US)", "en", locString(best));
    best = matcher.getBestMatch("fr_FR", errorCode);
    assertEquals("getBestMatch(fr_FR)", "fr", locString(best));
    best = matcher.getBestMatch("ja_JP", errorCode);
    assertEquals("getBestMatch(ja_JP)", "en_GB", locString(best));
    LocaleMatcher::Result result = matcher.getBestMatchResult("ja_JP", errorCode);
    assertEquals("getBestMatchResult(ja_JP).supp",
                 "en_GB", locString(result.getSupportedLocale()));
    assertEquals("getBestMatchResult(ja_JP).suppIndex",
                 -1, result.getSupportedIndex());
}

void LocaleMatcherTest::testUnsupportedDefault() {
    // The default locale does not match any of the supported locales.
    IcuTestErrorCode errorCode(*this, "testUnsupportedDefault");
    Locale locales[] = { "fr", "en_GB", "en" };
    Locale def("de");
    LocaleMatcher matcher = LocaleMatcher::Builder().
        setSupportedLocales(ARRAY_RANGE(locales)).
        setDefaultLocale(&def).
        build(errorCode);
    const Locale *best = matcher.getBestMatch("en_GB", errorCode);
    assertEquals("getBestMatch(en_GB)", "en_GB", locString(best));
    best = matcher.getBestMatch("en_US", errorCode);
    assertEquals("getBestMatch(en_US)", "en", locString(best));
    best = matcher.getBestMatch("fr_FR", errorCode);
    assertEquals("getBestMatch(fr_FR)", "fr", locString(best));
    best = matcher.getBestMatch("ja_JP", errorCode);
    assertEquals("getBestMatch(ja_JP)", "de", locString(best));
    LocaleMatcher::Result result = matcher.getBestMatchResult("ja_JP", errorCode);
    assertEquals("getBestMatchResult(ja_JP).supp",
                 "de", locString(result.getSupportedLocale()));
    assertEquals("getBestMatchResult(ja_JP).suppIndex",
                 -1, result.getSupportedIndex());
}

void LocaleMatcherTest::testDemotion() {
    IcuTestErrorCode errorCode(*this, "testDemotion");
    Locale supported[] = { "fr", "de-CH", "it" };
    Locale desired[] = { "fr-CH", "de-CH", "it" };
    {
        LocaleMatcher noDemotion = LocaleMatcher::Builder().
            setSupportedLocales(ARRAY_RANGE(supported)).
            setDemotionPerDesiredLocale(ULOCMATCH_DEMOTION_NONE).build(errorCode);
        Locale::RangeIterator<Locale *> desiredIter(ARRAY_RANGE(desired));
        assertEquals("no demotion",
                     "de_CH", locString(noDemotion.getBestMatch(desiredIter, errorCode)));
    }

    {
        LocaleMatcher regionDemotion = LocaleMatcher::Builder().
            setSupportedLocales(ARRAY_RANGE(supported)).
            setDemotionPerDesiredLocale(ULOCMATCH_DEMOTION_REGION).build(errorCode);
        Locale::RangeIterator<Locale *> desiredIter(ARRAY_RANGE(desired));
        assertEquals("region demotion",
                     "fr", locString(regionDemotion.getBestMatch(desiredIter, errorCode)));
    }
}

void LocaleMatcherTest::testDirection() {
    IcuTestErrorCode errorCode(*this, "testDirection");
    Locale supported[] = { "ar", "nn" };
    Locale desired[] = { "arz-EG", "nb-DK" };
    LocaleMatcher::Builder builder;
    builder.setSupportedLocales(ARRAY_RANGE(supported));
    {
        // arz is a close one-way match to ar, and the region matches.
        // (Egyptian Arabic vs. Arabic)
        LocaleMatcher withOneWay = builder.build(errorCode);
        Locale::RangeIterator<Locale *> desiredIter(ARRAY_RANGE(desired));
        assertEquals("with one-way", "ar",
                     locString(withOneWay.getBestMatch(desiredIter, errorCode)));
    }
    {
        // nb is a less close two-way match to nn, and the regions differ.
        // (Norwegian Bokmal vs. Nynorsk)
        LocaleMatcher onlyTwoWay =
            builder.setDirection(ULOCMATCH_DIRECTION_ONLY_TWO_WAY).build(errorCode);
        Locale::RangeIterator<Locale *> desiredIter(ARRAY_RANGE(desired));
        assertEquals("only two-way", "nn",
                     locString(onlyTwoWay.getBestMatch(desiredIter, errorCode)));
    }
}

void LocaleMatcherTest::testMatch() {
    IcuTestErrorCode errorCode(*this, "testMatch");
    LocaleMatcher matcher = LocaleMatcher::Builder().build(errorCode);

    // Java test function testMatch_exact()
    Locale en_CA("en_CA");
    assertEquals("exact match", 1.0, matcher.internalMatch(en_CA, en_CA, errorCode));

    // testMatch_none
    Locale ar_MK("ar_MK");
    double match = matcher.internalMatch(ar_MK, en_CA, errorCode);
    assertTrue("mismatch: 0<=match<0.2", 0 <= match && match < 0.2);

    // testMatch_matchOnMaximized
    Locale und_TW("und_TW");
    Locale zh("zh");
    Locale zh_Hant("zh_Hant");
    double matchZh = matcher.internalMatch(und_TW, zh, errorCode);
    double matchZhHant = matcher.internalMatch(und_TW, zh_Hant, errorCode);
    assertTrue("und_TW should be closer to zh_Hant than to zh",
               matchZh < matchZhHant);
    Locale en_Hant_TW("en_Hant_TW");
    double matchEnHantTw = matcher.internalMatch(en_Hant_TW, zh_Hant, errorCode);
    assertTrue("zh_Hant should be closer to und_TW than to en_Hant_TW",
               matchEnHantTw < matchZhHant);
    assertTrue("zh should be closer to und_TW than to en_Hant_TW",
               matchEnHantTw < matchZh);
}

void LocaleMatcherTest::testResolvedLocale() {
    IcuTestErrorCode errorCode(*this, "testResolvedLocale");
    LocaleMatcher matcher = LocaleMatcher::Builder().
        addSupportedLocale("ar-EG").
        build(errorCode);
    Locale desired("ar-SA-u-nu-latn");
    LocaleMatcher::Result result = matcher.getBestMatchResult(desired, errorCode);
    assertEquals("best", "ar_EG", locString(result.getSupportedLocale()));
    Locale resolved = result.makeResolvedLocale(errorCode);
    assertEquals("ar-EG + ar-SA-u-nu-latn = ar-SA-u-nu-latn",
                 "ar-SA-u-nu-latn",
                 resolved.toLanguageTag<std::string>(errorCode).data());
}

namespace {

bool toInvariant(const UnicodeString &s, CharString &inv, ErrorCode &errorCode) {
    if (errorCode.isSuccess()) {
        inv.clear().appendInvariantChars(s, errorCode);
        return errorCode.isSuccess();
    }
    return false;
}

bool getSuffixAfterPrefix(const UnicodeString &s, int32_t limit,
                          const UnicodeString &prefix, UnicodeString &suffix) {
    if (prefix.length() <= limit && s.startsWith(prefix)) {
        suffix.setTo(s, prefix.length(), limit - prefix.length());
        return true;
    } else {
        return false;
    }
}

bool getInvariantSuffixAfterPrefix(const UnicodeString &s, int32_t limit,
                                   const UnicodeString &prefix, CharString &suffix,
                                   ErrorCode &errorCode) {
    UnicodeString u_suffix;
    return getSuffixAfterPrefix(s, limit, prefix, u_suffix) &&
        toInvariant(u_suffix, suffix, errorCode);
}

bool readTestCase(const UnicodeString &line, TestCase &test, IcuTestErrorCode &errorCode) {
    if (errorCode.isFailure()) { return false; }
    ++test.lineNr;
    // Start of comment, or end of line, minus trailing spaces.
    int32_t limit = line.indexOf(u'#');
    if (limit < 0) {
        limit = line.length();
        // Remove trailing CR LF.
        char16_t c;
        while (limit > 0 && ((c = line.charAt(limit - 1)) == u'\n' || c == u'\r')) {
            --limit;
        }
    }
    // Remove spaces before comment or at the end of the line.
    char16_t c;
    while (limit > 0 && ((c = line.charAt(limit - 1)) == u' ' || c == u'\t')) {
        --limit;
    }
    if (limit == 0) {  // empty line
        return false;
    }
    if (line.startsWith(u"** test: ")) {
        test.reset();
    } else if (getInvariantSuffixAfterPrefix(line, limit, u"@supported=",
                                             test.supported, errorCode)) {
    } else if (getInvariantSuffixAfterPrefix(line, limit, u"@default=",
                                             test.def, errorCode)) {
    } else if (getSuffixAfterPrefix(line, limit, u"@favor=", test.favor)) {
    } else if (getSuffixAfterPrefix(line, limit, u"@threshold=", test.threshold)) {
    } else {
        int32_t matchSep = line.indexOf(u">>");
        // >> before an inline comment, and followed by more than white space.
        if (0 <= matchSep && (matchSep + 2) < limit) {
            toInvariant(line.tempSubStringBetween(0, matchSep).trim(), test.desired, errorCode);
            test.expDesired.clear();
            test.expCombined.clear();
            int32_t start = matchSep + 2;
            int32_t expLimit = line.indexOf(u'|', start);
            if (expLimit < 0) {
                toInvariant(line.tempSubStringBetween(start, limit).trim(),
                            test.expMatch, errorCode);
            } else {
                toInvariant(line.tempSubStringBetween(start, expLimit).trim(),
                            test.expMatch, errorCode);
                start = expLimit + 1;
                expLimit = line.indexOf(u'|', start);
                if (expLimit < 0) {
                    toInvariant(line.tempSubStringBetween(start, limit).trim(),
                                test.expDesired, errorCode);
                } else {
                    toInvariant(line.tempSubStringBetween(start, expLimit).trim(),
                                test.expDesired, errorCode);
                    toInvariant(line.tempSubStringBetween(expLimit + 1, limit).trim(),
                                test.expCombined, errorCode);
                }
            }
            return errorCode.isSuccess();
        } else {
            errorCode.set(U_INVALID_FORMAT_ERROR);
        }
    }
    return false;
}

Locale *getLocaleOrNull(const CharString &s, Locale &locale) {
    if (s == "null") {
        return nullptr;
    } else {
        return &(locale = Locale(s.data()));
    }
}

}  // namespace

UBool LocaleMatcherTest::dataDriven(const TestCase &test, IcuTestErrorCode &errorCode) {
    LocaleMatcher::Builder builder;
    builder.setSupportedLocalesFromListString(test.supported.toStringPiece());
    if (!test.def.isEmpty()) {
        Locale defaultLocale(test.def.data());
        builder.setDefaultLocale(&defaultLocale);
    }
    if (!test.favor.isEmpty()) {
        ULocMatchFavorSubtag favor;
        if (test.favor == u"normal") {
            favor = ULOCMATCH_FAVOR_LANGUAGE;
        } else if (test.favor == u"script") {
            favor = ULOCMATCH_FAVOR_SCRIPT;
        } else {
            errln(UnicodeString(u"unsupported FavorSubtag value ") + test.favor);
            return FALSE;
        }
        builder.setFavorSubtag(favor);
    }
    if (!test.threshold.isEmpty()) {
        infoln("skipping test case on line %d with non-default threshold: not exposed via API",
               (int)test.lineNr);
        return TRUE;
        // int32_t threshold = Integer.valueOf(test.threshold);
        // builder.internalSetThresholdDistance(threshold);
    }
    LocaleMatcher matcher = builder.build(errorCode);
    if (errorCode.errIfFailureAndReset("LocaleMatcher::Builder::build()")) {
        return FALSE;
    }

    Locale expMatchLocale("");
    Locale *expMatch = getLocaleOrNull(test.expMatch, expMatchLocale);
    if (test.expDesired.isEmpty() && test.expCombined.isEmpty()) {
        StringPiece desiredSP = test.desired.toStringPiece();
        const Locale *bestSupported = matcher.getBestMatchForListString(desiredSP, errorCode);
        if (!assertEquals("bestSupported from string",
                          locString(expMatch), locString(bestSupported))) {
            return FALSE;
        }
        LocalePriorityList desired(test.desired.toStringPiece(), errorCode);
        LocalePriorityList::Iterator desiredIter = desired.iterator();
        if (desired.getLength() == 1) {
            const Locale &desiredLocale = desiredIter.next();
            bestSupported = matcher.getBestMatch(desiredLocale, errorCode);
            UBool ok = assertEquals("bestSupported from Locale",
                                    locString(expMatch), locString(bestSupported));

            LocaleMatcher::Result result = matcher.getBestMatchResult(desiredLocale, errorCode);
            return ok & assertEquals("result.getSupportedLocale from Locale",
                                     locString(expMatch), locString(result.getSupportedLocale()));
        } else {
            bestSupported = matcher.getBestMatch(desiredIter, errorCode);
            return assertEquals("bestSupported from Locale iterator",
                                locString(expMatch), locString(bestSupported));
        }
    } else {
        LocalePriorityList desired(test.desired.toStringPiece(), errorCode);
        LocalePriorityList::Iterator desiredIter = desired.iterator();
        LocaleMatcher::Result result = matcher.getBestMatchResult(desiredIter, errorCode);
        UBool ok = assertEquals("result.getSupportedLocale from Locales",
                                locString(expMatch), locString(result.getSupportedLocale()));
        if (!test.expDesired.isEmpty()) {
            Locale expDesiredLocale("");
            Locale *expDesired = getLocaleOrNull(test.expDesired, expDesiredLocale);
            ok &= assertEquals("result.getDesiredLocale from Locales",
                               locString(expDesired), locString(result.getDesiredLocale()));
        }
        if (!test.expCombined.isEmpty()) {
            if (test.expMatch.contains("-u-")) {
                logKnownIssue("20727",
                              UnicodeString(u"ignoring makeResolvedLocale() line ") + test.lineNr);
                return ok;
            }
            Locale expCombinedLocale("");
            Locale *expCombined = getLocaleOrNull(test.expCombined, expCombinedLocale);
            Locale combined = result.makeResolvedLocale(errorCode);
            ok &= assertEquals("combined Locale from Locales",
                               locString(expCombined), locString(&combined));
        }
        return ok;
    }
}

void LocaleMatcherTest::testDataDriven() {
    IcuTestErrorCode errorCode(*this, "testDataDriven");
    CharString path(getSourceTestData(errorCode), errorCode);
    path.appendPathPart("localeMatcherTest.txt", errorCode);
    const char *codePage = "UTF-8";
    LocalUCHARBUFPointer f(ucbuf_open(path.data(), &codePage, TRUE, FALSE, errorCode));
    if(errorCode.errIfFailureAndReset("ucbuf_open(localeMatcherTest.txt)")) {
        return;
    }
    int32_t lineLength;
    const UChar *p;
    UnicodeString line;
    TestCase test;
    int32_t numPassed = 0;
    while ((p = ucbuf_readline(f.getAlias(), &lineLength, errorCode)) != nullptr &&
            errorCode.isSuccess()) {
        line.setTo(FALSE, p, lineLength);
        if (!readTestCase(line, test, errorCode)) {
            if (errorCode.errIfFailureAndReset(
                    "test data syntax error on line %d", (int)test.lineNr)) {
                infoln(line);
            }
            continue;
        }
        UBool ok = dataDriven(test, errorCode);
        if (errorCode.errIfFailureAndReset("test error on line %d", (int)test.lineNr)) {
            infoln(line);
        } else if (!ok) {
            infoln("test failure on line %d", (int)test.lineNr);
            infoln(line);
        } else {
            ++numPassed;
        }
    }
    infoln("number of passing test cases: %d", (int)numPassed);
}
