// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html#License
/*
 *******************************************************************************
 * 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;
            }

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