/*
 *******************************************************************************
 * Copyright (C) 2014, International Business Machines Corporation and
 * others. All Rights Reserved.
 *******************************************************************************
 */
package com.ibm.icu.impl;

import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.MissingResourceException;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import com.ibm.icu.impl.TextTrieMap.ResultHandler;
import com.ibm.icu.text.TimeZoneNames;
import com.ibm.icu.util.ULocale;
import com.ibm.icu.util.UResourceBundle;

/**
 * Yet another TimeZoneNames implementation based on the tz database.
 * This implementation contains only tz abbreviations (short standard
 * and daylight names) for each metazone.
 * 
 * The data file $ICU4C_ROOT/source/data/zone/tzdbNames.txt contains
 * the metazone - abbreviations mapping data (manually edited).
 * 
 * Note: The abbreviations in the tz database are not necessarily
 * unique. For example, parsing abbreviation "IST" is ambiguous
 * (can be parsed as India Standard Time or Israel Standard Time).
 * The data file (tzdbNames.txt) contains regional mapping, and
 * the locale in the constructor is used as a hint for resolving
 * these ambiguous names.
 */
public class TZDBTimeZoneNames extends TimeZoneNames {
    private static final long serialVersionUID = 1L;

    private static final ConcurrentHashMap<String, TZDBNames> TZDB_NAMES_MAP = 
            new ConcurrentHashMap<String, TZDBNames>();

    private static volatile TextTrieMap<TZDBNameInfo> TZDB_NAMES_TRIE = null;

    private static final ICUResourceBundle ZONESTRINGS;
    static {
        UResourceBundle bundle = ICUResourceBundle
                .getBundleInstance(ICUResourceBundle.ICU_ZONE_BASE_NAME, "tzdbNames");
        ZONESTRINGS = (ICUResourceBundle)bundle.get("zoneStrings");
    }

    private ULocale _locale;
    private transient volatile String _region;

    public TZDBTimeZoneNames(ULocale loc) {
        _locale = loc;
    }

    /* (non-Javadoc)
     * @see com.ibm.icu.text.TimeZoneNames#getAvailableMetaZoneIDs()
     */
    @Override
    public Set<String> getAvailableMetaZoneIDs() {
        return TimeZoneNamesImpl._getAvailableMetaZoneIDs();
    }

    /* (non-Javadoc)
     * @see com.ibm.icu.text.TimeZoneNames#getAvailableMetaZoneIDs(java.lang.String)
     */
    @Override
    public Set<String> getAvailableMetaZoneIDs(String tzID) {
        return TimeZoneNamesImpl._getAvailableMetaZoneIDs(tzID);
    }

    /* (non-Javadoc)
     * @see com.ibm.icu.text.TimeZoneNames#getMetaZoneID(java.lang.String, long)
     */
    @Override
    public String getMetaZoneID(String tzID, long date) {
        return TimeZoneNamesImpl._getMetaZoneID(tzID, date);
    }

    /* (non-Javadoc)
     * @see com.ibm.icu.text.TimeZoneNames#getReferenceZoneID(java.lang.String, java.lang.String)
     */
    @Override
    public String getReferenceZoneID(String mzID, String region) {
        return TimeZoneNamesImpl._getReferenceZoneID(mzID, region);
    }

    /* (non-Javadoc)
     * @see com.ibm.icu.text.TimeZoneNames#getMetaZoneDisplayName(java.lang.String,
     *      com.ibm.icu.text.TimeZoneNames.NameType)
     */
    @Override
    public String getMetaZoneDisplayName(String mzID, NameType type) {
        if (mzID == null || mzID.length() == 0 || 
                (type != NameType.SHORT_STANDARD && type != NameType.SHORT_DAYLIGHT)) {
            return null;
        }
        return getMetaZoneNames(mzID).getName(type);
    }

    /* (non-Javadoc)
     * @see com.ibm.icu.text.TimeZoneNames#getTimeZoneDisplayName(java.lang.String,
     *      com.ibm.icu.text.TimeZoneNames.NameType)
     */
    @Override
    public String getTimeZoneDisplayName(String tzID, NameType type) {
        // No abbreviations associated a zone directly for now.
        return null;
    }

//    /* (non-Javadoc)
//     * @see com.ibm.icu.text.TimeZoneNames#getExemplarLocationName(java.lang.String)
//     */
//    public String getExemplarLocationName(String tzID) {
//        return super.getExemplarLocationName(tzID);
//    }

