/*
**********************************************************************
* Copyright (c) 2003-2009 International Business Machines
* Corporation and others.  All Rights Reserved.
**********************************************************************
* Author: Alan Liu
* Created: September 4 2003
* Since: ICU 2.8
**********************************************************************
*/
package com.ibm.icu.impl;

import java.lang.ref.SoftReference;
import java.text.ParsePosition;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.Set;

import com.ibm.icu.text.MessageFormat;
import com.ibm.icu.text.NumberFormat;
import com.ibm.icu.util.SimpleTimeZone;
import com.ibm.icu.util.TimeZone;
import com.ibm.icu.util.ULocale;
import com.ibm.icu.util.UResourceBundle;
import com.ibm.icu.util.UResourceBundleIterator;

/**
 * This class, not to be instantiated, implements the meta-data
 * missing from the underlying core JDK implementation of time zones.
 * There are two missing features: Obtaining a list of available zones
 * for a given country (as defined by the Olson database), and
 * obtaining a list of equivalent zones for a given zone (as defined
 * by Olson links).
 *
 * This class uses a data class, ZoneMetaData, which is created by the
 * tool tz2icu.
 *
 * @author Alan Liu
 * @since ICU 2.8
 */
public final class ZoneMeta {
    private static final boolean ASSERT = false;

