// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
 *******************************************************************************
 * Copyright (C) 2014-2016, 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(ICUData.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;
            default:
                // No names for all other types handled by
                // this class.
                break;
            }

            return name;
        }

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

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

        TZDBNameInfo(String mzID, NameType type, boolean ambiguousType, String[] parseRegions) {
            this.mzID = mzID;
            this.type = type;
            this.ambiguousType = ambiguousType;
            this.parseRegions = 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)
         */
        @Override
        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
                    TextTrieMap<TZDBNameInfo> 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(mzID,
                                    NameType.SHORT_STANDARD,
                                    ambiguousType,
                                    parseRegions);
                            trie.put(std, stdInf);
                        }
                        if (dst != null) {
                            TZDBNameInfo dstInf = new TZDBNameInfo(mzID,
                                    NameType.SHORT_DAYLIGHT,
                                    ambiguousType,
                                    parseRegions);
                            trie.put(dst, dstInf);
                        }
                    }
                    TZDB_NAMES_TRIE = trie;
                }
            }
        }
    }

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