/*
 * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/**
 * @test
 * @bug 4640234 4946057 4938151 4873691 5023181
 * @summary Verifies the translation of time zone names, this test will catch
 *          presence of country name for english and selected locales for all
 *          ISO country codes.
 *          The test program also displays which timezone, country and
 *          language names are not translated
 */


/*
 * 4946057 Localization for ISO country & language data.
 * 4938151 Time zones not translated
 * 4873691 Changes in TimeZone mapping
 */

import java.text.MessageFormat;
import java.text.SimpleDateFormat;

import java.util.Date;
import java.util.Locale;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.TimeZone;


public class Bug4640234  {
    static SimpleDateFormat sdfEn = new SimpleDateFormat("zzzz", Locale.US);
    static SimpleDateFormat sdfEnShort = new SimpleDateFormat("z", Locale.US);
    static Locale locEn = Locale.ENGLISH;

    static SimpleDateFormat sdfLoc;
    static SimpleDateFormat sdfLocShort;
    static Date date = new Date();

    // Define supported locales
    static Locale[] locales2Test = new Locale[] {
        new Locale("de"),
        new Locale("es"),
        new Locale("fr"),
        new Locale("it"),
        new Locale("ja"),
        new Locale("ko"),
        new Locale("sv"),
        new Locale("zh", "CN"),
        new Locale("zh", "TW")
    };

    public static void main(String[] args) throws Exception {
        Locale reservedLocale = Locale.getDefault();
        try {
            Locale.setDefault(Locale.ENGLISH);

            StringBuffer errors = new StringBuffer("");
            StringBuffer warnings = new StringBuffer("");

            String[] timezones = TimeZone.getAvailableIDs();
            String[] countries = locEn.getISOCountries();
            String[] languages = locEn.getISOLanguages();

            ResourceBundle resEn = ResourceBundle.getBundle(
                    "sun.util.resources.LocaleNames", locEn);
            Map<String, String> countryMapEn = getList(resEn, true);
            Map<String, String> languageMapEn = getList(resEn, false);

            ResourceBundle resLoc;
            Map<String, String> countryMap;
            Map<String, String> languageMap;

            for (Locale locale : locales2Test) {
                resLoc = ResourceBundle.getBundle(
                    "sun.util.resources.LocaleNames", locale);

                sdfLoc = new SimpleDateFormat("zzzz", locale);
                sdfLocShort = new SimpleDateFormat("z", locale);

                for (String timezone : timezones) {
                    if (isTZIgnored(timezone)) {
                        continue;
                    }
                    warnings.append(testTZ(timezone, locale));
                }

                countryMap = getList(resLoc, true);

                for (String country : countries) {
                    String[] result = testEntry(country,
                        countryMapEn,
                        countryMap,
                        locale,
                        "ERROR: {0} country name for country code: {1} not found!\n",
                        "WARNING: {0} country name for country code: {1} not localized!\n"
                    );
                    if (warnings.indexOf(result[0]) == -1) {
                        warnings.append(result[0]);
                    }
                    if (errors.indexOf(result[1]) == -1) {
                        errors.append(result[1]);
                    }
                }

                languageMap = getList(resLoc, false);
                for (String language : languages) {
                    String[] result = testEntry(language,
                        languageMapEn,
                        languageMap,
                        locale,
                        "ERROR: {0} language name for language code: {1} not found!\n",
                        "WARNING: {0} language name for language code: {1} not localized!\n");
                    if (warnings.indexOf(result[0]) == -1) {
                        warnings.append(result[0]);
                    }
                    if (errors.indexOf(result[1]) == -1) {
                        errors.append(result[1]);
                    }
                }
            }

            StringBuffer message = new StringBuffer("");
            if (!"".equals(errors.toString())) {
                message.append("Test failed! ");
                message.append("ERROR: some keys are missing! ");
            }

            if ("".equals(message.toString())) {
                System.out.println("\nTest passed");
                System.out.println(warnings.toString());
            } else {
                System.out.println("\nTest failed!");
                System.out.println(errors.toString());
                System.out.println(warnings.toString());
                throw new Exception("\n" + message);
            }
        } finally {
            // restore the reserved locale
            Locale.setDefault(reservedLocale);
        }
    }

