// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html#License
/*
 ******************************************************************************************
 * Copyright (C) 2009-2015, Google, Inc.; International Business Machines Corporation and *
 * others. All Rights Reserved.                                                           *
 ******************************************************************************************
 */

package com.ibm.icu.dev.test.util;

import java.io.BufferedReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import org.junit.Test;
import org.junit.runner.RunWith;

import com.ibm.icu.dev.test.TestFmwk;
import com.ibm.icu.dev.tool.locale.LikelySubtagsBuilder;
import com.ibm.icu.impl.locale.XCldrStub.FileUtilities;
import com.ibm.icu.impl.locale.XLikelySubtags;
import com.ibm.icu.util.LocaleMatcher;
import com.ibm.icu.util.LocaleMatcher.FavorSubtag;
import com.ibm.icu.util.LocalePriorityList;
import com.ibm.icu.util.ULocale;

import junitparams.JUnitParamsRunner;
import junitparams.Parameters;

/**
 * Test the LocaleMatcher.
 *
 * @author markdavis
 */
@RunWith(JUnitParamsRunner.class)
public class LocaleMatcherTest extends TestFmwk {
    private static final ULocale ZH_MO = new ULocale("zh_MO");
    private static final ULocale ZH_HK = new ULocale("zh_HK");

    private LocaleMatcher newLocaleMatcher(LocalePriorityList build) {
        return new LocaleMatcher(build);
    }

    private LocaleMatcher newLocaleMatcher(String string) {
        return new LocaleMatcher(LocalePriorityList.add(string).build());
    }

    @Test
    public void testParentLocales() {
        assertCloser("es_AR", "es_419", "es_ES");
        assertCloser("es_AR", "es_419", "es");

        assertCloser("es_AR", "es_MX", "es");
        assertCloser("es_AR", "es_MX", "es");

        assertCloser("en_AU", "en_GB", "en_US");
        assertCloser("en_AU", "en_GB", "en");

        assertCloser("en_AU", "en_NZ", "en_US");
        assertCloser("en_AU", "en_NZ", "en");

        assertCloser("pt_AO", "pt_PT", "pt_BR");
        assertCloser("pt_AO", "pt_PT", "pt");

        assertCloser("zh_HK", "zh_MO", "zh_TW");
        assertCloser("zh_HK", "zh_MO", "zh_CN");
        assertCloser("zh_HK", "zh_MO", "zh");
    }

    private void assertCloser(String a, String closer, String further) {
        LocaleMatcher matcher = newLocaleMatcher(further + ", " + closer);
        assertEquals("test " + a + " is closer to " + closer + " than to " + further, new ULocale(closer), matcher.getBestMatch(a));
        matcher = newLocaleMatcher(closer + ", " + further);
        assertEquals("test " + a + " is closer to " + closer + " than to " + further, new ULocale(closer), matcher.getBestMatch(a));
    }

    @Test
    public void testChinese() {
        LocaleMatcher matcher = newLocaleMatcher("zh_CN, zh_TW, iw");
        ULocale taiwanChinese = new ULocale("zh_TW");
        ULocale chinaChinese = new ULocale("zh_CN");
        assertEquals("zh_CN, zh_TW, iw;", taiwanChinese, matcher.getBestMatch("zh_Hant_TW"));
        assertEquals("zh_CN, zh_TW, iw;", taiwanChinese, matcher.getBestMatch("zh_Hant"));
        assertEquals("zh_CN, zh_TW, iw;", taiwanChinese, matcher.getBestMatch("zh_TW"));
        assertEquals("zh_CN, zh_TW, iw;", chinaChinese, matcher.getBestMatch("zh_Hans_CN"));
        assertEquals("zh_CN, zh_TW, iw;", chinaChinese, matcher.getBestMatch("zh_CN"));
        assertEquals("zh_CN, zh_TW, iw;", chinaChinese, matcher.getBestMatch("zh"));
        assertEquals("zh_CN, zh_TW, iw;", taiwanChinese, matcher.getBestMatch("zh_Hant_HK"));
    }

    @Test
    public void testenGB() {
        final LocaleMatcher matcher = newLocaleMatcher("fr, en, en_GB, es_MX, es_419, es");
        assertEquals("en_GB", matcher.getBestMatch("en_NZ").toString());
        assertEquals("es", matcher.getBestMatch("es_ES").toString());
        assertEquals("es_419", matcher.getBestMatch("es_AR").toString());
        assertEquals("es_MX", matcher.getBestMatch("es_MX").toString());
    }

    @Test
    public void testFallbacks() {
        LocalePriorityList lpl = LocalePriorityList.add("en, hi").build();
        final LocaleMatcher matcher = newLocaleMatcher(lpl);
        assertEquals("hi", matcher.getBestMatch("sa").toString());
    }

    @Test
    public void testBasics() {
        LocaleMatcher matcher = newLocaleMatcher(
                LocalePriorityList.
                    add(ULocale.FRENCH).add(ULocale.UK).add(ULocale.ENGLISH).
                    build());
        logln(matcher.toString());

        assertEquals(ULocale.UK, matcher.getBestMatch(ULocale.UK));
        assertEquals(ULocale.ENGLISH, matcher.getBestMatch(ULocale.US));
        assertEquals(ULocale.FRENCH, matcher.getBestMatch(ULocale.FRANCE));
        assertEquals(ULocale.FRENCH, matcher.getBestMatch(ULocale.JAPAN));

        // API coverage
        List<Locale> locales = new ArrayList<>();
        locales.add(Locale.FRENCH);
        locales.add(Locale.UK);
        matcher = LocaleMatcher.builder().
                setSupportedLocales(locales).addSupportedLocale(Locale.ENGLISH).
                setDefaultLocale(Locale.GERMAN).build();
        assertEquals(ULocale.UK, matcher.getBestMatch(ULocale.UK));
        assertEquals(ULocale.ENGLISH, matcher.getBestMatch(ULocale.US));
        assertEquals(ULocale.FRENCH, matcher.getBestMatch(ULocale.FRANCE));
        assertEquals(ULocale.GERMAN, matcher.getBestMatch(ULocale.JAPAN));

        ULocale udesired = new ULocale("en_GB");  // distinct object from ULocale.UK
        LocaleMatcher.Result result = matcher.getBestMatchResult(udesired);
        assertTrue("exactly desired en-GB object", udesired == result.getDesiredULocale());
        assertEquals(Locale.UK, result.getDesiredLocale());
        assertEquals(0, result.getDesiredIndex());
        assertEquals(ULocale.UK, result.getSupportedULocale());
        assertEquals(Locale.UK, result.getSupportedLocale());
        assertEquals(1, result.getSupportedIndex());

        LocalePriorityList list = LocalePriorityList.add(ULocale.JAPAN, ULocale.US).build();
        result = matcher.getBestMatchResult(list);
        assertEquals(1, result.getDesiredIndex());
        assertEquals(Locale.US, result.getDesiredLocale());

        Locale desired = new Locale("en", "US");  // distinct object from Locale.US
        result = matcher.getBestLocaleResult(desired);
        assertEquals(ULocale.US, result.getDesiredULocale());
        assertTrue("exactly desired en-US object", desired == result.getDesiredLocale());
        assertEquals(0, result.getDesiredIndex());
        assertEquals(ULocale.ENGLISH, result.getSupportedULocale());
        assertEquals(Locale.ENGLISH, result.getSupportedLocale());
        assertEquals(2, result.getSupportedIndex());

        result = matcher.getBestMatchResult(ULocale.JAPAN);
        assertNull(result.getDesiredLocale());
        assertNull(result.getDesiredULocale());
        assertEquals(-1, result.getDesiredIndex());
        assertEquals(ULocale.GERMAN, result.getSupportedULocale());
        assertEquals(Locale.GERMAN, result.getSupportedLocale());
        assertEquals(-1, result.getSupportedIndex());
    }

