/*
 **********************************************************************
 * Copyright (c) 2015, International Business Machines
 * Corporation and others.  All Rights Reserved.
 **********************************************************************
 * Author: Alan Liu
 * Created: January 14 2004
 * Since: ICU 2.8
 **********************************************************************
 */
package com.ibm.icu.dev.test.util;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;

import com.ibm.icu.dev.test.TestFmwk;
import com.ibm.icu.text.Collator;
import com.ibm.icu.text.DisplayContext;
import com.ibm.icu.text.DisplayContext.Type;
import com.ibm.icu.text.LocaleDisplayNames;
import com.ibm.icu.text.LocaleDisplayNames.UiListItem;
import com.ibm.icu.util.IllformedLocaleException;
import com.ibm.icu.util.ULocale;

public class ULocaleCollationTest extends TestFmwk {

    public static void main(String[] args) throws Exception {
        new ULocaleCollationTest().run(args);
    }

    public void TestCollator() {
        checkService("ja_JP_YOKOHAMA", new ServiceFacade() {
            public Object create(ULocale req) {
                return Collator.getInstance(req);
            }
        }, null, new Registrar() {
            public Object register(ULocale loc, Object prototype) {
                return Collator.registerInstance((Collator) prototype, loc);
            }
            public boolean unregister(Object key) {
                return Collator.unregister(key);
            }
        });
    }


    /**
     * Interface used by checkService defining a protocol to create an
     * object, given a requested locale.
     */
    interface ServiceFacade {
        Object create(ULocale requestedLocale);
    }

    /**
     * Interface used by checkService defining a protocol to get a
     * contained subobject, given its parent object.
     */
    interface Subobject {
        Object get(Object parent);
    }

    /**
     * Interface used by checkService defining a protocol to register
     * and unregister a service object prototype.
     */
    interface Registrar {
        Object register(ULocale loc, Object prototype);
        boolean unregister(Object key);
    }



    /**
     * Compare two locale IDs.  If they are equal, return 0.  If `string'
     * starts with `prefix' plus an additional element, that is, string ==
     * prefix + '_' + x, then return 1.  Otherwise return a value < 0.
     */
    static int loccmp(String string, String prefix) {
        int slen = string.length(),
                plen = prefix.length();
        /* 'root' is "less than" everything */
        if (prefix.equals("root")) {
            return string.equals("root") ? 0 : 1;
        }
        // ON JAVA (only -- not on C -- someone correct me if I'm wrong)
        // consider "" to be an alternate name for "root".
        if (plen == 0) {
            return slen == 0 ? 0 : 1;
        }
        if (!string.startsWith(prefix)) return -1; /* mismatch */
        if (slen == plen) return 0;
        if (string.charAt(plen) == '_') return 1;
        return -2; /* false match, e.g. "en_USX" cmp "en_US" */
    }

    /**
     * Check the relationship between requested locales, and report problems.
     * The caller specifies the expected relationships between requested
     * and valid (expReqValid) and between valid and actual (expValidActual).
     * Possible values are:
     * "gt" strictly greater than, e.g., en_US > en
     * "ge" greater or equal,      e.g., en >= en
     * "eq" equal,                 e.g., en == en
     */
    void checklocs(String label,
            String req,
            Locale validLoc,
            Locale actualLoc,
            String expReqValid,
            String expValidActual) {
        String valid = validLoc.toString();
        String actual = actualLoc.toString();
        int reqValid = loccmp(req, valid);
        int validActual = loccmp(valid, actual);
        boolean reqOK = (expReqValid.equals("gt") && reqValid > 0) ||
                (expReqValid.equals("ge") && reqValid >= 0) ||
                (expReqValid.equals("eq") && reqValid == 0);
        boolean valOK = (expValidActual.equals("gt") && validActual > 0) ||
                (expValidActual.equals("ge") && validActual >= 0) ||
                (expValidActual.equals("eq") && validActual == 0);
        if (reqOK && valOK) {
            logln("Ok: " + label + "; req=" + req + ", valid=" + valid +
                    ", actual=" + actual);
        } else {
            errln("FAIL: " + label + "; req=" + req + ", valid=" + valid +
                    ", actual=" + actual +
                    (reqOK ? "" : "\n  req !" + expReqValid + " valid") +
                    (valOK ? "" : "\n  val !" + expValidActual + " actual"));
        }
    }