    /**
     * Returns a String array containing all system TimeZone IDs
     * associated with the given country.  These IDs may be passed to
     * <code>TimeZone.getTimeZone()</code> to construct the
     * corresponding TimeZone object.
     * @param country a two-letter ISO 3166 country code, or <code>null</code>
     * to return zones not associated with any country
     * @return an array of IDs for system TimeZones in the given
     * country.  If there are none, return a zero-length array.
     */
    public static synchronized String[] getAvailableIDs(String country) {
        if(!getOlsonMeta()){
            return EMPTY;
        }
        try{
            UResourceBundle top = (ICUResourceBundle)ICUResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, "zoneinfo", ICUResourceBundle.ICU_DATA_CLASS_LOADER);
            UResourceBundle regions = top.get(kREGIONS);
            UResourceBundle names = top.get(kNAMES); // dereference Zones section
            UResourceBundle temp = regions.get(country);
            int[] vector = temp.getIntVector();
            if (ASSERT) Assert.assrt("vector.length>0", vector.length>0);
            String[] ret = new String[vector.length];
            for (int i=0; i<vector.length; ++i) {
                if (ASSERT) Assert.assrt("vector[i] >= 0 && vector[i] < OLSON_ZONE_COUNT", 
                        vector[i] >= 0 && vector[i] < OLSON_ZONE_COUNT);
                ret[i] = names.getString(vector[i]);
            }
            return ret;
        }catch(MissingResourceException ex){
            //throw away the exception
        }
        return EMPTY;
    }
    public static synchronized String[] getAvailableIDs() {
        if(!getOlsonMeta()){
            return EMPTY;
        }
        try{
            UResourceBundle top = (ICUResourceBundle)ICUResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, "zoneinfo", ICUResourceBundle.ICU_DATA_CLASS_LOADER);
            UResourceBundle names = top.get(kNAMES); // dereference Zones section
            return names.getStringArray();
        }catch(MissingResourceException ex){
            //throw away the exception
        }
        return EMPTY;
    }
    public static synchronized String[] getAvailableIDs(int offset){
        if(!getOlsonMeta()){
            return EMPTY;
        }
        LinkedList vector = new LinkedList();
        for (int i=0; i<OLSON_ZONE_COUNT; ++i) {
            String unistr;
            if ((unistr=getID(i))!=null) {
                // This is VERY inefficient.
                TimeZone z = TimeZone.getTimeZone(unistr);
                // Make sure we get back the ID we wanted (if the ID is
                // invalid we get back GMT).
                if (z != null && z.getID().equals(unistr) &&
                    z.getRawOffset() == offset) {
                    vector.add(unistr);
                }
            }
        }
        if(!vector.isEmpty()){
            String[] strings = new String[vector.size()];
            return (String[])vector.toArray(strings);
        }
        return EMPTY;
    }
    private static String getID(int i) {
        try{
            UResourceBundle top = (ICUResourceBundle)ICUResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, "zoneinfo", ICUResourceBundle.ICU_DATA_CLASS_LOADER);
            UResourceBundle names = top.get(kNAMES); // dereference Zones section
            return names.getString(i);
        }catch(MissingResourceException ex){
            //throw away the exception
        }
        return null;
    }
    /**
     * Returns the number of IDs in the equivalency group that
     * includes the given ID.  An equivalency group contains zones
     * that behave identically to the given zone.
     *
     * <p>If there are no equivalent zones, then this method returns
     * 0.  This means either the given ID is not a valid zone, or it
     * is and there are no other equivalent zones.
     * @param id a system time zone ID
     * @return the number of zones in the equivalency group containing
     * 'id', or zero if there are no equivalent zones.
     * @see #getEquivalentID
     */
    public static synchronized int countEquivalentIDs(String id) {

        UResourceBundle res = openOlsonResource(id);
        int size = res.getSize();
        if (size == 4 || size == 6) {
            UResourceBundle r=res.get(size-1);
            //result = ures_getSize(&r); // doesn't work
            int[] v = r.getIntVector();
            return v.length;
        }
        return 0;
    }

    /**
     * Returns an ID in the equivalency group that includes the given
     * ID.  An equivalency group contains zones that behave
     * identically to the given zone.
     *
     * <p>The given index must be in the range 0..n-1, where n is the
     * value returned by <code>countEquivalentIDs(id)</code>.  For
     * some value of 'index', the returned value will be equal to the
     * given id.  If the given id is not a valid system time zone, or
     * if 'index' is out of range, then returns an empty string.
     * @param id a system time zone ID
     * @param index a value from 0 to n-1, where n is the value
     * returned by <code>countEquivalentIDs(id)</code>
     * @return the ID of the index-th zone in the equivalency group
     * containing 'id', or an empty string if 'id' is not a valid
     * system ID or 'index' is out of range
     * @see #countEquivalentIDs
     */
    public static synchronized String getEquivalentID(String id, int index) {
        String result="";
        UResourceBundle res = openOlsonResource(id);
        if (res != null) {
            int zone = -1;
            int size = res.getSize();
            if (size == 4 || size == 6) {
                UResourceBundle r = res.get(size-1);
                int[] v = r.getIntVector();
                if (index >= 0 && index < v.length) {
                    zone = v[index];
                }
            }
            if (zone >= 0) {
                try {
                    UResourceBundle top = UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, "zoneinfo",
                            ICUResourceBundle.ICU_DATA_CLASS_LOADER);
                    UResourceBundle ares = top.get(kNAMES); // dereference Zones section
                    result = ares.getString(zone);
                } catch (MissingResourceException e) {
                    result = "";
                }
            }
        }
        return result;
    }

    private static String[] getCanonicalInfo(String id) {
        if (id == null || id.length() == 0) {
            return null;
        }
        if (canonicalMap == null) {
            Map m = new HashMap();
            Set s = new HashSet();
            try {
                UResourceBundle supplementalDataBundle = UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, "supplementalData", ICUResourceBundle.ICU_DATA_CLASS_LOADER);
    
                UResourceBundle zoneFormatting = supplementalDataBundle.get("zoneFormatting");
                UResourceBundleIterator it = zoneFormatting.getIterator();
    
                while ( it.hasNext()) {
                    UResourceBundle temp = it.next();
                    int resourceType = temp.getType();
    
                    switch(resourceType) {
                        case UResourceBundle.TABLE:
                            String [] result = { "", "" };
                            UResourceBundle zoneInfo = temp;
                            String canonicalID = zoneInfo.getKey().replace(':','/');
                            String territory = zoneInfo.get("territory").getString();
                            result[0] = canonicalID;
                            if ( territory.equals("001")) {
                                result[1] = null;
                            }
                            else {
                                result[1] = territory;
                            }
                            m.put(canonicalID,result);
                            try {
                                UResourceBundle aliasBundle = zoneInfo.get("aliases");
                                String [] aliases = aliasBundle.getStringArray();
                                for (int i=0 ; i<aliases.length; i++) {
                                   m.put(aliases[i],result);
                                }
                            } catch(MissingResourceException ex){
                                // Disregard if there are no aliases
                            }
                            break;
                        case UResourceBundle.ARRAY:
                            String[] territoryList = temp.getStringArray();
                            for (int i=0 ; i < territoryList.length; i++) {
                                s.add(territoryList[i]);
                            }
                            break;
                    }
                }
            } catch (MissingResourceException e) {
                // throws away the exception - maps are empty for this case
            }

            // Some available Olson zones are not included in CLDR data (such as Asia/Riyadh87).
            // Also, when we update Olson tzdata, new zones may be added.
            // This code scans all available zones in zoneinfo.res, and if any of them are
            // missing, add them to the map.
            try{
                UResourceBundle top = (ICUResourceBundle)ICUResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BASE_NAME,
                        "zoneinfo", ICUResourceBundle.ICU_DATA_CLASS_LOADER);
                UResourceBundle names = top.get(kNAMES);
                String[] ids = names.getStringArray();
                for (int i = 0; i < ids.length; i++) {
                    if (m.containsKey(ids[i])) {
                        // Already included in CLDR data
                        continue;
                    }
                    // Not in CLDR data, but it could be new one whose alias is
                    // available in CLDR
                    String[] tmpinfo = null;
                    int nTzdataEquivalent = TimeZone.countEquivalentIDs(ids[i]);
                    for (int j = 0; j < nTzdataEquivalent; j++) {
                        String alias = TimeZone.getEquivalentID(ids[i], j);
                        if (alias.equals(ids[i])) {
                            continue;
                        }
                        tmpinfo = (String[])m.get(alias);
                        if (tmpinfo != null) {
                            break;
                        }
                    }
                    if (tmpinfo == null) {
                        // Set dereferenced zone ID as the canonical ID
                        UResourceBundle res = getZoneByName(top, ids[i]);
                        String derefID = (res.getSize() == 1) ? ids[res.getInt()] : ids[i];
                        m.put(ids[i], new String[] {derefID, null});
                    } else {
                        // Use the canonical ID in the existing entry
                        m.put(ids[i], tmpinfo);
                    }
                }
            } catch (MissingResourceException ex) {
                //throw away the exception
            }

            synchronized (ZoneMeta.class) {
                canonicalMap = m;
                multiZoneTerritories = s;
            }
        }

        return (String[])canonicalMap.get(id);
    }

    private static Map canonicalMap = null;
    private static Set multiZoneTerritories = null;

    /**
     * Return the canonical id for this system tzid, which might be the id itself.
     * If the given system tzid is not know, return null.
     */
    public static String getCanonicalSystemID(String tzid) {
        String[] info = getCanonicalInfo(tzid);
        if (info != null) {
            return info[0];
        }
        return null;
    }

    /**
     * Return the canonical country code for this tzid.  If we have none, or if the time zone
     * is not associated with a country, return null.
     */
    public static String getCanonicalCountry(String tzid) {
        String[] info = getCanonicalInfo(tzid);
        if (info != null) {
            return info[1];
        }
        return null;
    }

    /**
     * Return the country code if this is a 'single' time zone that can fallback to just
     * the country, otherwise return null.  (Note, one must also check the locale data
     * to see that there is a localization for the country in order to implement
     * tr#35 appendix J step 5.)
     */
    public static String getSingleCountry(String tzid) {
        String[] info = getCanonicalInfo(tzid);
        if (info != null && info[1] != null && !multiZoneTerritories.contains(info[1])) {
            return info[1];
        }
        return null;
    }

    /**
     * Returns a time zone location(region) format string defined by UTR#35.
     * e.g. "Italy Time", "United States (Los Angeles) Time"
     */
    public static String getLocationFormat(String tzid, String city, ULocale locale) {
        String[] info = getCanonicalInfo(tzid);
        if (info == null) {
            return null; // error
        }

        String country_code = info[1];
        if (country_code == null) {
            return null; // error!   
        }

        String country = null;
        if (country_code != null) {
            try {
                ICUResourceBundle rb = 
                    (ICUResourceBundle)UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, locale);
//
// TODO: There is a design bug in UResourceBundle and getLoadingStatus() does not work well.
//
//                if (rb.getLoadingStatus() != ICUResourceBundle.FROM_ROOT && rb.getLoadingStatus() != ICUResourceBundle.FROM_DEFAULT) {
//                    country = ULocale.getDisplayCountry("xx_" + country_code, locale);
//                }
// START WORKAROUND
                ULocale rbloc = rb.getULocale();
                if (!rbloc.equals(ULocale.ROOT) && rbloc.getLanguage().equals(locale.getLanguage())) {
                    country = ULocale.getDisplayCountry("xx_" + country_code, locale);
                }
// END WORKAROUND
            } catch (MissingResourceException e) {
                // fall through
            }
            if (country == null || country.length() == 0) {
                country = country_code;
            }
        }
        
        // This is not behavior specified in tr35, but behavior added by Mark.  
        // TR35 says to display the country _only_ if there is a localization.
        if (getSingleCountry(tzid) != null) { // single country
            String regPat = getTZLocalizationInfo(locale, REGION_FORMAT);
            if (regPat == null) {
                regPat = DEF_REGION_FORMAT;
            }
            MessageFormat mf = new MessageFormat(regPat);
            return mf.format(new Object[] { country });
        }

        if (city == null) {
            city = tzid.substring(tzid.lastIndexOf('/')+1).replace('_',' ');
        }

        String flbPat = getTZLocalizationInfo(locale, FALLBACK_FORMAT);
        if (flbPat == null) {
            flbPat = DEF_FALLBACK_FORMAT;
        }
        MessageFormat mf = new MessageFormat(flbPat);

        return mf.format(new Object[] { city, country });
    }

    private static final String DEF_REGION_FORMAT = "{0}";
    private static final String DEF_FALLBACK_FORMAT = "{1} ({0})";

    public static final String
        HOUR = "hourFormat",
        GMT = "gmtFormat",
        REGION_FORMAT = "regionFormat",
        FALLBACK_FORMAT = "fallbackFormat",
        ZONE_STRINGS = "zoneStrings",
        FORWARD_SLASH = "/";
     
    /**
     * Get the index'd tz datum for this locale.  Index must be one of the 
     * values PREFIX, HOUR, GMT, REGION_FORMAT, FALLBACK_FORMAT
     */
    public static String getTZLocalizationInfo(ULocale locale, String format) {
        String result = null;
        try {
            ICUResourceBundle bundle = (ICUResourceBundle) ICUResourceBundle.getBundleInstance(locale);
            result = bundle.getStringWithFallback(ZONE_STRINGS+FORWARD_SLASH+format);
        } catch (MissingResourceException e) {
            result = null;
        }
        return result;
    }