    private static final String locString(ULocale loc) {
        return loc != null ? loc.getName() : "(null)";
    }

    @Test
    public void testSupportedDefault() {
        // The default locale is one of the supported locales.
        List<ULocale> locales = Arrays.asList(
                new ULocale("fr"), new ULocale("en_GB"), new ULocale("en"));
        LocaleMatcher matcher = LocaleMatcher.builder().
            setSupportedULocales(locales).
            setDefaultULocale(locales.get(1)).
            build();
        ULocale best = matcher.getBestMatch("en_GB");
        assertEquals("getBestMatch(en_GB)", "en_GB", locString(best));
        best = matcher.getBestMatch("en_US");
        assertEquals("getBestMatch(en_US)", "en", locString(best));
        best = matcher.getBestMatch("fr_FR");
        assertEquals("getBestMatch(fr_FR)", "fr", locString(best));
        best = matcher.getBestMatch("ja_JP");
        assertEquals("getBestMatch(ja_JP)", "en_GB", locString(best));
        LocaleMatcher.Result result = matcher.getBestMatchResult(new ULocale("ja_JP"));
        assertEquals("getBestMatchResult(ja_JP).supp",
                     "en_GB", locString(result.getSupportedULocale()));
        assertEquals("getBestMatchResult(ja_JP).suppIndex",
                     -1, result.getSupportedIndex());
    }

    @Test
    public void testUnsupportedDefault() {
        // The default locale does not match any of the supported locales.
        List<ULocale> locales = Arrays.asList(
                new ULocale("fr"), new ULocale("en_GB"), new ULocale("en"));
        LocaleMatcher matcher = LocaleMatcher.builder().
            setSupportedULocales(locales).
            setDefaultULocale(new ULocale("de")).
            build();
        ULocale best = matcher.getBestMatch("en_GB");
        assertEquals("getBestMatch(en_GB)", "en_GB", locString(best));
        best = matcher.getBestMatch("en_US");
        assertEquals("getBestMatch(en_US)", "en", locString(best));
        best = matcher.getBestMatch("fr_FR");
        assertEquals("getBestMatch(fr_FR)", "fr", locString(best));
        best = matcher.getBestMatch("ja_JP");
        assertEquals("getBestMatch(ja_JP)", "de", locString(best));
        LocaleMatcher.Result result = matcher.getBestMatchResult(new ULocale("ja_JP"));
        assertEquals("getBestMatchResult(ja_JP).supp",
                     "de", locString(result.getSupportedULocale()));
        assertEquals("getBestMatchResult(ja_JP).suppIndex",
                     -1, result.getSupportedIndex());
    }

    @Test
    public void testNoDefault() {
        // We want null instead of any default locale.
        List<ULocale> locales = Arrays.asList(
                new ULocale("fr"), new ULocale("en_GB"), new ULocale("en"));
        LocaleMatcher matcher = LocaleMatcher.builder().
            setSupportedULocales(locales).
            setNoDefaultLocale().
            build();
        ULocale best = matcher.getBestMatch("en_GB");
        assertEquals("getBestMatch(en_GB)", "en_GB", locString(best));
        best = matcher.getBestMatch("en_US");
        assertEquals("getBestMatch(en_US)", "en", locString(best));
        best = matcher.getBestMatch("fr_FR");
        assertEquals("getBestMatch(fr_FR)", "fr", locString(best));
        best = matcher.getBestMatch("ja_JP");
        assertEquals("getBestMatch(ja_JP)", "(null)", locString(best));
        LocaleMatcher.Result result = matcher.getBestMatchResult(new ULocale("ja_JP"));
        assertEquals("getBestMatchResult(ja_JP).supp",
                     "(null)", locString(result.getSupportedULocale()));
        assertEquals("getBestMatchResult(ja_JP).suppIndex",
                     -1, result.getSupportedIndex());
    }

    @Test
    public void testFallback() {
        // check that script fallbacks are handled right
        final LocaleMatcher matcher = newLocaleMatcher("zh_CN, zh_TW, iw");
        assertEquals(new ULocale("zh_TW"), matcher.getBestMatch("zh_Hant"));
        assertEquals(new ULocale("zh_CN"), matcher.getBestMatch("zh"));
        assertEquals(new ULocale("zh_CN"), matcher.getBestMatch("zh_Hans_CN"));
        assertEquals(new ULocale("zh_TW"), matcher.getBestMatch("zh_Hant_HK"));
        assertEquals(new ULocale("iw"), matcher.getBestMatch("iw_IT"));
    }

    @Test
    public void testSpecials() {
        // check that nearby languages are handled
        final LocaleMatcher matcher = newLocaleMatcher("en, fil, ro, nn");
        assertEquals(new ULocale("fil"), matcher.getBestMatch("tl"));
        assertEquals(new ULocale("ro"), matcher.getBestMatch("mo"));
        assertEquals(new ULocale("nn"), matcher.getBestMatch("nb"));
        // make sure default works
        assertEquals(new ULocale("en"), matcher.getBestMatch("ja"));
    }

    @Test
    public void testRegionalSpecials() {
        // verify that en_AU is closer to en_GB than to en (which is en_US)
        final LocaleMatcher matcher = newLocaleMatcher("en, en_GB, es, es_419");
        assertEquals("es_MX in {en, en_GB, es, es_419}", new ULocale("es_419"), matcher.getBestMatch("es_MX"));
        assertEquals("en_AU in {en, en_GB, es, es_419}", new ULocale("en_GB"), matcher.getBestMatch("en_AU"));
        assertEquals("es_ES in {en, en_GB, es, es_419}", new ULocale("es"), matcher.getBestMatch("es_ES"));
    }

    @Test
    public void testHK() {
        // HK and MO are closer to each other for Hant than to TW
        final LocaleMatcher matcher = newLocaleMatcher("zh, zh_TW, zh_MO");
        assertEquals("zh_HK in {zh, zh_TW, zh_MO}", ZH_MO, matcher.getBestMatch("zh_HK"));
        final LocaleMatcher matcher2 = newLocaleMatcher("zh, zh_TW, zh_HK");
        assertEquals("zh_MO in {zh, zh_TW, zh_HK}", ZH_HK, matcher2.getBestMatch("zh_MO"));
    }

    @Test
    public void TestLocaleMatcherCoverage() {
        // Add tests for better code coverage
        LocaleMatcher matcher = newLocaleMatcher(LocalePriorityList.add(null, 0).build());
        logln(matcher.toString());
    }

    private void assertEquals(Object expected, Object string) {
        assertEquals("", expected, string);
    }

    private void assertNull(Object bestMatch) {
        assertNull("", bestMatch);
    }

