/*
 **********************************************************************
 * 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)", "Bahasa Indonesia (Indonesia)", "in", "in_ID"}, 
                    {"Indonésien (Serbie)", "Bahasa 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());
            } 
        }
    }
}
