// © 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 <utility>

#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 testNoDefault();
    void testDemotion();
    void testDirection();
    void testMaxDistanceAndIsMatch();
    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(testNoDefault);
    TESTCASE_AUTO(testDemotion);
    TESTCASE_AUTO(testDirection);
    TESTCASE_AUTO(testMaxDistanceAndIsMatch);
    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::testNoDefault() {
    // We want nullptr instead of any default locale.
    IcuTestErrorCode errorCode(*this, "testNoDefault");
    Locale locales[] = { "fr", "en_GB", "en" };
    LocaleMatcher matcher = LocaleMatcher::Builder().
        setSupportedLocales(ARRAY_RANGE(locales)).
        setNoDefaultLocale().
        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)", "(null)", locString(best));
    LocaleMatcher::Result result = matcher.getBestMatchResult("ja_JP", errorCode);
    assertEquals("getBestMatchResult(ja_JP).supp",
                 "(null)", 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)
        // Also explicitly exercise the move copy constructor.
        LocaleMatcher built = builder.build(errorCode);
        LocaleMatcher withOneWay(std::move(built));
        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)
        // Also explicitly exercise the move assignment operator.
        LocaleMatcher onlyTwoWay = builder.build(errorCode);
        LocaleMatcher built =
            builder.setDirection(ULOCMATCH_DIRECTION_ONLY_TWO_WAY).build(errorCode);
        onlyTwoWay = std::move(built);
        Locale::RangeIterator<Locale *> desiredIter(ARRAY_RANGE(desired));
        assertEquals("only two-way", "nn",
                     locString(onlyTwoWay.getBestMatch(desiredIter, errorCode)));
    }
}

void LocaleMatcherTest::testMaxDistanceAndIsMatch() {
    IcuTestErrorCode errorCode(*this, "testMaxDistanceAndIsMatch");
    LocaleMatcher::Builder builder;
    LocaleMatcher standard = builder.build(errorCode);
    Locale germanLux("de-LU");
    Locale germanPhoenician("de-Phnx-AT");
    Locale greek("el");
    assertTrue("standard de-LU / de", standard.isMatch(germanLux, Locale::getGerman(), errorCode));
    assertFalse("standard de-Phnx-AT / de",
                standard.isMatch(germanPhoenician, Locale::getGerman(), errorCode));

    // Allow a script difference to still match.
    LocaleMatcher loose =
        builder.setMaxDistance(germanPhoenician, Locale::getGerman()).build(errorCode);
    assertTrue("loose de-LU / de", loose.isMatch(germanLux, Locale::getGerman(), errorCode));
    assertTrue("loose de-Phnx-AT / de",
               loose.isMatch(germanPhoenician, Locale::getGerman(), errorCode));
    assertFalse("loose el / de", loose.isMatch(greek, Locale::getGerman(), errorCode));

    // Allow at most a regional difference.
    LocaleMatcher regional =
        builder.setMaxDistance(Locale("de-AT"), Locale::getGerman()).build(errorCode);
    assertTrue("regional de-LU / de",
               regional.isMatch(Locale("de-LU"), Locale::getGerman(), errorCode));
    assertFalse("regional da / no", regional.isMatch(Locale("da"), Locale("no"), errorCode));
    assertFalse("regional zh-Hant / zh",
                regional.isMatch(Locale::getChinese(), Locale::getTraditionalChinese(), 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);
}