    @Test
    public void testEmpty() {
        final LocaleMatcher matcher = LocaleMatcher.builder().build();
        assertNull(matcher.getBestMatch(ULocale.FRENCH));
        LocaleMatcher.Result result = matcher.getBestMatchResult(ULocale.FRENCH);
        assertNull(result.getDesiredULocale());
        assertNull(result.getDesiredLocale());
        assertEquals(-1, result.getDesiredIndex());
        assertNull(result.getSupportedULocale());
        assertNull(result.getSupportedLocale());
        assertEquals(-1, result.getSupportedIndex());
    }

    static final ULocale ENGLISH_CANADA = new ULocale("en_CA");

    private static double match(ULocale a, ULocale b) {
        final LocaleMatcher matcher = new LocaleMatcher("");
        return matcher.match(a, null, b, null);
    }

    @Test
    public void testMatch_exact() {
        assertEquals(1.0, match(ENGLISH_CANADA, ENGLISH_CANADA));
    }

    @Test
    public void testMatch_none() {
        double match = match(new ULocale("ar_MK"), ENGLISH_CANADA);
        assertTrue("Actual >= 0: " + match, 0 <= match);
        assertTrue("Actual < 0.2 (~ language + script distance): " + match, 0.2 > match);
    }

    @Test
    public void testMatch_matchOnMaximized() {
        ULocale undTw = new ULocale("und_TW");
        ULocale zhHant = new ULocale("zh_Hant");
        double matchZh = match(undTw, new ULocale("zh"));
        double matchZhHant = match(undTw, zhHant);
        assertTrue("und_TW should be closer to zh_Hant (" + matchZhHant +
            ") than to zh (" + matchZh + ")",
            matchZh < matchZhHant);
        double matchEnHantTw = match(new ULocale("en_Hant_TW"), zhHant);
        assertTrue("zh_Hant should be closer to und_TW (" + matchZhHant +
            ") than to en_Hant_TW (" + matchEnHantTw + ")",
            matchEnHantTw < matchZhHant);
        assertTrue("zh should be closer to und_TW (" + matchZh +
            ") than to en_Hant_TW (" + matchEnHantTw + ")",
            matchEnHantTw < matchZh);
    }

    @Test
    public void testResolvedLocale() {
        LocaleMatcher matcher = LocaleMatcher.builder().
            addSupportedULocale(new ULocale("ar-EG")).
            build();
        ULocale desired = new ULocale("ar-SA-u-nu-latn");
        LocaleMatcher.Result result = matcher.getBestMatchResult(desired);
        assertEquals("best", "ar_EG", result.getSupportedLocale().toString());
        ULocale resolved = result.makeResolvedULocale();
        assertEquals("ar-EG + ar-SA-u-nu-latn = ar-SA-u-nu-latn",
                     "ar-SA-u-nu-latn",
                     resolved.toLanguageTag());
    }

    @Test
    public void testMatchGrandfatheredCode() {
        final LocaleMatcher matcher = newLocaleMatcher("fr, i_klingon, en_Latn_US");
        assertEquals("en_Latn_US", matcher.getBestMatch("en_GB_oed").toString());
        // assertEquals("tlh", matcher.getBestMatch("i_klingon").toString());
    }

    @Test
    public void testGetBestMatchForList_exactMatch() {
        final LocaleMatcher matcher = newLocaleMatcher("fr, en_GB, ja, es_ES, es_MX");
        assertEquals("ja", matcher.getBestMatch("ja, de").toString());
    }

    @Test
    public void testGetBestMatchForList_simpleVariantMatch() {
        final LocaleMatcher matcher = newLocaleMatcher("fr, en_GB, ja, es_ES, es_MX");
        // Intentionally avoiding a perfect_match or two candidates for variant
        // matches.
        assertEquals("en_GB", matcher.getBestMatch("de, en_US").toString());
        // Fall back.
        assertEquals("fr", matcher.getBestMatch("de, zh").toString());
    }

    @Test
    public void testGetBestMatchForList_matchOnMaximized() {
        final LocaleMatcher matcher = newLocaleMatcher("en, ja");
        // final LocaleMatcher matcher =
        // newLocaleMatcher("fr, en, ja, es_ES, es_MX");
        // Check that if the preference is maximized already, it works as well.
        assertEquals("Match for ja_Jpan_JP (maximized already)",
            "ja", matcher.getBestMatch("ja_Jpan_JP, en-AU").toString());
        if (true)
            return;
        // ja_JP matches ja on likely subtags, and it's listed first, thus it
        // wins over
        // thus it wins over the second preference en_GB.
        assertEquals("Match for ja_JP, with likely region subtag",
            "ja", matcher.getBestMatch("ja_JP, en_US").toString());
        // Check that if the preference is maximized already, it works as well.
        assertEquals("Match for ja_Jpan_JP (maximized already)",
            "ja", matcher.getBestMatch("ja_Jpan_JP, en_US").toString());
    }

    @Test
    public void testGetBestMatchForList_noMatchOnMaximized() {
        // Regression test for http://b/5714572 .
        final LocaleMatcher matcher = newLocaleMatcher("en, de, fr, ja");
        // de maximizes to de_DE. Pick the exact match for the secondary
        // language instead.
        assertEquals("de", matcher.getBestMatch("de_CH, fr").toString());
    }

    @Test
    public void testBestMatchForTraditionalChinese() {
        // Scenario: An application that only supports Simplified Chinese (and
        // some other languages),
        // but does not support Traditional Chinese. zh_Hans_CN could be
        // replaced with zh_CN, zh, or
        // zh_Hans, it wouldn't make much of a difference.
        final LocaleMatcher matcher = newLocaleMatcher("fr, zh_Hans_CN, en_US");

        // The script distance (simplified vs. traditional Han) is considered
        // small enough
        // to be an acceptable match. The regional difference is considered
        // almost insignificant.
        assertEquals("zh_Hans_CN", matcher.getBestMatch("zh_TW").toString());
        assertEquals("zh_Hans_CN", matcher.getBestMatch("zh_Hant").toString());

        // For geo_political reasons, you might want to avoid a zh_Hant ->
        // zh_Hans match.
        // In this case, if zh_TW, zh_HK or a tag starting with zh_Hant is
        // requested, you can
        // change your call to getBestMatch to include a 2nd language
        // preference.
        // "en" is a better match since its distance to "en_US" is closer than
        // the distance
        // from "zh_TW" to "zh_CN" (script distance).
        assertEquals("en_US", matcher.getBestMatch("zh_TW, en").toString());
        assertEquals("en_US", matcher.getBestMatch("zh_Hant_CN, en").toString());
        assertEquals("zh_Hans_CN", matcher.getBestMatch("zh_Hans, en").toString());
    }

    @Test
    public void testUndefined() {
        // When the undefined language doesn't match anything in the list,
        // getBestMatch returns
        // the default, as usual.
        LocaleMatcher matcher = newLocaleMatcher("it,fr");
        assertEquals("it", matcher.getBestMatch("und").toString());

        // When it *does* occur in the list, BestMatch returns it, as expected.
        matcher = newLocaleMatcher("it,und");
        assertEquals("", matcher.getBestMatch("und").toString());

        // The unusual part:
        // max("und") = "en_Latn_US", and since matching is based on maximized
        // tags, the undefined
        // language would normally match English. But that would produce the
        // counterintuitive results
        // that getBestMatch("und", LocaleMatcher("it,en")) would be "en", and
        // getBestMatch("en", LocaleMatcher("it,und")) would be "und".
        //
        // To avoid that, we change the matcher's definitions of max
        // (AddLikelySubtagsWithDefaults)
        // so that max("und")="und". That produces the following, more desirable
        // results:
        matcher = newLocaleMatcher("it,en");
        assertEquals("it", matcher.getBestMatch("und").toString());
        matcher = newLocaleMatcher("it,und");
        assertEquals("it", matcher.getBestMatch("en").toString());
    }

