/*
 * Copyright (c) 2007, 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.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);
    }
  }

  /**
  * 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;
    }
}