    /* (non-Javadoc)
     * @see com.ibm.icu.text.TimeZoneNames#find(java.lang.CharSequence, int, java.util.EnumSet)
     */
    @Override
    public Collection<MatchInfo> find(CharSequence text, int start, EnumSet<NameType> nameTypes) {
        if (text == null || text.length() == 0 || start < 0 || start >= text.length()) {
            throw new IllegalArgumentException("bad input text or range");
        }

        prepareFind();
        TZDBNameSearchHandler handler = new TZDBNameSearchHandler(nameTypes, getTargetRegion());
        TZDB_NAMES_TRIE.find(text, start, handler);
        return handler.getMatches();
    }

    private static class TZDBNames {
        public static final TZDBNames EMPTY_TZDBNAMES = new TZDBNames(null, null);

        private String[] _names;
        private String[] _parseRegions;
        private static final String[] KEYS = {"ss", "sd"};

        private TZDBNames(String[] names, String[] parseRegions) {
            _names = names;
            _parseRegions = parseRegions;
        }

        static TZDBNames getInstance(ICUResourceBundle zoneStrings, String key) {
            if (zoneStrings == null || key == null || key.length() == 0) {
                return EMPTY_TZDBNAMES;
            }

            ICUResourceBundle table = null;
            try {
                table = (ICUResourceBundle)zoneStrings.get(key);
            } catch (MissingResourceException e) {
                return EMPTY_TZDBNAMES;
            }

            boolean isEmpty = true;
            String[] names = new String[KEYS.length];
            for (int i = 0; i < names.length; i++) {
                try {
                    names[i] = table.getString(KEYS[i]);
                    isEmpty = false;
                } catch (MissingResourceException e) {
                    names[i] = null;
                }
            }

            if (isEmpty) {
                return EMPTY_TZDBNAMES;
            }

            String[] parseRegions = null;
            try {
                ICUResourceBundle regionsRes = (ICUResourceBundle)table.get("parseRegions");
                if (regionsRes.getType() == UResourceBundle.STRING) {
                    parseRegions = new String[1];
                    parseRegions[0] = regionsRes.getString();
                } else if (regionsRes.getType() == UResourceBundle.ARRAY) {
                    parseRegions = regionsRes.getStringArray();
                }
            } catch (MissingResourceException e) {
                // fall through
            }

            return new TZDBNames(names, parseRegions);
        }

        String getName(NameType type) {
            if (_names == null) {
                return null;
            }
            String name = null;
            switch (type) {
            case SHORT_STANDARD:
                name = _names[0];
                break;
            case SHORT_DAYLIGHT:
                name = _names[1];
                break;
            }

            return name;
        }

        String[] getParseRegions() {
            return _parseRegions;
        }
    }

    private static class TZDBNameInfo {
        String mzID;
        NameType type;
        boolean ambiguousType;
        String[] parseRegions;
    }

    private static class TZDBNameSearchHandler implements ResultHandler<TZDBNameInfo> {
        private EnumSet<NameType> _nameTypes;
        private Collection<MatchInfo> _matches;
        private String _region;

        TZDBNameSearchHandler(EnumSet<NameType> nameTypes, String region) {
            _nameTypes = nameTypes;
            assert region != null;
            _region = region;
        }