    @Test
    public void testGetBestMatch_googlePseudoLocales() {
        // Google pseudo locales are primarily based on variant subtags.
        // (See below for the region code based fall back options.)
        final LocaleMatcher matcher = newLocaleMatcher(
            "fr, pt");
        assertEquals("fr", matcher.getBestMatch("de").toString());
        assertEquals("fr", matcher.getBestMatch("en_US").toString());
        assertEquals("fr", matcher.getBestMatch("en").toString());
        assertEquals("pt", matcher.getBestMatch("pt_BR").toString());
    }

    @Test
    public void testGetBestMatch_regionDistance() {
        LocaleMatcher matcher = newLocaleMatcher("es_AR, es");
        assertEquals("es_AR", matcher.getBestMatch("es_MX").toString());

        matcher = newLocaleMatcher("fr, en, en_GB");
        assertEquals("en_GB", matcher.getBestMatch("en_CA").toString());

        matcher = newLocaleMatcher("de_AT, de_DE, de_CH");
        assertEquals("de_DE", matcher.getBestMatch("de").toString());

        showDistance(matcher, "en", "en_CA");
        showDistance(matcher, "en_CA", "en");
        showDistance(matcher, "en_US", "en_CA");
        showDistance(matcher, "en_CA", "en_US");
        showDistance(matcher, "en_GB", "en_CA");
        showDistance(matcher, "en_CA", "en_GB");
        showDistance(matcher, "en", "en_UM");
        showDistance(matcher, "en_UM", "en");
    }

    private void showDistance(LocaleMatcher matcher, String desired, String supported) {
        ULocale desired2 = new ULocale(desired);
        ULocale supported2 = new ULocale(supported);
        double distance = matcher.match(desired2, ULocale.addLikelySubtags(desired2), supported2, ULocale.addLikelySubtags(supported2));
        logln(desired + " to " + supported + " :\t" + distance);
    }

    /**
     * If all the base languages are the same, then each sublocale matches
     * itself most closely
     */
    @Test
    public void testExactMatches() {
        String lastBase = "";
        TreeSet<ULocale> sorted = new TreeSet<>();
        for (ULocale loc : ULocale.getAvailableLocales()) {
            String language = loc.getLanguage();
            if (!lastBase.equals(language)) {
                check(sorted);
                sorted.clear();
                lastBase = language;
            }
            sorted.add(loc);
        }
        check(sorted);
    }

    private void check(Set<ULocale> sorted) {
        if (sorted.isEmpty()) {
            return;
        }
        check2(sorted);
        ULocale first = sorted.iterator().next();
        ULocale max = ULocale.addLikelySubtags(first);
        sorted.add(max);
        check2(sorted);
    }

    private static final ULocale posix = new ULocale("en_US_POSIX");

    /**
     * @param sorted
     */
    private void check2(Set<ULocale> sorted) {
        logln("Checking: " + sorted);
        LocaleMatcher matcher = newLocaleMatcher(
            LocalePriorityList.add(
                sorted.toArray(new ULocale[sorted.size()]))
            .build());
        for (ULocale loc : sorted) {
            // The result may not be the exact same locale, but it must be equivalent.
            // Variants and extensions are ignored.
            if (loc.equals(posix)) { continue; }
            ULocale max = ULocale.addLikelySubtags(loc);
            ULocale best = matcher.getBestMatch(loc);
            ULocale maxBest = ULocale.addLikelySubtags(best);
            assertEquals(loc.toString(), max, maxBest);
        }
    }

    @Test
    public void testAsymmetry() {
        LocaleMatcher matcher;
        matcher = new LocaleMatcher("mul, nl");
        assertEquals("nl", matcher.getBestMatch("af").toString()); // af => nl

        matcher = new LocaleMatcher("mul, af");
        assertEquals("mul", matcher.getBestMatch("nl").toString()); // but nl !=> af
    }


    @Test
    public void testGetBestMatchForList_matchOnMaximized2() {
        final LocaleMatcher matcher = newLocaleMatcher("fr, en-GB, ja, es-ES, es-MX");
        // ja-JP matches ja on likely subtags, and it's listed first, thus it wins over
        // thus it wins over the second preference en-GB.
        assertEquals("Match for ja-JP, with likely region subtag",
            "ja", matcher.getBestMatch("ja-JP, en-GB").toString());
        // Check that if the preference is maximized already, it works as well.
        assertEquals("Match for ja-Jpan-JP (maximized already)",
            "ja", matcher.getBestMatch("ja-Jpan-JP, en-GB").toString());
    }

    @Test
    public void testGetBestMatchForList_closeEnoughMatchOnMaximized() {
        final LocaleMatcher matcher = newLocaleMatcher("en-GB, en, de, fr, ja");
        assertEquals("de", matcher.getBestMatch("de-CH, fr").toString());
        assertEquals("en", matcher.getBestMatch("en-US, ar, nl, de, ja").toString());
    }

    @Test
    public void testGetBestMatchForPortuguese() {
        final LocaleMatcher withPTExplicit = newLocaleMatcher("pt_PT, pt_BR, es, es_419");
        final LocaleMatcher withPTImplicit = newLocaleMatcher("pt_PT, pt, es, es_419");
        // Could happen because "pt_BR" is a tier_1 language and "pt_PT" is tier_2.

        final LocaleMatcher withoutPT = newLocaleMatcher("pt_BR, es, es_419");
        // European user who prefers Spanish over Brazilian Portuguese as a fallback.

        assertEquals("pt_PT", withPTExplicit.getBestMatch("pt_PT, es, pt").toString());
        assertEquals("pt_PT", withPTImplicit.getBestMatch("pt_PT, es, pt").toString());
        // The earlier pt_PT vs. pt_BR region mismatch is as good as the later es perfect match
        // because of the demotion per desired locale.
        assertEquals("pt_BR", withoutPT.getBestMatch("pt_PT, es, pt").toString());

        // Brazilian user who prefers South American Spanish over European Portuguese as a fallback.
        // The asymmetry between this case and above is because it's "pt_PT" that's missing between the
        // matchers as "pt_BR" is a much more common language.
        assertEquals("pt_BR", withPTExplicit.getBestMatch("pt, es_419, pt_PT").toString());
        assertEquals("pt", withPTImplicit.getBestMatch("pt, es_419, pt_PT").toString());
        assertEquals("pt_BR", withoutPT.getBestMatch("pt, es_419, pt_PT").toString());

        // Code that adds the user's country can get "pt_US" for a user's language.
        // That should fall back to "pt_BR".
        assertEquals("pt_BR", withPTExplicit.getBestMatch("pt_US, pt_PT").toString());
        assertEquals("pt", withPTImplicit.getBestMatch("pt_US, pt_PT").toString());
    }