    /**
    * Compares the english timezone name and timezone name in specified locale
    * @param timeZoneName - name of the timezone to compare
    * @param locale - locale to test against english
    * @return empty string when passed, descriptive error message in other cases
    */
    private static String testTZ(String timeZoneName, Locale locale) {
        StringBuffer timeZoneResult = new StringBuffer("");
        TimeZone tz = TimeZone.getTimeZone(timeZoneName);
        sdfEn.setTimeZone(tz);
        sdfEnShort.setTimeZone(tz);
        sdfLoc.setTimeZone(tz);
        sdfLocShort.setTimeZone(tz);

        String en, enShort, loc, locShort;
        en = sdfEn.format(date);
        enShort = sdfEnShort.format(date);
        loc = sdfLoc.format(date);
        locShort = sdfLocShort.format(date);

        String displayLanguage = locale.getDisplayLanguage();
        String displayCountry = locale.getDisplayCountry();

        if (loc.equals(en)) {
            timeZoneResult.append("[");
            timeZoneResult.append(displayLanguage);
            if (!"".equals(displayCountry)) {
                timeZoneResult.append(" ");
                timeZoneResult.append(displayCountry);
            }
            timeZoneResult.append("] timezone \"");
            timeZoneResult.append(timeZoneName);
            timeZoneResult.append("\" long name \"" + en);
            timeZoneResult.append("\" not localized!\n");
        }

        if (!locShort.equals(enShort)) {
            timeZoneResult.append("[");
            timeZoneResult.append(displayLanguage);
            if (!"".equals(displayCountry)) {
                timeZoneResult.append(" ");
                timeZoneResult.append(displayCountry);
            }
            timeZoneResult.append("] timezone \"");
            timeZoneResult.append(timeZoneName);
            timeZoneResult.append("\" short name \"" + enShort);
            timeZoneResult.append("\" is localized \"");
            timeZoneResult.append(locShort);
            timeZoneResult.append("\"!\n");
        }
        return timeZoneResult.toString();
    }

    /**
    * Verifies whether the name for ISOCode is localized.
    * @param ISOCode - ISO country/language code for country/language name
    *      to test
    * @param entriesEn - array of english country/language names
    * @param entriesLoc - array of localized country/language names for
    *      specified locale
    * @param locale - locale to test against english
    * @param notFoundMessage - message in form ready for MessageFormat,
    *      {0} will be human readable language name, {1} will be ISOCode.
    * @param notLocalizedMessage - message in for ready for MessageFormat,
    *      same formatting like for notFountMessage
    * @return array of two empty strings when passed, descriptive error message
    *      in other cases, [0] - warnings for not localized, [1] - errors for
    *      missing keys.
    */
    private static String[] testEntry(String ISOCode,
                Map<String, String> entriesEn,
                Map<String, String> entriesLoc,
                Locale locale,
                String notFoundMessage,
                String notLocalizedMessage) {
        String nameEn = null;
        String nameLoc = null;

        for (String key: entriesEn.keySet()) {
            if (ISOCode.equalsIgnoreCase(key)) {
                nameEn = entriesEn.get(key);
                break;
            }
        }

        for (String key: entriesLoc.keySet()) {
            if (ISOCode.equalsIgnoreCase(key)) {
                nameLoc = entriesLoc.get(key);
                break;
            }
        }

        if (nameEn == null) {
            // We should not get here but test is a MUST have
            return new String[] {"", MessageFormat.format(notFoundMessage,
                new String[] {"English", ISOCode})};
        }

        if (nameLoc == null) {
            return new String[] {"", MessageFormat.format(notFoundMessage,
                new String[] {locale.getDisplayName(), ISOCode})};
        }

        if (nameEn.equals(nameLoc)) {
            return new String[] {MessageFormat.format(notLocalizedMessage,
                new String[] {locale.getDisplayName(), ISOCode}), ""};
        }

        return new String[] {"", ""};
    }

    private static boolean isTZIgnored(String TZName) {
        if (TZName.startsWith("Etc/GMT") ||
                TZName.indexOf("Riyadh8") != -1 ||
                TZName.equals("GMT0") ||
                TZName.equals("MET")
                ) {
            return true;
        }
        return false;
    }

    private static Map<String, String> getList(
            ResourceBundle rs, Boolean getCountryList) {
        char beginChar = 'a';
        char endChar = 'z';
        if (getCountryList) {
            beginChar = 'A';
            endChar = 'Z';
        }

        Map<String, String> hm = new HashMap<String, String>();
        Enumeration<String> keys = rs.getKeys();
        while (keys.hasMoreElements()) {
            String s = keys.nextElement();
            if (s.length() == 2 &&
                s.charAt(0) >= beginChar && s.charAt(0) <= endChar) {
                hm.put(s, rs.getString(s));
            }
        }
        return hm;
    }
}