        /* (non-Javadoc)
         * @see com.ibm.icu.impl.TextTrieMap.ResultHandler#handlePrefixMatch(int,
         *      java.util.Iterator)
         */
        public boolean handlePrefixMatch(int matchLength, Iterator<TZDBNameInfo> values) {
            TZDBNameInfo match = null;
            TZDBNameInfo defaultRegionMatch = null;

            while (values.hasNext()) {
                TZDBNameInfo ninfo = values.next();

                if (_nameTypes != null && !_nameTypes.contains(ninfo.type)) {
                    continue;
                }

                // Some tz database abbreviations are ambiguous. For example,
                // CST means either Central Standard Time or China Standard Time.
                // Unlike CLDR time zone display names, this implementation
                // does not use unique names. And TimeZoneFormat does not expect
                // multiple results returned for the same time zone type.
                // For this reason, this implementation resolve one among same
                // zone type with a same name at this level.
                if (ninfo.parseRegions == null) {
                    // parseRegions == null means this is the default metazone
                    // mapping for the abbreviation.
                    if (defaultRegionMatch == null) {
                        match = defaultRegionMatch = ninfo;
                    }
                } else {
                    boolean matchRegion = false;
                    // non-default metazone mapping for an abbreviation
                    // comes with applicable regions. For example, the default
                    // metazone mapping for "CST" is America_Central,
                    // but if region is one of CN/MO/TW, "CST" is parsed
                    // as metazone China (China Standard Time).
                    for (String region : ninfo.parseRegions) {
                        if (_region.equals(region)) {
                            match = ninfo;
                            matchRegion = true;
                            break;
                        }
                    }
                    if (matchRegion) {
                        break;
                    }
                    if (match == null) {
                        match = ninfo;
                    }
                }
            }

            if (match != null) {
                NameType ntype = match.type;
                // Note: Workaround for duplicated standard/daylight names
                // The tz database contains a few zones sharing a
                // same name for both standard time and daylight saving
                // time. For example, Australia/Sydney observes DST,
                // but "EST" is used for both standard and daylight.
                // When both SHORT_STANDARD and SHORT_DAYLIGHT are included
                // in the find operation, we cannot tell which one was
                // actually matched.
                // TimeZoneFormat#parse returns a matched name type (standard
                // or daylight) and DateFormat implementation uses the info to
                // to adjust actual time. To avoid false type information,
                // this implementation replaces the name type with SHORT_GENERIC.
                if (match.ambiguousType
                        && (ntype == NameType.SHORT_STANDARD || ntype == NameType.SHORT_DAYLIGHT)
                        && _nameTypes.contains(NameType.SHORT_STANDARD)
                        && _nameTypes.contains(NameType.SHORT_DAYLIGHT)) {
                    ntype = NameType.SHORT_GENERIC;
                }
                MatchInfo minfo = new MatchInfo(ntype, null, match.mzID, matchLength);
                if (_matches == null) {
                    _matches = new LinkedList<MatchInfo>();
                }
                _matches.add(minfo);
            }

            return true;
        }

        /**
         * Returns the match results
         * @return the match results
         */
        public Collection<MatchInfo> getMatches() {
            if (_matches == null) {
                return Collections.emptyList();
            }
            return _matches;
        }
    }

    private static TZDBNames getMetaZoneNames(String mzID) {
        TZDBNames names = TZDB_NAMES_MAP.get(mzID);
        if (names == null) {
            names = TZDBNames.getInstance(ZONESTRINGS, "meta:" + mzID);
            mzID = mzID.intern();
            TZDBNames tmpNames = TZDB_NAMES_MAP.putIfAbsent(mzID, names);
            names = (tmpNames == null) ? names : tmpNames;
        }
        return names;
    }

    private static void prepareFind() {
        if (TZDB_NAMES_TRIE == null) {
            synchronized(TZDBTimeZoneNames.class) {
                if (TZDB_NAMES_TRIE == null) {
                    // loading all names into trie
                    TZDB_NAMES_TRIE = new TextTrieMap<TZDBNameInfo>(true);
                    Set<String> mzIDs = TimeZoneNamesImpl._getAvailableMetaZoneIDs();
                    for (String mzID : mzIDs) {
                        TZDBNames names = getMetaZoneNames(mzID);
                        String std = names.getName(NameType.SHORT_STANDARD);
                        String dst = names.getName(NameType.SHORT_DAYLIGHT);
                        if (std == null && dst == null) {
                            continue;
                        }
                        String[] parseRegions = names.getParseRegions();
                        mzID = mzID.intern();

                        // The tz database contains a few zones sharing a
                        // same name for both standard time and daylight saving
                        // time. For example, Australia/Sydney observes DST,
                        // but "EST" is used for both standard and daylight.
                        // we need to store the information for later processing.
                        boolean ambiguousType = (std != null && dst != null && std.equals(dst));

                        if (std != null) {
                            TZDBNameInfo stdInf = new TZDBNameInfo();
                            stdInf.mzID = mzID;
                            stdInf.type = NameType.SHORT_STANDARD;
                            stdInf.ambiguousType = ambiguousType;
                            stdInf.parseRegions = parseRegions;
                            TZDB_NAMES_TRIE.put(std, stdInf);
                        }
                        if (dst != null) {
                            TZDBNameInfo dstInf = new TZDBNameInfo();
                            dstInf.mzID = mzID;
                            dstInf.type = NameType.SHORT_DAYLIGHT;
                            dstInf.ambiguousType = ambiguousType;
                            dstInf.parseRegions = parseRegions;
                            TZDB_NAMES_TRIE.put(dst, dstInf);
                        }
                    }
                }
            }
        }
    }

    private String getTargetRegion() {
        if (_region == null) {
            String region = _locale.getCountry();
            if (region.length() == 0) {
                ULocale tmp = ULocale.addLikelySubtags(_locale);
                region = tmp.getCountry();
                if (region.length() == 0) {
                    region = "001";
                }
            }
            _region = region;
        }
        return _region;
    }
}