    @Test
    public void testVariantWithScriptMatch() {
        final LocaleMatcher matcher = newLocaleMatcher("fr, en, sv");
        assertEquals("en", matcher.getBestMatch("en-GB").toString());
        assertEquals("en", matcher.getBestMatch("en-GB, sv").toString());
    }

    @Test
    public void testVariantWithScriptMatch2() {
        final LocaleMatcher matcher = newLocaleMatcher("en, sv");
        assertEquals("en", matcher.getBestMatch("en-GB, sv").toString());
    }

    @Test
    public void Test8288() {
        final LocaleMatcher matcher = newLocaleMatcher("it, en");
        assertEquals("it", matcher.getBestMatch("und").toString());
        assertEquals("en", matcher.getBestMatch("und, en").toString());
    }

    @Test
    public void testDemotion() {
        LocalePriorityList supported = LocalePriorityList.add("fr, de-CH, it").build();
        LocalePriorityList desired = LocalePriorityList.add("fr-CH, de-CH, it").build();
        LocaleMatcher noDemotion = LocaleMatcher.builder().
                setSupportedULocales(supported.getULocales()).
                setDemotionPerDesiredLocale(LocaleMatcher.Demotion.NONE).build();
        assertEquals("no demotion", new ULocale("de-CH"), noDemotion.getBestMatch(desired));

        LocaleMatcher regionDemotion = LocaleMatcher.builder().
                setSupportedULocales(supported.getULocales()).
                setDemotionPerDesiredLocale(LocaleMatcher.Demotion.REGION).build();
        assertEquals("region demotion", ULocale.FRENCH, regionDemotion.getBestMatch(desired));
    }

    @Test
    public void testDirection() {
        List<ULocale> desired = Arrays.asList(new ULocale("arz-EG"), new ULocale("nb-DK"));
        LocaleMatcher.Builder builder =
                LocaleMatcher.builder().setSupportedLocales("ar, nn");
        // arz is a close one-way match to ar, and the region matches.
        // (Egyptian Arabic vs. Arabic)
        LocaleMatcher withOneWay = builder.build();
        assertEquals("with one-way", "ar", withOneWay.getBestMatch(desired).toString());
        // nb is a less close two-way match to nn, and the regions differ.
        // (Norwegian Bokmal vs. Nynorsk)
        LocaleMatcher onlyTwoWay = builder.setDirection(LocaleMatcher.Direction.ONLY_TWO_WAY).build();
        assertEquals("only two-way", "nn", onlyTwoWay.getBestMatch(desired).toString());
    }

    @Test
    public void testCanonicalize() {
        LocaleMatcher matcher = LocaleMatcher.builder().build();
        assertEquals("bh --> bho", new ULocale("bho"), matcher.canonicalize(new ULocale("bh")));
        assertEquals("mo-200 --> ro-CZ", new ULocale("ro_CZ"),
                matcher.canonicalize(new ULocale("mo_200")));
    }

    private static final class PerfCase {
        ULocale desired;
        ULocale expectedShort;
        ULocale expectedLong;
        ULocale expectedVeryLong;

        PerfCase(String des, String expShort, String expLong, String expVeryLong) {
            desired = new ULocale(des);
            expectedShort = new ULocale(expShort);
            expectedLong = new ULocale(expLong);
            expectedVeryLong = new ULocale(expVeryLong);
        }
    }

    private static final int WARM_UP_ITERATIONS = 1000;
    private static final int BENCHMARK_ITERATIONS = 20000;