    /**
     * Use reflection to call getLocale() on the given object to
     * determine both the valid and the actual locale.  Verify these
     * for correctness.
     */
    void checkObject(String requestedLocale, Object obj,
            String expReqValid, String expValidActual) {
        Class[] getLocaleParams = new Class[] { ULocale.Type.class };
        try {
            Class cls = obj.getClass();
            Method getLocale = cls.getMethod("getLocale", getLocaleParams);
            ULocale valid = (ULocale) getLocale.invoke(obj, new Object[] {
                    ULocale.VALID_LOCALE });
            ULocale actual = (ULocale) getLocale.invoke(obj, new Object[] {
                    ULocale.ACTUAL_LOCALE });
            checklocs(cls.getName(), requestedLocale,
                    valid.toLocale(), actual.toLocale(),
                    expReqValid, expValidActual);
        }

        // Make the following exceptions _specific_ -- do not
        // catch(Exception), since that will catch the exception
        // that errln throws.
        catch(NoSuchMethodException e1) {
            // no longer an error, Currency has no getLocale
            // errln("FAIL: reflection failed: " + e1);
        } catch(SecurityException e2) {
            errln("FAIL: reflection failed: " + e2);
        } catch(IllegalAccessException e3) {
            errln("FAIL: reflection failed: " + e3);
        } catch(IllegalArgumentException e4) {
            errln("FAIL: reflection failed: " + e4);
        } catch(InvocationTargetException e5) {
            // no longer an error, Currency has no getLocale
            // errln("FAIL: reflection failed: " + e5);
        }
    }

    /**
     * Verify the correct getLocale() behavior for the given service.
     * @param requestedLocale the locale to request.  This MUST BE
     * FAKE.  In other words, it should be something like
     * en_US_FAKEVARIANT so this method can verify correct fallback
     * behavior.
     * @param svc a factory object that can create the object to be
     * tested.  This isn't necessary here (one could just pass in the
     * object) but is required for the overload of this method that
     * takes a Registrar.
     */
    void checkService(String requestedLocale, ServiceFacade svc) {
        checkService(requestedLocale, svc, null, null);
    }

    /**
     * Verify the correct getLocale() behavior for the given service.
     * @param requestedLocale the locale to request.  This MUST BE
     * FAKE.  In other words, it should be something like
     * en_US_FAKEVARIANT so this method can verify correct fallback
     * behavior.
     * @param svc a factory object that can create the object to be
     * tested.
     * @param sub an object that can be used to retrieve a subobject
     * which should also be tested.  May be null.
     * @param reg an object that supplies the registration and
     * unregistration functionality to be tested.  May be null.
     */
    void checkService(String requestedLocale, ServiceFacade svc,
            Subobject sub, Registrar reg) {
        ULocale req = new ULocale(requestedLocale);
        Object obj = svc.create(req);
        checkObject(requestedLocale, obj, "gt", "ge");
        if (sub != null) {
            Object subobj = sub.get(obj);
            checkObject(requestedLocale, subobj, "gt", "ge");
        }
        if (reg != null) {
            logln("Info: Registering service");
            Object key = reg.register(req, obj);
            Object objReg = svc.create(req);
            checkObject(requestedLocale, objReg, "eq", "eq");
            if (sub != null) {
                Object subobj = sub.get(obj);
                // Assume subobjects don't come from services, so
                // their metadata should be structured normally.
                checkObject(requestedLocale, subobj, "gt", "ge");
            }
            logln("Info: Unregistering service");
            if (!reg.unregister(key)) {
                errln("FAIL: unregister failed");
            }
            Object objUnreg = svc.create(req);
            checkObject(requestedLocale, objUnreg, "gt", "ge");
        }
    }