//    private static Set getValidIDs() {
//        // Construct list of time zones that are valid, according
//        // to the current underlying core JDK.  We have to do this
//        // at runtime since we don't know what we're running on.
//        Set valid = new TreeSet();
//        valid.addAll(Arrays.asList(java.util.TimeZone.getAvailableIDs()));
//        return valid;
//    }

    /**
     * Empty string array.
     */
    private static final String[] EMPTY = new String[0];



    /**
     * Given an ID, open the appropriate resource for the given time zone.
     * Dereference aliases if necessary.
     * @param id zone id
     * @return top-level resource bundle
     */
    public static UResourceBundle openOlsonResource(String id)
    {
        UResourceBundle res = null;
        try {
            ICUResourceBundle top = (ICUResourceBundle)UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, "zoneinfo", ICUResourceBundle.ICU_DATA_CLASS_LOADER);
            res = getZoneByName(top, id);
            // Dereference if this is an alias.  Docs say result should be 1
            // but it is 0 in 2.8 (?).
             if (res.getSize() <= 1) {
                int deref = res.getInt() + 0;
                UResourceBundle ares = top.get(kZONES); // dereference Zones section
                res = (ICUResourceBundle) ares.get(deref);
            }
        } catch (MissingResourceException e) {
            res = null;
        }
        return res;
    }

    /**
     * Fetch a specific zone by name.  Replaces the getByKey call. 
     * @param top Top timezone resource
     * @param id Time zone ID
     * @return the zone's bundle if found, or undefined if error.  Reuses oldbundle.
     */
    private static UResourceBundle getZoneByName(UResourceBundle top, String id) throws MissingResourceException {
        // load the Rules object
        UResourceBundle tmp = top.get(kNAMES);
        
        // search for the string
        int idx = findInStringArray(tmp, id);
        
        if((idx == -1)) {
            // not found 
            throw new MissingResourceException(kNAMES, ((ICUResourceBundle)tmp).getResPath(), id);
            //ures_close(oldbundle);
            //oldbundle = NULL;
        } else {
            tmp = top.get(kZONES); // get Zones object from top
            tmp = tmp.get(idx); // get nth Zone object
        }
        return tmp;
    }
    private static int findInStringArray(UResourceBundle array, String id){
        int start = 0;
        int limit = array.getSize();
        int mid;
        String u = null;
        int lastMid = Integer.MAX_VALUE;
        if((limit < 1)) { 
            return -1;
        }
        for (;;) {
            mid = (int)((start + limit) / 2);
            if (lastMid == mid) {   /* Have we moved? */
                break;  /* We haven't moved, and it wasn't found. */
            }
            lastMid = mid;
            u = array.getString(mid);
            if(u==null){
                break;
            }
            int r = id.compareTo(u);
            if(r==0) {
                return mid;
            } else if(r<0) {
                limit = mid;
            } else {
                start = mid;
            }
        }
        return -1;
    }
    private static final String kREGIONS  = "Regions";
    private static final String kZONES    = "Zones";
    private static final String kNAMES    = "Names";
    private static final String kGMT_ID   = "GMT";
    private static final String kCUSTOM_TZ_PREFIX = "GMT";
    private static ICUCache zoneCache = new SimpleCache();
    /**
     * The Olson data is stored the "zoneinfo" resource bundle.
     * Sub-resources are organized into three ranges of data: Zones, final
     * rules, and country tables.  There is also a meta-data resource
     * which has 3 integers: The number of zones, rules, and countries,
     * respectively.  The country count includes the non-country 'Default'.
     */
    static int OLSON_ZONE_START = -1; // starting index of zones
    static int OLSON_ZONE_COUNT = 0;  // count of zones

    /**
     * Given a pointer to an open "zoneinfo" resource, load up the Olson
     * meta-data. Return true if successful.
     */
    private static boolean getOlsonMeta(ICUResourceBundle top) {
        if (OLSON_ZONE_START < 0 && top != null) {
            try {
                UResourceBundle res = top.get(kZONES);
                OLSON_ZONE_COUNT = res.getSize();
                OLSON_ZONE_START = 0;
            } catch (MissingResourceException e) {
                // throws away the exception
            }
        }
        return (OLSON_ZONE_START >= 0);
    }

    /**
     * Load up the Olson meta-data. Return true if successful.
     */
    private static boolean getOlsonMeta() {
        if (OLSON_ZONE_START < 0) {
            try {
                ICUResourceBundle top = (ICUResourceBundle)ICUResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, "zoneinfo", ICUResourceBundle.ICU_DATA_CLASS_LOADER);
                getOlsonMeta(top);
            } catch (MissingResourceException e) {
                // throws away the exception
            }
        }
        return (OLSON_ZONE_START >= 0);
    }

    /**
     * Lookup the given name in our system zone table.  If found,
     * instantiate a new zone of that name and return it.  If not
     * found, return 0.
     */
    public static TimeZone getSystemTimeZone(String id) {
        TimeZone z = (TimeZone)zoneCache.get(id);
        if (z == null) {
            try{
                UResourceBundle top = UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, "zoneinfo", ICUResourceBundle.ICU_DATA_CLASS_LOADER);
                UResourceBundle res = openOlsonResource(id);
                z = new OlsonTimeZone(top, res);
                z.setID(id);
                zoneCache.put(id, z);
            }catch(Exception ex){
                return null;
            }
        }
        return (TimeZone)z.clone();
    }
    
    public static TimeZone getGMT(){
        TimeZone z = new SimpleTimeZone(0, kGMT_ID);
        z.setID(kGMT_ID);
        return z;
    }

    // Maximum value of valid custom time zone hour/min
    private static final int kMAX_CUSTOM_HOUR = 23;
    private static final int kMAX_CUSTOM_MIN = 59;
    private static final int kMAX_CUSTOM_SEC = 59;

    /**
     * Parse a custom time zone identifier and return a corresponding zone.
     * @param id a string of the form GMT[+-]hh:mm, GMT[+-]hhmm, or
     * GMT[+-]hh.
     * @return a newly created SimpleTimeZone with the given offset and
     * no Daylight Savings Time, or null if the id cannot be parsed.
    */
    public static TimeZone getCustomTimeZone(String id){
        int[] fields = new int[4];
        if (parseCustomID(id, fields)) {
            String zid = formatCustomID(fields[1], fields[2], fields[3], fields[0] < 0);
            int offset = fields[0] * ((fields[1] * 60 + fields[2]) * 60 + fields[3]) * 1000;
            return new SimpleTimeZone(offset, zid);
        }
        return null;
    }

    /**
     * Parse a custom time zone identifier and return the normalized
     * custom time zone identifier for the given custom id string.
     * @param id a string of the form GMT[+-]hh:mm, GMT[+-]hhmm, or
     * GMT[+-]hh.
     * @return The normalized custom id string.
    */
    public static String getCustomID(String id) {
        int[] fields = new int[4];
        if (parseCustomID(id, fields)) {
            return formatCustomID(fields[1], fields[2], fields[3], fields[0] < 0);
        }
        return null;
    }

    /*
     * Parses the given custom time zone identifier
     * @param id id A string of the form GMT[+-]hh:mm, GMT[+-]hhmm, or
     * GMT[+-]hh.
     * @param fields An array of int (length = 4) to receive the parsed
     * offset time fields.  The sign is set to fields[0] (-1 or 1),
     * hour is set to fields[1], minute is set to fields[2] and second is
     * set to fields[3].
     * @return Returns true when the given custom id is valid.
     */
    static boolean parseCustomID(String id, int[] fields) {
        NumberFormat numberFormat = null;
        String idUppercase = id.toUpperCase();

        if (id != null && id.length() > kGMT_ID.length() &&
            idUppercase.startsWith(kGMT_ID)) {
            ParsePosition pos = new ParsePosition(kGMT_ID.length());
            int sign = 1;
            int hour = 0;
            int min = 0;
            int sec = 0;

            if (id.charAt(pos.getIndex()) == 0x002D /*'-'*/) {
                sign = -1;
            } else if (id.charAt(pos.getIndex()) != 0x002B /*'+'*/) {
                return false;
            }
            pos.setIndex(pos.getIndex() + 1);

            numberFormat = NumberFormat.getInstance();
            numberFormat.setParseIntegerOnly(true);

            // Look for either hh:mm, hhmm, or hh
            int start = pos.getIndex();

            Number n = numberFormat.parse(id, pos);
            if (pos.getIndex() == start) {
                return false;
            }
            hour = n.intValue();

            if (pos.getIndex() < id.length()){
                if (pos.getIndex() - start > 2
                        || id.charAt(pos.getIndex()) != 0x003A /*':'*/) {
                    return false;
                }
                // hh:mm
                pos.setIndex(pos.getIndex() + 1);
                int oldPos = pos.getIndex();
                n = numberFormat.parse(id, pos);
                if ((pos.getIndex() - oldPos) != 2) {
                    // must be 2 digits
                    return false;
                }
                min = n.intValue();
                if (pos.getIndex() < id.length()) {
                    if (id.charAt(pos.getIndex()) != 0x003A /*':'*/) {
                        return false;
                    }
                    // [:ss]
                    pos.setIndex(pos.getIndex() + 1);
                    oldPos = pos.getIndex();
                    n = numberFormat.parse(id, pos);
                    if (pos.getIndex() != id.length()
                            || (pos.getIndex() - oldPos) != 2) {
                        return false;
                    }
                    sec = n.intValue();
                }
            } else {
                // Supported formats are below -
                //
                // HHmmss
                // Hmmss
                // HHmm
                // Hmm
                // HH
                // H

                int length = pos.getIndex() - start;
                if (length <= 0 || 6 < length) {
                    // invalid length
                    return false;
                }
                switch (length) {
                    case 1:
                    case 2:
                        // already set to hour
                        break;
                    case 3:
                    case 4:
                        min = hour % 100;
                        hour /= 100;
                        break;
                    case 5:
                    case 6:
                        sec = hour % 100;
                        min = (hour/100) % 100;
                        hour /= 10000;
                        break;
                }
            }

            if (hour <= kMAX_CUSTOM_HOUR && min <= kMAX_CUSTOM_MIN && sec <= kMAX_CUSTOM_SEC) {
                if (fields != null) {
                    if (fields.length >= 1) {
                        fields[0] = sign;
                    }
                    if (fields.length >= 2) {
                        fields[1] = hour;
                    }
                    if (fields.length >= 3) {
                        fields[2] = min;
                    }
                    if (fields.length >= 4) {
                        fields[3] = sec;
                    }
                }
                return true;
            }
        }
        return false;
    }

    /**
     * Creates a custom zone for the offset
     * @param offset GMT offset in milliseconds
     * @return A custom TimeZone for the offset with normalized time zone id
     */
    public static TimeZone getCustomTimeZone(int offset) {
        boolean negative = false;
        int tmp = offset;
        if (offset < 0) {
            negative = true;
            tmp = -offset;
        }

        int hour, min, sec, millis;

        millis = tmp % 1000;
        if (ASSERT) {
            Assert.assrt("millis!=0", millis != 0);
        }
        tmp /= 1000;
        sec = tmp % 60;
        tmp /= 60;
        min = tmp % 60;
        hour = tmp / 60;

        // Note: No millisecond part included in TZID for now
        String zid = formatCustomID(hour, min, sec, negative);

        return new SimpleTimeZone(offset, zid);
    }

    /*
     * Returns the normalized custom TimeZone ID
     */
    static String formatCustomID(int hour, int min, int sec, boolean negative) {
        // Create normalized time zone ID - GMT[+|-]hh:mm[:ss]
        StringBuffer zid = new StringBuffer(kCUSTOM_TZ_PREFIX);
        if (hour != 0 || min != 0) {
            if(negative) {
                zid.append('-');
            } else {
                zid.append('+');
            }
            // Always use US-ASCII digits
            if (hour < 10) {
                zid.append('0');
            }
            zid.append(hour);
            zid.append(':');
            if (min < 10) {
                zid.append('0');
            }
            zid.append(min);

            if (sec != 0) {
                // Optional second field
                zid.append(':');
                if (sec < 10) {
                    zid.append('0');
                }
                zid.append(sec);
            }
        }
        return zid.toString();
    }

    private static SoftReference OLSON_TO_META_REF;
    private static SoftReference META_TO_OLSON_REF;

    static class OlsonToMetaMappingEntry {
        String mzid;
        long from;
        long to;
    }

    private static class MetaToOlsonMappingEntry {
        String id;
        String territory;
    }

    static Map getOlsonToMetaMap() {
        Map olsonToMeta = null;
        synchronized(ZoneMeta.class) {
            if (OLSON_TO_META_REF != null) {
                olsonToMeta = (HashMap)OLSON_TO_META_REF.get();
            }
            if (olsonToMeta == null) {
                olsonToMeta = createOlsonToMetaMap();
                if (olsonToMeta == null) {
                    // We need to return non-null Map to avoid disaster
                    olsonToMeta = new HashMap();
                }
                OLSON_TO_META_REF = new SoftReference(olsonToMeta);
            }
        }
        return olsonToMeta;
    }

    /*
     * Create olson tzid to metazone mappings from metazoneInfo.res (3.8.1 or later)
     */
    private static Map createOlsonToMetaMap() {
        // Create olson id to metazone mapping table
        HashMap olsonToMeta = null;
        UResourceBundle metazoneMappingsBundle = null;
        try {
            UResourceBundle bundle = UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, "metazoneInfo");
            metazoneMappingsBundle = bundle.get("metazoneMappings");
        } catch (MissingResourceException mre) {
            // do nothing
        }
        if (metazoneMappingsBundle != null) {
            String[] tzids = getAvailableIDs();
            for (int i = 0; i < tzids.length; i++) {
                // Skip aliases
                String canonicalID = TimeZone.getCanonicalID(tzids[i]);
                if (canonicalID == null || !tzids[i].equals(canonicalID)) {
                    continue;
                }
                String tzkey = tzids[i].replace('/', ':');
                try {
                    UResourceBundle zoneBundle = metazoneMappingsBundle.get(tzkey);
                    LinkedList mzMappings = new LinkedList();
                    for (int idx = 0; ; idx++) {
                        try {
                            UResourceBundle mz = zoneBundle.get("mz" + idx);
                            String[] mzstr = mz.getStringArray();
                            if (mzstr == null || mzstr.length != 3) {
                                continue;
                            }
                            OlsonToMetaMappingEntry mzmap = new OlsonToMetaMappingEntry();
                            mzmap.mzid = mzstr[0].intern();
                            mzmap.from = parseDate(mzstr[1]);
                            mzmap.to = parseDate(mzstr[2]);

                            // Add this mapping to the list
                            mzMappings.add(mzmap);
                        } catch (MissingResourceException nomz) {
                            // we're done
                            break;
                        } catch (IllegalArgumentException baddate) {
                            // skip this
                        }
                    }
                    if (mzMappings.size() != 0) {
                        // Add to the olson-to-meta map
                        if (olsonToMeta == null) {
                            olsonToMeta = new HashMap();
                        }
                        olsonToMeta.put(tzids[i], mzMappings);
                    }
                } catch (MissingResourceException noum) {
                    // Does not use metazone, just skip this.
                }
            }
        }
        return olsonToMeta;
    }

    /**
     * Returns a CLDR metazone ID for the given Olson tzid and time.
     */
    public static String getMetazoneID(String olsonID, long date) {
        String mzid = null;
        Map olsonToMeta = getOlsonToMetaMap();
        List mappings = (List)olsonToMeta.get(olsonID);
        if (mappings == null) {
            // The given ID might be an alias - try its canonical id
            String canonicalID = getCanonicalSystemID(olsonID);
            if (canonicalID != null && !canonicalID.equals(olsonID)) {
                mappings = (List)olsonToMeta.get(canonicalID);
            }
        }
        if (mappings != null) {
            for (int i = 0; i < mappings.size(); i++) {
                OlsonToMetaMappingEntry mzm = (OlsonToMetaMappingEntry)mappings.get(i);
                if (date >= mzm.from && date < mzm.to) {
                    mzid = mzm.mzid;
                    break;
                }
            }
        }
        return mzid;
    }

    private static Map getMetaToOlsonMap() {
        HashMap metaToOlson = null;
        synchronized(ZoneMeta.class) {
            if (META_TO_OLSON_REF != null) {
                metaToOlson = (HashMap)META_TO_OLSON_REF.get();
            }
            if (metaToOlson == null) {
                metaToOlson = new HashMap();
                UResourceBundle metazonesBundle = null;
                try {
                    UResourceBundle supplementalBundle = UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BASE_NAME,
                        "supplementalData");
                    UResourceBundle  mapTimezonesBundle = supplementalBundle.get("mapTimezones");
                    metazonesBundle = mapTimezonesBundle.get("metazones");
                } catch (MissingResourceException mre) {
                    // do nothing
                }
                if (metazonesBundle != null) {
                    Enumeration mzenum = metazonesBundle.getKeys();
                    while (mzenum.hasMoreElements()) {
                        String mzkey = (String)mzenum.nextElement();
                        if (!mzkey.startsWith("meta:")) {
                            continue;
                        }
                        String tzid = null;
                        try {
                            tzid = metazonesBundle.getString(mzkey);
                        } catch (MissingResourceException mre) {
                            // It should not happen..
                        }
                        if (tzid != null) {
                            int territoryIdx = mzkey.lastIndexOf('_');
                            if (territoryIdx > 0) {
                                String mzid = mzkey.substring(5 /* "meta:".length() */, territoryIdx);
                                String territory = mzkey.substring(territoryIdx + 1);
                                List mappings = (List)metaToOlson.get(mzid);
                                if (mappings == null) {
                                    mappings = new LinkedList();
                                    metaToOlson.put(mzid, mappings);
                                }
                                MetaToOlsonMappingEntry olsonmap = new MetaToOlsonMappingEntry();
                                olsonmap.id = tzid;
                                olsonmap.territory = territory;
                                mappings.add(olsonmap);
                            }
                        }
                    }
                }
                META_TO_OLSON_REF = new SoftReference(metaToOlson);
            }
        }
        return metaToOlson;
    }

    /**
     * Returns an Olson ID for the ginve metazone and region
     */
    public static String getZoneIdByMetazone(String metazoneID, String region) {
        String tzid = null;
        Map metaToOlson = getMetaToOlsonMap();
        List mappings = (List)metaToOlson.get(metazoneID);
        if (mappings != null) {
            for (int i = 0; i < mappings.size(); i++) {
                MetaToOlsonMappingEntry olsonmap = (MetaToOlsonMappingEntry)mappings.get(i);
                if (olsonmap.territory.equals(region)) {
                    tzid = olsonmap.id;
                    break;
                } else if (olsonmap.territory.equals("001")) {
                    tzid = olsonmap.id;
                }
            }
        }
        return tzid;
    }