    @Test
    public void testPerf() {
        final String shortList = "en, sv";
        final String longList = "af, am, ar, az, be, bg, bn, bs, ca, cs, cy, cy, da, de, " +
                "el, en, en-GB, es, es-419, et, eu, fa, fi, fil, fr, ga, gl, gu, " +
                "hi, hr, hu, hy, id, is, it, iw, ja, ka, kk, km, kn, ko, ky, lo, lt, lv, " +
                "mk, ml, mn, mr, ms, my, ne, nl, no, pa, pl, pt, pt-PT, ro, ru, " +
                "si, sk, sl, sq, sr, sr-Latn, sv, sw, ta, te, th, tr, uk, ur, uz, vi, " +
                "zh-CN, zh-TW, zu";
        final String veryLongList = "af, af_NA, af_ZA, agq, agq_CM, ak, ak_GH, am, am_ET, " +
                "ar, ar_001, ar_AE, ar_BH, ar_DJ, ar_DZ, ar_EG, ar_EH, ar_ER, ar_IL, ar_IQ, " +
                "ar_JO, ar_KM, ar_KW, ar_LB, ar_LY, ar_MA, ar_MR, ar_OM, ar_PS, ar_QA, " +
                "ar_SA, ar_SD, ar_SO, ar_SS, ar_SY, ar_TD, ar_TN, ar_YE, as, as_IN, asa, asa_TZ, " +
                "ast, ast_ES, az, az_Cyrl, az_Cyrl_AZ, az_Latn, az_Latn_AZ, " +
                "bas, bas_CM, be, be_BY, bem, bem_ZM, bez, bez_TZ, bg, bg_BG, bm, bm_ML, " +
                "bn, bn_BD, bn_IN, bo, bo_CN, bo_IN, br, br_FR, brx, brx_IN, " +
                "bs, bs_Cyrl, bs_Cyrl_BA, bs_Latn, bs_Latn_BA, ca, ca_AD, ca_ES, ca_ES_VALENCIA, " +
                "ca_FR, ca_IT, ce, ce_RU, cgg, cgg_UG, chr, chr_US, ckb, ckb_IQ, ckb_IR, cs, cs_CZ, " +
                "cu, cu_RU, cy, cy_GB, da, da_DK, da_GL, dav, dav_KE, de, de_AT, de_BE, de_CH, " +
                "de_DE, de_LI, de_LU, dje, dje_NE, dsb, dsb_DE, dua, dua_CM, dyo, dyo_SN, dz, dz_BT, " +
                // removed en_001 to avoid exact match
                "ebu, ebu_KE, ee, ee_GH, ee_TG, el, el_CY, el_GR, en, en_150, " +
                "en_AG, en_AI, en_AS, en_AT, en_AU, en_BB, en_BE, en_BI, en_BM, en_BS, en_BW, " +
                "en_BZ, en_CA, en_CC, en_CH, en_CK, en_CM, en_CX, en_CY, en_DE, en_DG, en_DK, " +
                "en_DM, en_ER, en_FI, en_FJ, en_FK, en_FM, en_GB, en_GD, en_GG, en_GH, en_GI, " +
                "en_GM, en_GU, en_GY, en_HK, en_IE, en_IL, en_IM, en_IN, en_IO, en_JE, en_JM, " +
                "en_KE, en_KI, en_KN, en_KY, en_LC, en_LR, en_LS, en_MG, en_MH, en_MO, en_MP, " +
                "en_MS, en_MT, en_MU, en_MW, en_MY, en_NA, en_NF, en_NG, en_NL, en_NR, en_NU, " +
                "en_NZ, en_PG, en_PH, en_PK, en_PN, en_PR, en_PW, en_RW, en_SB, en_SC, en_SD, " +
                "en_SE, en_SG, en_SH, en_SI, en_SL, en_SS, en_SX, en_SZ, en_TC, en_TK, en_TO, " +
                "en_TT, en_TV, en_TZ, en_UG, en_UM, en_US, en_US_POSIX, en_VC, en_VG, en_VI, " +
                "en_VU, en_WS, en_ZA, en_ZM, en_ZW, eo, eo_001, es, es_419, es_AR, es_BO, es_CL, " +
                "es_CO, es_CR, es_CU, es_DO, es_EA, es_EC, es_ES, es_GQ, es_GT, es_HN, es_IC, " +
                "es_MX, es_NI, es_PA, es_PE, es_PH, es_PR, es_PY, es_SV, es_US, es_UY, es_VE, " +
                "et, et_EE, eu, eu_ES, ewo, ewo_CM, fa, fa_AF, fa_IR, ff, ff_CM, ff_GN, ff_MR, " +
                "ff_SN, fi, fi_FI, fil, fil_PH, fo, fo_DK, fo_FO, fr, fr_BE, fr_BF, fr_BI, fr_BJ, " +
                "fr_BL, fr_CA, fr_CD, fr_CF, fr_CG, fr_CH, fr_CI, fr_CM, fr_DJ, fr_DZ, " +
                "fr_FR, fr_GA, fr_GF, fr_GN, fr_GP, fr_GQ, fr_HT, fr_KM, fr_LU, fr_MA, fr_MC, " +
                "fr_MF, fr_MG, fr_ML, fr_MQ, fr_MR, fr_MU, fr_NC, fr_NE, fr_PF, fr_PM, fr_RE, " +
                "fr_RW, fr_SC, fr_SN, fr_SY, fr_TD, fr_TG, fr_TN, fr_VU, fr_WF, fr_YT, " +
                "fur, fur_IT, fy, fy_NL, ga, ga_IE, gd, gd_GB, gl, gl_ES, gsw, gsw_CH, gsw_FR, " +
                "gsw_LI, gu, gu_IN, guz, guz_KE, gv, gv_IM, ha, ha_GH, ha_NE, ha_NG, haw, haw_US, " +
                "he, he_IL, hi, hi_IN, hr, hr_BA, hr_HR, hsb, hsb_DE, hu, hu_HU, hy, hy_AM, " +
                "id, id_ID, ig, ig_NG, ii, ii_CN, is, is_IS, it, it_CH, it_IT, it_SM, ja, ja_JP, " +
                "jgo, jgo_CM, jmc, jmc_TZ, ka, ka_GE, kab, kab_DZ, kam, kam_KE, kde, kde_TZ, " +
                "kea, kea_CV, khq, khq_ML, ki, ki_KE, kk, kk_KZ, kkj, kkj_CM, kl, kl_GL, " +
                "kln, kln_KE, km, km_KH, kn, kn_IN, ko, ko_KP, ko_KR, kok, kok_IN, " +
                "ks, ks_IN, ksb, ksb_TZ, ksf, ksf_CM, ksh, ksh_DE, kw, kw_GB, ky, ky_KG, " +
                "lag, lag_TZ, lb, lb_LU, lg, lg_UG, lkt, lkt_US, ln, ln_AO, ln_CD, ln_CF, ln_CG, " +
                "lo, lo_LA, lrc, lrc_IQ, lrc_IR, lt, lt_LT, lu, lu_CD, luo, luo_KE, luy, luy_KE, " +
                "lv, lv_LV, mas, mas_KE, mas_TZ, mer, mer_KE, mfe, mfe_MU, mg, mg_MG, " +
                "mgh, mgh_MZ, mgo, mgo_CM, mk, mk_MK, ml, ml_IN, mn, mn_MN, mr, mr_IN, ms, ms_BN, " +
                "ms_MY, ms_SG, mt, mt_MT, mua, mua_CM, my, my_MM, mzn, mzn_IR, naq, naq_NA, " +
                "nb, nb_NO, nb_SJ, nd, nd_ZW, ne, ne_IN, ne_NP, nl, nl_AW, nl_BE, nl_BQ, nl_CW, " +
                "nl_NL, nl_SR, nl_SX, nmg, nmg_CM, nn, nn_NO, nnh, nnh_CM, nus, nus_SS, nyn, " +
                "nyn_UG, om, om_ET, om_KE, or, or_IN, os, os_GE, os_RU, pa, pa_Arab, pa_Arab_PK, " +
                "pa_Guru, pa_Guru_IN, pl, pl_PL, prg, prg_001, ps, ps_AF, pt, pt_AO, pt_BR, " +
                "pt_CV, pt_GW, pt_MO, pt_MZ, pt_PT, pt_ST, pt_TL, qu, qu_BO, qu_EC, qu_PE, rm, " +
                "rm_CH, rn, rn_BI, ro, ro_MD, ro_RO, rof, rof_TZ, root, ru, ru_BY, ru_KG, ru_KZ, " +
                "ru_MD, ru_RU, ru_UA, rw, rw_RW, rwk, rwk_TZ, sah, sah_RU, saq, saq_KE, sbp, " +
                "sbp_TZ, se, se_FI, se_NO, se_SE, seh, seh_MZ, ses, ses_ML, sg, sg_CF, shi, " +
                "shi_Latn, shi_Latn_MA, shi_Tfng, shi_Tfng_MA, si, si_LK, sk, sk_SK, sl, sl_SI, " +
                "smn, smn_FI, sn, sn_ZW, so, so_DJ, so_ET, so_KE, so_SO, sq, sq_AL, sq_MK, sq_XK, " +
                "sr, sr_Cyrl, sr_Cyrl_BA, sr_Cyrl_ME, sr_Cyrl_RS, sr_Cyrl_XK, sr_Latn, " +
                "sr_Latn_BA, sr_Latn_ME, sr_Latn_RS, sr_Latn_XK, sv, sv_AX, sv_FI, sv_SE, sw, " +
                "sw_CD, sw_KE, sw_TZ, sw_UG, ta, ta_IN, ta_LK, ta_MY, ta_SG, te, te_IN, teo, " +
                "teo_KE, teo_UG, th, th_TH, ti, ti_ER, ti_ET, tk, tk_TM, to, to_TO, tr, tr_CY, " +
                "tr_TR, twq, twq_NE, tzm, tzm_MA, ug, ug_CN, uk, uk_UA, ur, ur_IN, ur_PK, uz, " +
                "uz_Arab, uz_Arab_AF, uz_Cyrl, uz_Cyrl_UZ, uz_Latn, uz_Latn_UZ, vai, vai_Latn, " +
                "vai_Latn_LR, vai_Vaii, vai_Vaii_LR, vi, vi_VN, vo, vo_001, vun, vun_TZ, wae, " +
                "wae_CH, xog, xog_UG, yav, yav_CM, yi, yi_001, yo, yo_BJ, yo_NG, zgh, zgh_MA, " +
                "zh, zh_Hans, zh_Hans_CN, zh_Hans_HK, zh_Hans_MO, zh_Hans_SG, zh_Hant, " +
                "zh_Hant_HK, zh_Hant_MO, zh_Hant_TW, zu, zu_ZA";

        final LocaleMatcher matcherShort = newLocaleMatcher(shortList);
        final LocaleMatcher matcherLong = newLocaleMatcher(longList);
        final LocaleMatcher matcherVeryLong = newLocaleMatcher(veryLongList);

        PerfCase[] pcs = new PerfCase[] {
                // Exact match in all matchers.
                new PerfCase("sv", "sv", "sv", "sv"),
                // Common locale, exact match only in very long list.
                new PerfCase("fr_CA", "en", "fr", "fr_CA"),
                // Unusual locale, no exact match.
                new PerfCase("de_CA", "en", "de", "de"),
                // World English maps to several region partitions.
                new PerfCase("en_001", "en", "en", "en"),
                // Ancient language with interesting subtags.
                new PerfCase("egy_Copt_CY", "en", "af", "af")
        };

        for (PerfCase pc : pcs) {
            final ULocale desired = pc.desired;

            assertEquals(desired.toString(), pc.expectedShort, matcherShort.getBestMatch(desired));
            assertEquals(desired.toString(), pc.expectedLong, matcherLong.getBestMatch(desired));
            assertEquals(desired.toString(), pc.expectedVeryLong, matcherVeryLong.getBestMatch(desired));

            timeLocaleMatcher(desired, matcherShort, WARM_UP_ITERATIONS);
            timeLocaleMatcher(desired, matcherLong, WARM_UP_ITERATIONS);
            timeLocaleMatcher(desired, matcherVeryLong, WARM_UP_ITERATIONS);
            long tns = timeLocaleMatcher(desired, matcherShort, BENCHMARK_ITERATIONS);
            System.out.format("New Duration (few  supported):\t%s\t%d\tnanos\n", desired, tns);
            long tnl = timeLocaleMatcher(desired, matcherLong, BENCHMARK_ITERATIONS);
            System.out.format("New Duration (med. supported):\t%s\t%d\tnanos\n", desired, tnl);
            long tnv = timeLocaleMatcher(desired, matcherVeryLong, BENCHMARK_ITERATIONS);
            System.out.format("New Duration (many supported):\t%s\t%d\tnanos\n", desired, tnv);
        }

        maximizePerf();
    }

