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

// 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 not match und_TW or en_Hant_TW",
               matchZh == 0.0 && matchEnHantTw == 0.0); // with changes in CLDR-1435
}

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);
}