    public void TestNameList() { 
        String[][][] tests = { 
                /* name in French, name in self, minimized, modified */
                {{"fr-Cyrl-BE", "fr-Cyrl-CA"}, 
                    {"Français (cyrillique, Belgique)", "Français (cyrillique, Belgique)", "fr_Cyrl_BE", "fr_Cyrl_BE"}, 
                    {"Français (cyrillique, Canada)", "Français (cyrillique, Canada)", "fr_Cyrl_CA", "fr_Cyrl_CA"}, 
                }, 
                {{"en", "de", "fr", "zh"}, 
                    {"Allemand", "Deutsch", "de", "de"}, 
                    {"Anglais", "English", "en", "en"}, 
                    {"Chinois", "中文", "zh", "zh"}, 
                    {"Français", "Français", "fr", "fr"}, 
                }, 
                // some non-canonical names
                {{"iw", "iw-US", "no", "no-Cyrl", "in", "in-YU"}, 
                    {"Hébreu (États-Unis)", "עברית (ארצות הברית)", "iw_US", "iw_US"}, 
                    {"Hébreu (Israël)", "עברית (ישראל)", "iw", "iw_IL"}, 
                    {"Indonésien (Indonésie)", "Indonesia (Indonesia)", "in", "in_ID"}, 
                    {"Indonésien (Serbie)", "Indonesia (Serbia)", "in_YU", "in_YU"}, 
                    {"Norvégien (cyrillique)", "Norsk (kyrillisk)", "no_Cyrl", "no_Cyrl"}, 
                    {"Norvégien (latin)", "Norsk (latinsk)", "no", "no_Latn"}, 
                }, 
                {{"zh-Hant-TW", "en", "en-gb", "fr", "zh-Hant", "de", "de-CH", "zh-TW"}, 
                    {"Allemand (Allemagne)", "Deutsch (Deutschland)", "de", "de_DE"}, 
                    {"Allemand (Suisse)", "Deutsch (Schweiz)", "de_CH", "de_CH"}, 
                    {"Anglais (États-Unis)", "English (United States)", "en", "en_US"}, 
                    {"Anglais (Royaume-Uni)", "English (United Kingdom)", "en_GB", "en_GB"}, 
                    {"Chinois (traditionnel)", "中文（繁體）", "zh_Hant", "zh_Hant"}, 
                    {"Français", "Français", "fr", "fr"}, 
                }, 
                {{"zh", "en-gb", "en-CA", "fr-Latn-FR"}, 
                    {"Anglais (Canada)", "English (Canada)", "en_CA", "en_CA"}, 
                    {"Anglais (Royaume-Uni)", "English (United Kingdom)", "en_GB", "en_GB"}, 
                    {"Chinois", "中文", "zh", "zh"}, 
                    {"Français", "Français", "fr", "fr"}, 
                }, 
                {{"en-gb", "fr", "zh-Hant", "zh-SG", "sr", "sr-Latn"}, 
                    {"Anglais (Royaume-Uni)", "English (United Kingdom)", "en_GB", "en_GB"}, 
                    {"Chinois (simplifié, Singapour)", "中文（简体、新加坡）", "zh_SG", "zh_Hans_SG"}, 
                    {"Chinois (traditionnel, Taïwan)", "中文（繁體，台灣）", "zh_Hant", "zh_Hant_TW"}, 
                    {"Français", "Français", "fr", "fr"}, 
                    {"Serbe (cyrillique)", "Српски (ћирилица)", "sr", "sr_Cyrl"}, 
                    {"Serbe (latin)", "Srpski (latinica)", "sr_Latn", "sr_Latn"}, 
                }, 
                {{"fr-Cyrl", "fr-Arab"}, 
                    {"Français (arabe)", "Français (arabe)", "fr_Arab", "fr_Arab"}, 
                    {"Français (cyrillique)", "Français (cyrillique)", "fr_Cyrl", "fr_Cyrl"}, 
                }, 
                {{"fr-Cyrl-BE", "fr-Arab-CA"}, 
                    {"Français (arabe, Canada)", "Français (arabe, Canada)", "fr_Arab_CA", "fr_Arab_CA"}, 
                    {"Français (cyrillique, Belgique)", "Français (cyrillique, Belgique)", "fr_Cyrl_BE", "fr_Cyrl_BE"}, 
                } 
        }; 
        ULocale french = ULocale.FRENCH; 
        LocaleDisplayNames names = LocaleDisplayNames.getInstance(french,  
                DisplayContext.CAPITALIZATION_FOR_UI_LIST_OR_MENU); 
        for (Type type : DisplayContext.Type.values()) { 
            logln("Contexts: " + names.getContext(type).toString()); 
        } 
        Collator collator = Collator.getInstance(french); 

        for (String[][] test : tests) { 
            Set<ULocale> list = new LinkedHashSet<ULocale>(); 
            List<UiListItem> expected = new ArrayList<UiListItem>(); 
            for (String item : test[0]) { 
                list.add(new ULocale(item)); 
            } 
            for (int i = 1; i < test.length; ++i) { 
                String[] rawRow = test[i]; 
                expected.add(new UiListItem(new ULocale(rawRow[2]), new ULocale(rawRow[3]), rawRow[0], rawRow[1])); 
            } 
            List<UiListItem> newList = names.getUiList(list, false, collator); 
            if (!expected.equals(newList)) { 
                if (expected.size() != newList.size()) { 
                    errln(list.toString() + ": wrong size" + expected + ", " + newList); 
                } else { 
                    errln(list.toString()); 
                    for (int i = 0; i < expected.size(); ++i) { 
                        assertEquals(i+"", expected.get(i), newList.get(i)); 
                    } 
                } 
            } else { 
                assertEquals(list.toString(), expected, newList); 
            } 
        } 
    } 

    public void TestIllformedLocale() {
        ULocale french = ULocale.FRENCH; 
        Collator collator = Collator.getInstance(french); 
        LocaleDisplayNames names = LocaleDisplayNames.getInstance(french,  
                DisplayContext.CAPITALIZATION_FOR_UI_LIST_OR_MENU); 
        for (String malformed : Arrays.asList("en-a", "$", "ü--a", "en--US")) {
            try {
                Set<ULocale> supported = Collections.singleton(new ULocale(malformed));
                names.getUiList(supported, false, collator);
                assertNull("Failed to detect bogus locale «" + malformed + "»", supported);
            } catch (IllformedLocaleException e) {
                logln("Successfully detected ill-formed locale «" + malformed + "»:" + e.getMessage());
            } 
        }
    }
}