    private static long timeLocaleMatcher(ULocale desired, LocaleMatcher matcher, int iterations) {
        long start = System.nanoTime();
        for (int i = iterations; i > 0; --i) {
            matcher.getBestMatch(desired);
        }
        long delta = System.nanoTime() - start;
        return (delta / iterations);
    }

    private void maximizePerf() {
        final String tags = "af, am, ar, az, be, bg, bn, bs, ca, cs, cy, cy, da, de, " +
                "el, en, en-GB, es, es-419, et, eu, fa, fi, fil, fr, ga, gl, gu, " +
                "hi, hr, hu, hy, id, is, it, iw, ja, ka, kk, km, kn, ko, ky, lo, lt, lv, " +
                "mk, ml, mn, mr, ms, my, ne, nl, no, pa, pl, pt, pt-PT, ro, ru, " +
                "si, sk, sl, sq, sr, sr-Latn, sv, sw, ta, te, th, tr, uk, ur, uz, vi, " +
                "zh-CN, zh-TW, zu";
        LocalePriorityList list = LocalePriorityList.add(tags).build();
        int few = 1000;
        long t = timeMaximize(list, few);  // warm up
        t = timeMaximize(list, few);  // measure for scale
        long targetTime = 100000000L;  // 10^8 ns = 0.1s
        int iterations = (int)((targetTime * few) / t);
        t = timeMaximize(list, iterations);
        int length = 0;
        for (@SuppressWarnings("unused") ULocale locale : list) { ++length; }
        System.out.println("maximize: " + (t / iterations / length) + " ns/locale: " +
                t + " ns / " + iterations + " iterations / " + length + " locales");
    }

    // returns total ns not per iteration
    private  static long timeMaximize(Iterable<ULocale> list, int iterations) {
        long start = System.nanoTime();
        for (int i = iterations; i > 0; --i) {
            for (ULocale locale : list) {
                XLikelySubtags.INSTANCE.makeMaximizedLsrFrom(locale);
            }
        }
        return System.nanoTime() - start;
    }

    @Test
    public void testLikelySubtagsLoadedDataSameAsBuiltFromScratch() {
        XLikelySubtags.Data built = LikelySubtagsBuilder.build();
        XLikelySubtags.Data loaded = XLikelySubtags.Data.load();
        assertEquals("run LocaleDistanceBuilder and update ICU4C langInfo.txt", built, loaded);
    }

    private static final class TestCase implements Cloneable {
        private static final String ENDL = System.getProperties().getProperty("line.separator");

        int lineNr = 0;

        String nameLine = "";
        String supportedLine = "";
        String defaultLine = "";
        String distanceLine = "";
        String thresholdLine = "";
        String matchLine = "";

        String supported = "";
        String def = "";
        String favor = "";
        String threshold = "";
        String desired = "";
        String expMatch = "";
        String expDesired = "";
        String expCombined = "";

        @Override
        public TestCase clone() throws CloneNotSupportedException {
            return (TestCase) super.clone();
        }

        void reset(String newNameLine) {
            nameLine = newNameLine;
            supportedLine = "";
            defaultLine = "";
            distanceLine = "";
            thresholdLine = "";

            supported = "";
            def = "";
            favor = "";
            threshold = "";
        }

        String toInputsKey() {
            return supported + '+' + def + '+' + favor + '+' + threshold + '+' + desired;
        }