//    /**
//     * Returns an Olson ID for the given metazone and locale
//     */
//    public static String getZoneIdByMetazone(String metazoneID, ULocale loc) {
//        String region = loc.getCountry();
//        if (region.length() == 0) {
//            // Get likely region
//            ULocale tmp = ULocale.addLikelySubtag(loc);
//            region = tmp.getCountry();
//        }
//        return getZoneIdByMetazone(metazoneID, region);
//    }

    /*
     * Convert a date string used by metazone mappings to long.
     * The format used by CLDR metazone mapping is "yyyy-MM-dd HH:mm".
     * We do not want to use SimpleDateFormat to parse the metazone
     * mapping range strings in createOlsonToMeta, because it might be
     * called from SimpleDateFormat initialization code.
     */
     static long parseDate (String text) throws IllegalArgumentException {
        int year = 0, month = 0, day = 0, hour = 0, min = 0;
        int idx;
        int n;

        // "yyyy" (0 - 3)
        for (idx = 0; idx <= 3; idx++) {
            n = text.charAt(idx) - '0';
            if (n >= 0 && n < 10) {
                year = 10*year + n;
            } else {
                throw new IllegalArgumentException("Bad year");
            }
        }
        // "MM" (5 - 6)
        for (idx = 5; idx <= 6; idx++) {
            n = text.charAt(idx) - '0';
            if (n >= 0 && n < 10) {
                month = 10*month + n;
            } else {
                throw new IllegalArgumentException("Bad month");
            }
        }
        // "dd" (8 - 9)
        for (idx = 8; idx <= 9; idx++) {
            n = text.charAt(idx) - '0';
            if (n >= 0 && n < 10) {
                day = 10*day + n;
            } else {
                throw new IllegalArgumentException("Bad day");
            }
        }
        // "HH" (11 - 12)
        for (idx = 11; idx <= 12; idx++) {
            n = text.charAt(idx) - '0';
            if (n >= 0 && n < 10) {
                hour = 10*hour + n;
            } else {
                throw new IllegalArgumentException("Bad hour");
            }
        }
        // "mm" (14 - 15)
        for (idx = 14; idx <= 15; idx++) {
            n = text.charAt(idx) - '0';
            if (n >= 0 && n < 10) {
                min = 10*min + n;
            } else {
                throw new IllegalArgumentException("Bad minute");
            }
        }

        long date = Grego.fieldsToDay(year, month - 1, day) * Grego.MILLIS_PER_DAY
                    + hour * Grego.MILLIS_PER_HOUR + min * Grego.MILLIS_PER_MINUTE;
        return date;
     }
}