        private static void appendLine(StringBuilder sb, String line) {
            if (!line.isEmpty()) {
                sb.append(ENDL).append(line);
            }
        }

        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder(nameLine);
            appendLine(sb, supportedLine);
            appendLine(sb, defaultLine);
            appendLine(sb, distanceLine);
            appendLine(sb, thresholdLine);
            sb.append(ENDL).append("line ").append(lineNr).append(':');
            appendLine(sb, matchLine);
            return sb.toString();
        }
    }

    private static String getSuffixAfterPrefix(String s, int limit, String prefix) {
        if (prefix.length() <= limit && s.startsWith(prefix)) {
            return s.substring(prefix.length(), limit);
        } else {
            return null;
        }
    }

    // UsedReflectively, not private to avoid unused-warning
    static List<TestCase> readTestCases() throws Exception {
        List<TestCase> tests = new ArrayList<>();
        Map<String, Integer> uniqueTests = new HashMap<>();
        TestCase test = new TestCase();
        String filename = "data/localeMatcherTest.txt";
        try (BufferedReader in = FileUtilities.openFile(LocaleMatcherTest.class, filename)) {
            String line;
            while ((line = in.readLine()) != null) {
                ++test.lineNr;
                // Start of comment, or end of line, minus trailing spaces.
                int limit = line.indexOf('#');
                if (limit < 0) {
                    limit = line.length();
                }
                char c;
                while (limit > 0 && ((c = line.charAt(limit - 1)) == ' ' || c == '\t')) {
                    --limit;
                }
                if (limit == 0) {  // empty line
                    continue;
                }
                String suffix;
                if (line.startsWith("** test: ")) {
                    test.reset(line);
                } else if ((suffix = getSuffixAfterPrefix(line, limit, "@supported=")) != null) {
                    test.supportedLine = line;
                    test.supported = suffix;
                } else if ((suffix = getSuffixAfterPrefix(line, limit, "@default=")) != null) {
                    test.defaultLine = line;
                    test.def = suffix;
                } else if ((suffix = getSuffixAfterPrefix(line, limit, "@favor=")) != null) {
                    test.distanceLine = line;
                    test.favor = suffix;
                } else if ((suffix = getSuffixAfterPrefix(line, limit, "@threshold=")) != null) {
                    test.thresholdLine = line;
                    test.threshold = suffix;
                } else {
                    int matchSep = line.indexOf(">>");
                    // >> before an inline comment, and followed by more than white space.
                    if (0 <= matchSep && (matchSep + 2) < limit) {
                        test.matchLine = line;
                        test.desired = line.substring(0, matchSep).trim();
                        test.expDesired = test.expCombined = "";
                        int start = matchSep + 2;
                        int expLimit = line.indexOf('|', start);
                        if (expLimit < 0) {
                            test.expMatch = line.substring(start, limit).trim();
                        } else {
                            test.expMatch = line.substring(start, expLimit).trim();
                            start = expLimit + 1;
                            expLimit = line.indexOf('|', start);
                            if (expLimit < 0) {
                                test.expDesired = line.substring(start, limit).trim();
                            } else {
                                test.expDesired = line.substring(start, expLimit).trim();
                                test.expCombined = line.substring(expLimit + 1, limit).trim();
                            }
                        }
                        String inputs = test.toInputsKey();
                        Integer prevIndex = uniqueTests.get(inputs);
                        if (prevIndex == null) {
                            uniqueTests.put(inputs, tests.size());
                        } else {
                            System.out.println("Locale matcher test case on line " + test.lineNr
                                    + " is a duplicate of line " + tests.get(prevIndex).lineNr);
                        }
                        tests.add(test.clone());
                    } else {
                        throw new IllegalArgumentException("test data syntax error on line "
                                + test.lineNr + "\n" + line);
                    }
                }
            }
        }
        System.out.println("Number of duplicate locale matcher test cases: " + (tests.size() - uniqueTests.size()));
        return tests;
    }

    private static ULocale getULocaleOrNull(String s) {
        if (s.equals("null")) {
            return null;
        } else {
            return new ULocale(s);
        }
    }

    private static Locale toLocale(ULocale ulocale) {
        return ulocale != null ? ulocale.toLocale() : null;
    }

    private static Iterable<Locale> localesFromULocales(Collection<ULocale> ulocales) {
        List<Locale> locales = new ArrayList<>(ulocales.size());
        for (ULocale ulocale : ulocales) {
            locales.add(ulocale.toLocale());
        }
        return locales;
    }

    @Test
    @Parameters(method = "readTestCases")
    public void dataDriven(TestCase test) {
        LocaleMatcher matcher;
        if (test.def.isEmpty() && test.favor.isEmpty() && test.threshold.isEmpty()) {
            matcher = new LocaleMatcher(test.supported);
        } else {
            LocaleMatcher.Builder builder = LocaleMatcher.builder();
            builder.setSupportedLocales(test.supported);
            if (!test.def.isEmpty()) {
                builder.setDefaultULocale(new ULocale(test.def));
            }
            if (!test.favor.isEmpty()) {
                FavorSubtag favor;
                switch (test.favor) {
                case "normal":
                    favor = FavorSubtag.LANGUAGE;
                    break;
                case "script":
                    favor = FavorSubtag.SCRIPT;
                    break;
                default:
                    throw new IllegalArgumentException("unsupported FavorSubtag value " + test.favor);
                }
                builder.setFavorSubtag(favor);
            }
            if (!test.threshold.isEmpty()) {
                int threshold = Integer.valueOf(test.threshold);
                builder.internalSetThresholdDistance(threshold);
            }
            matcher = builder.build();
        }

        ULocale expMatch = getULocaleOrNull(test.expMatch);
        if (test.expDesired.isEmpty() && test.expCombined.isEmpty()) {
            ULocale bestSupported = matcher.getBestMatch(test.desired);
            assertEquals("bestSupported ULocale from string", expMatch, bestSupported);
            LocalePriorityList desired = LocalePriorityList.add(test.desired).build();
            if (desired.getULocales().size() == 1) {
                ULocale desiredULocale = desired.iterator().next();
                bestSupported = matcher.getBestMatch(desiredULocale);
                assertEquals("bestSupported ULocale from ULocale", expMatch, bestSupported);
                Locale desiredLocale = desiredULocale.toLocale();
                Locale bestSupportedLocale = matcher.getBestLocale(desiredLocale);
                assertEquals("bestSupported Locale from Locale",
                        toLocale(expMatch), bestSupportedLocale);

                LocaleMatcher.Result result = matcher.getBestMatchResult(desiredULocale);
                assertEquals("result.getSupportedULocale from ULocale",
                        expMatch, result.getSupportedULocale());
                assertEquals("result.getSupportedLocale from ULocale",
                        toLocale(expMatch), result.getSupportedLocale());

                result = matcher.getBestLocaleResult(desiredLocale);
                assertEquals("result.getSupportedULocale from Locale",
                        expMatch, result.getSupportedULocale());
                assertEquals("result.getSupportedLocale from Locale",
                        toLocale(expMatch), result.getSupportedLocale());
            } else {
                bestSupported = matcher.getBestMatch(desired);
                assertEquals("bestSupported ULocale from ULocale iterator",
                        expMatch, bestSupported);
                Locale bestSupportedLocale = matcher.getBestLocale(
                        localesFromULocales(desired.getULocales()));
                assertEquals("bestSupported Locale from Locale iterator",
                        toLocale(expMatch), bestSupportedLocale);
            }
        } else {
            LocalePriorityList desired = LocalePriorityList.add(test.desired).build();
            LocaleMatcher.Result result = matcher.getBestMatchResult(desired);
            assertEquals("result.getSupportedULocale from ULocales",
                    expMatch, result.getSupportedULocale());
            assertEquals("result.getSupportedLocale from ULocales",
                    toLocale(expMatch), result.getSupportedLocale());
            if (!test.expDesired.isEmpty()) {
                ULocale expDesired = getULocaleOrNull(test.expDesired);
                assertEquals("result.getDesiredULocale from ULocales",
                        expDesired, result.getDesiredULocale());
                assertEquals("result.getDesiredLocale from ULocales",
                        toLocale(expDesired), result.getDesiredLocale());
            }
            if (!test.expCombined.isEmpty()) {
                ULocale expCombined = getULocaleOrNull(test.expCombined);
                assertEquals("combined ULocale from ULocales", expCombined, result.makeResolvedULocale());
                assertEquals("combined Locale from ULocales", toLocale(expCombined), result.makeResolvedLocale());
            }

            result = matcher.getBestLocaleResult(localesFromULocales(desired.getULocales()));
            assertEquals("result.getSupportedULocale from Locales",
                    expMatch, result.getSupportedULocale());
            assertEquals("result.getSupportedLocale from Locales",
                    toLocale(expMatch), result.getSupportedLocale());
            if (!test.expDesired.isEmpty()) {
                ULocale expDesired = getULocaleOrNull(test.expDesired);
                assertEquals("result.getDesiredULocale from Locales",
                        expDesired, result.getDesiredULocale());
                assertEquals("result.getDesiredLocale from Locales",
                        toLocale(expDesired), result.getDesiredLocale());
            }
            if (!test.expCombined.isEmpty()) {
                ULocale expCombined = getULocaleOrNull(test.expCombined);
                assertEquals("combined ULocale from Locales", expCombined, result.makeResolvedULocale());
                assertEquals("combined Locale from Locales", toLocale(expCombined), result.makeResolvedLocale());
            }
        }
    }
}
