// © 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.locale;

import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.Set;
import java.util.regex.Pattern;

import com.ibm.icu.impl.ICUData;
import com.ibm.icu.impl.ICUResourceBundle;
import com.ibm.icu.util.Output;
import com.ibm.icu.util.UResourceBundle;
import com.ibm.icu.util.UResourceBundleIterator;

/**
 */
public class KeyTypeData {

    public enum ValueType {
        single, multiple, incremental, any
    }

    private static abstract class SpecialTypeHandler {
        abstract boolean isWellFormed(String value); // doesn't test validity, just whether it is well formed.
        String canonicalize(String value) {
            return AsciiUtil.toLowerString(value);
        }
    }

    private static class CodepointsTypeHandler extends SpecialTypeHandler {
        private static final Pattern pat = Pattern.compile("[0-9a-fA-F]{4,6}(-[0-9a-fA-F]{4,6})*");
        boolean isWellFormed(String value) {
            return pat.matcher(value).matches();
        }
    }

    private static class ReorderCodeTypeHandler extends SpecialTypeHandler {
        private static final Pattern pat = Pattern.compile("[a-zA-Z]{3,8}(-[a-zA-Z]{3,8})*");
        boolean isWellFormed(String value) {
            return pat.matcher(value).matches();
        }
    }

    private static class RgKeyValueTypeHandler extends SpecialTypeHandler {
        private static final Pattern pat = Pattern.compile("([a-zA-Z]{2}|[0-9]{3})[zZ]{4}");
        boolean isWellFormed(String value) {
            return pat.matcher(value).matches();
        }
    }
    
    private static class SubdivisionKeyValueTypeHandler extends SpecialTypeHandler {
        private static final Pattern pat = Pattern.compile("([a-zA-Z]{2}|[0-9]{3})");
        boolean isWellFormed(String value) {
            return pat.matcher(value).matches();
        }
    }
    
    private static class PrivateUseKeyValueTypeHandler extends SpecialTypeHandler {
        private static final Pattern pat = Pattern.compile("[a-zA-Z0-9]{3,8}(-[a-zA-Z0-9]{3,8})*");
        boolean isWellFormed(String value) {
            return pat.matcher(value).matches();
        }
    }

    private enum SpecialType {
        CODEPOINTS(new CodepointsTypeHandler()),
        REORDER_CODE(new ReorderCodeTypeHandler()),
        RG_KEY_VALUE(new RgKeyValueTypeHandler()),
        SUBDIVISION_CODE(new SubdivisionKeyValueTypeHandler()),
        PRIVATE_USE(new PrivateUseKeyValueTypeHandler()),
        ;
        SpecialTypeHandler handler;
        SpecialType(SpecialTypeHandler handler) {
            this.handler = handler;
        }
    };

    private static class KeyData {
        String legacyId;
        String bcpId;
        Map<String, Type> typeMap;
        EnumSet<SpecialType> specialTypes;

        KeyData(String legacyId, String bcpId, Map<String, Type> typeMap,
                EnumSet<SpecialType> specialTypes) {
            this.legacyId = legacyId;
            this.bcpId = bcpId;
            this.typeMap = typeMap;
            this.specialTypes = specialTypes;
        }
    }

    private static class Type {
        String legacyId;
        String bcpId;

        Type(String legacyId, String bcpId) {
            this.legacyId = legacyId;
            this.bcpId = bcpId;
        }
    }

    public static String toBcpKey(String key) {
        key = AsciiUtil.toLowerString(key);
        KeyData keyData = KEYMAP.get(key);
        if (keyData != null) {
            return keyData.bcpId;
        }
        return null;
    }

    public static String toLegacyKey(String key) {
        key = AsciiUtil.toLowerString(key);
        KeyData keyData = KEYMAP.get(key);
        if (keyData != null) {
            return keyData.legacyId;
        }
        return null;
    }

    public static String toBcpType(String key, String type,
            Output<Boolean> isKnownKey, Output<Boolean> isSpecialType) {

        if (isKnownKey != null) {
            isKnownKey.value = false;
        }
        if (isSpecialType != null) {
            isSpecialType.value = false;
        }

        key = AsciiUtil.toLowerString(key);
        type = AsciiUtil.toLowerString(type);

        KeyData keyData = KEYMAP.get(key);
        if (keyData != null) {
            if (isKnownKey != null) {
                isKnownKey.value = Boolean.TRUE;
            }
            Type t = keyData.typeMap.get(type);
            if (t != null) {
                return t.bcpId;
            }
            if (keyData.specialTypes != null) {
                for (SpecialType st : keyData.specialTypes) {
                    if (st.handler.isWellFormed(type)) {
                        if (isSpecialType != null) {
                            isSpecialType.value = true;
                        }
                        return st.handler.canonicalize(type);
                    }
                }
            }
        }
        return null;
    }


    public static String toLegacyType(String key, String type,
            Output<Boolean> isKnownKey, Output<Boolean> isSpecialType) {

        if (isKnownKey != null) {
            isKnownKey.value = false;
        }
        if (isSpecialType != null) {
            isSpecialType.value = false;
        }

        key = AsciiUtil.toLowerString(key);
        type = AsciiUtil.toLowerString(type);

        KeyData keyData = KEYMAP.get(key);
        if (keyData != null) {
            if (isKnownKey != null) {
                isKnownKey.value = Boolean.TRUE;
            }
            Type t = keyData.typeMap.get(type);
            if (t != null) {
                return t.legacyId;
            }
            if (keyData.specialTypes != null) {
                for (SpecialType st : keyData.specialTypes) {
                    if (st.handler.isWellFormed(type)) {
                        if (isSpecialType != null) {
                            isSpecialType.value = true;
                        }
                        return st.handler.canonicalize(type);
                    }
                }
            }
        }
        return null;
    }

    private static void initFromResourceBundle() {
        UResourceBundle keyTypeDataRes = UResourceBundle.getBundleInstance(
                ICUData.ICU_BASE_NAME,
                "keyTypeData",
                ICUResourceBundle.ICU_DATA_CLASS_LOADER);

        getKeyInfo(keyTypeDataRes.get("keyInfo"));
        getTypeInfo(keyTypeDataRes.get("typeInfo"));

        UResourceBundle keyMapRes = keyTypeDataRes.get("keyMap");
        UResourceBundle typeMapRes = keyTypeDataRes.get("typeMap");

        // alias data is optional
        UResourceBundle typeAliasRes = null;
        UResourceBundle bcpTypeAliasRes = null;

        try {
            typeAliasRes = keyTypeDataRes.get("typeAlias");
        } catch (MissingResourceException e) {
            // fall through
        }

        try {
            bcpTypeAliasRes = keyTypeDataRes.get("bcpTypeAlias");
        } catch (MissingResourceException e) {
            // fall through
        }

        // iterate through keyMap resource
        UResourceBundleIterator keyMapItr = keyMapRes.getIterator();
        Map<String,Set<String>> _Bcp47Keys = new LinkedHashMap<String,Set<String>>();

        while (keyMapItr.hasNext()) {
            UResourceBundle keyMapEntry = keyMapItr.next();
            String legacyKeyId = keyMapEntry.getKey();
            String bcpKeyId = keyMapEntry.getString();

            boolean hasSameKey = false;
            if (bcpKeyId.length() == 0) {
                // Empty value indicates that BCP key is same with the legacy key.
                bcpKeyId = legacyKeyId;
                hasSameKey = true;
            }
            final LinkedHashSet<String> _bcp47Types = new LinkedHashSet<String>();
            _Bcp47Keys.put(bcpKeyId, Collections.unmodifiableSet(_bcp47Types));

            boolean isTZ = legacyKeyId.equals("timezone");

            // reverse type alias map
            Map<String, Set<String>> typeAliasMap = null;
            if (typeAliasRes != null) {
                UResourceBundle typeAliasResByKey = null;
                try {
                    typeAliasResByKey = typeAliasRes.get(legacyKeyId);
                } catch (MissingResourceException e) {
                    // fall through
                }
                if (typeAliasResByKey != null) {
                    typeAliasMap = new HashMap<String, Set<String>>();
                    UResourceBundleIterator typeAliasResItr = typeAliasResByKey.getIterator();
                    while (typeAliasResItr.hasNext()) {
                        UResourceBundle typeAliasDataEntry = typeAliasResItr.next();
                        String from = typeAliasDataEntry.getKey();
                        String to = typeAliasDataEntry.getString();
                        if (isTZ) {
                            from = from.replace(':', '/');
                        }
                        Set<String> aliasSet = typeAliasMap.get(to);
                        if (aliasSet == null) {
                            aliasSet = new HashSet<String>();
                            typeAliasMap.put(to, aliasSet);
                        }
                        aliasSet.add(from);
                    }
                }
            }

            // reverse bcp type alias map
            Map<String, Set<String>> bcpTypeAliasMap = null;
            if (bcpTypeAliasRes != null) {
                UResourceBundle bcpTypeAliasResByKey = null;
                try {
                    bcpTypeAliasResByKey = bcpTypeAliasRes.get(bcpKeyId);
                } catch (MissingResourceException e) {
                    // fall through
                }
                if (bcpTypeAliasResByKey != null) {
                    bcpTypeAliasMap = new HashMap<String, Set<String>>();
                    UResourceBundleIterator bcpTypeAliasResItr = bcpTypeAliasResByKey.getIterator();
                    while (bcpTypeAliasResItr.hasNext()) {
                        UResourceBundle bcpTypeAliasDataEntry = bcpTypeAliasResItr.next();
                        String from = bcpTypeAliasDataEntry.getKey();
                        String to = bcpTypeAliasDataEntry.getString();
                        Set<String> aliasSet = bcpTypeAliasMap.get(to);
                        if (aliasSet == null) {
                            aliasSet = new HashSet<String>();
                            bcpTypeAliasMap.put(to, aliasSet);
                        }
                        aliasSet.add(from);
                    }
                }
            }

            Map<String, Type> typeDataMap = new HashMap<String, Type>();
            EnumSet<SpecialType> specialTypeSet = null;

            // look up type map for the key, and walk through the mapping data
            UResourceBundle typeMapResByKey = null;
            try {
                typeMapResByKey = typeMapRes.get(legacyKeyId);
            } catch (MissingResourceException e) {
                // type map for each key must exist
                assert false;
            }
            if (typeMapResByKey != null) {
                UResourceBundleIterator typeMapResByKeyItr = typeMapResByKey.getIterator();
                while (typeMapResByKeyItr.hasNext()) {
                    UResourceBundle typeMapEntry = typeMapResByKeyItr.next();
                    String legacyTypeId = typeMapEntry.getKey();
                    String bcpTypeId = typeMapEntry.getString();

                    // special types
                    final char first = legacyTypeId.charAt(0);
                    final boolean isSpecialType = '9' < first && first < 'a' && bcpTypeId.length() == 0;
                    if (isSpecialType) {
                        if (specialTypeSet == null) {
                            specialTypeSet = EnumSet.noneOf(SpecialType.class);
                        }
                        specialTypeSet.add(SpecialType.valueOf(legacyTypeId));
                        _bcp47Types.add(legacyTypeId);
                        continue;
                    }

                    if (isTZ) {
                        // a timezone key uses a colon instead of a slash in the resource.
                        // e.g. America:Los_Angeles
                        legacyTypeId = legacyTypeId.replace(':', '/');
                    }

                    boolean hasSameType = false;
                    if (bcpTypeId.length() == 0) {
                        // Empty value indicates that BCP type is same with the legacy type.
                        bcpTypeId = legacyTypeId;
                        hasSameType = true;
                    }
                    _bcp47Types.add(bcpTypeId);

                    // Note: legacy type value should never be
                    // equivalent to bcp type value of a different
                    // type under the same key. So we use a single
                    // map for lookup.
                    Type t = new Type(legacyTypeId, bcpTypeId);
                    typeDataMap.put(AsciiUtil.toLowerString(legacyTypeId), t);
                    if (!hasSameType) {
                        typeDataMap.put(AsciiUtil.toLowerString(bcpTypeId), t);
                    }

                    // Also put aliases in the map
                    if (typeAliasMap != null) {
                        Set<String> typeAliasSet = typeAliasMap.get(legacyTypeId);
                        if (typeAliasSet != null) {
                            for (String alias : typeAliasSet) {
                                typeDataMap.put(AsciiUtil.toLowerString(alias), t);
                            }
                        }
                    }
                    if (bcpTypeAliasMap != null) {
                        Set<String> bcpTypeAliasSet = bcpTypeAliasMap.get(bcpTypeId);
                        if (bcpTypeAliasSet != null) {
                            for (String alias : bcpTypeAliasSet) {
                                typeDataMap.put(AsciiUtil.toLowerString(alias), t);
                            }
                        }
                    }
                }
            }

            KeyData keyData = new KeyData(legacyKeyId, bcpKeyId, typeDataMap, specialTypeSet);

            KEYMAP.put(AsciiUtil.toLowerString(legacyKeyId), keyData);
            if (!hasSameKey) {
                KEYMAP.put(AsciiUtil.toLowerString(bcpKeyId), keyData);
            }
        }
        BCP47_KEYS = Collections.unmodifiableMap(_Bcp47Keys);
    }

    static Set<String> DEPRECATED_KEYS = Collections.emptySet(); // default for no resources
    static Map<String, ValueType> VALUE_TYPES = Collections.emptyMap(); // default for no resources
    static Map<String, Set<String>> DEPRECATED_KEY_TYPES = Collections.emptyMap(); // default for no resources

    private enum KeyInfoType {deprecated, valueType}
    private enum TypeInfoType {deprecated}

    /** Reads
keyInfo{
    deprecated{
        kh{"true"}
        vt{"true"}
    }
    valueType{
        ca{"incremental"}
        kr{"multiple"}
        vt{"multiple"}
        x0{"any"}
    }
}
     */
    private static void getKeyInfo(UResourceBundle keyInfoRes) {
        Set<String> _deprecatedKeys = new LinkedHashSet<String>();
        Map<String, ValueType> _valueTypes = new LinkedHashMap<String, ValueType>();
        for (UResourceBundleIterator keyInfoIt = keyInfoRes.getIterator(); keyInfoIt.hasNext();) {
            UResourceBundle keyInfoEntry = keyInfoIt.next();
            String key = keyInfoEntry.getKey();
            KeyInfoType keyInfo = KeyInfoType.valueOf(key);
            for (UResourceBundleIterator keyInfoIt2 = keyInfoEntry.getIterator(); keyInfoIt2.hasNext();) {
                UResourceBundle keyInfoEntry2 = keyInfoIt2.next();
                String key2 = keyInfoEntry2.getKey();
                String value2 = keyInfoEntry2.getString();
                switch (keyInfo) {
                case deprecated:
                    _deprecatedKeys.add(key2);
                    break;
                case valueType:
                    _valueTypes.put(key2, ValueType.valueOf(value2));
                    break;
                }
            }
        }
        DEPRECATED_KEYS = Collections.unmodifiableSet(_deprecatedKeys);
        VALUE_TYPES = Collections.unmodifiableMap(_valueTypes);
    }

    /** Reads:
typeInfo{
    deprecated{
        co{
            direct{"true"}
        }
        tz{
            camtr{"true"}
        }
    }
}
     */
    private static void getTypeInfo(UResourceBundle typeInfoRes) {
        Map<String,Set<String>> _deprecatedKeyTypes = new LinkedHashMap<String,Set<String>>();
        for (UResourceBundleIterator keyInfoIt = typeInfoRes.getIterator(); keyInfoIt.hasNext();) {
            UResourceBundle keyInfoEntry = keyInfoIt.next();
            String key = keyInfoEntry.getKey();
            TypeInfoType typeInfo = TypeInfoType.valueOf(key);
            for (UResourceBundleIterator keyInfoIt2 = keyInfoEntry.getIterator(); keyInfoIt2.hasNext();) {
                UResourceBundle keyInfoEntry2 = keyInfoIt2.next();
                String key2 = keyInfoEntry2.getKey();
                Set<String> _deprecatedTypes = new LinkedHashSet<String>();
                for (UResourceBundleIterator keyInfoIt3 = keyInfoEntry2.getIterator(); keyInfoIt3.hasNext();) {
                    UResourceBundle keyInfoEntry3 = keyInfoIt3.next();
                    String key3 = keyInfoEntry3.getKey();
                    switch (typeInfo) { // allow for expansion
                    case deprecated:
                        _deprecatedTypes.add(key3);
                        break;
                    }
                }
                _deprecatedKeyTypes.put(key2, Collections.unmodifiableSet(_deprecatedTypes));
            }
        }
        DEPRECATED_KEY_TYPES = Collections.unmodifiableMap(_deprecatedKeyTypes);
    }

    //
    // Note:    The key-type data is currently read from ICU resource bundle keyTypeData.res.
    //          In future, we may import the data into code like below directly from CLDR to
    //          avoid cyclic dependency between ULocale and UResourceBundle. For now, the code
    //          below is just for proof of concept, and commented out.
    //

    //    private static final String[][] TYPE_DATA_CA = {
    //     // {<legacy type>, <bcp type - if different>},
    //        {"buddhist", null},
    //        {"chinese", null},
    //        {"coptic", null},
    //        {"dangi", null},
    //        {"ethiopic", null},
    //        {"ethiopic-amete-alem", "ethioaa"},
    //        {"gregorian", "gregory"},
    //        {"hebrew", null},
    //        {"indian", null},
    //        {"islamic", null},
    //        {"islamic-civil", null},
    //        {"islamic-rgsa", null},
    //        {"islamic-tbla", null},
    //        {"islamic-umalqura", null},
    //        {"iso8601", null},
    //        {"japanese", null},
    //        {"persian", null},
    //        {"roc", null},
    //    };
    //
    //    private static final String[][] TYPE_DATA_KS = {
    //     // {<legacy type>, <bcp type - if different>},
    //        {"identical", "identic"},
    //        {"primary", "level1"},
    //        {"quaternary", "level4"},
    //        {"secondary", "level2"},
    //        {"tertiary", "level3"},
    //    };
    //
    //    private static final String[][] TYPE_ALIAS_KS = {
    //     // {<legacy alias>, <legacy canonical>},
    //        {"quarternary", "quaternary"},
    //    };
    //
    //    private static final String[][] BCP_TYPE_ALIAS_CA = {
    //     // {<bcp deprecated>, <bcp preferred>
    //        {"islamicc", "islamic-civil"},
    //    };
    //
    //    private static final Object[][] KEY_DATA = {
    //     // {<legacy key>, <bcp key - if different>, <type map>, <type alias>, <bcp type alias>},
    //        {"calendar", "ca", TYPE_DATA_CA, null, BCP_TYPE_ALIAS_CA},
    //        {"colstrength", "ks", TYPE_DATA_KS, TYPE_ALIAS_KS, null},
    //    };

    private static final Object[][] KEY_DATA = {};

    @SuppressWarnings("unused")
    private static void initFromTables() {
        for (Object[] keyDataEntry : KEY_DATA) {
            String legacyKeyId = (String)keyDataEntry[0];
            String bcpKeyId = (String)keyDataEntry[1];
            String[][] typeData = (String[][])keyDataEntry[2];
            String[][] typeAliasData = (String[][])keyDataEntry[3];
            String[][] bcpTypeAliasData = (String[][])keyDataEntry[4];

            boolean hasSameKey = false;
            if (bcpKeyId == null) {
                bcpKeyId = legacyKeyId;
                hasSameKey = true;
            }

            // reverse type alias map
            Map<String, Set<String>> typeAliasMap = null;
            if (typeAliasData != null) {
                typeAliasMap = new HashMap<String, Set<String>>();
                for (String[] typeAliasDataEntry : typeAliasData) {
                    String from = typeAliasDataEntry[0];
                    String to = typeAliasDataEntry[1];
                    Set<String> aliasSet = typeAliasMap.get(to);
                    if (aliasSet == null) {
                        aliasSet = new HashSet<String>();
                        typeAliasMap.put(to, aliasSet);
                    }
                    aliasSet.add(from);
                }
            }

            // BCP type alias map data
            Map<String, Set<String>> bcpTypeAliasMap = null;
            if (bcpTypeAliasData != null) {
                bcpTypeAliasMap = new HashMap<String, Set<String>>();
                for (String[] bcpTypeAliasDataEntry : bcpTypeAliasData) {
                    String from = bcpTypeAliasDataEntry[0];
                    String to = bcpTypeAliasDataEntry[1];
                    Set<String> aliasSet = bcpTypeAliasMap.get(to);
                    if (aliasSet == null) {
                        aliasSet = new HashSet<String>();
                        bcpTypeAliasMap.put(to, aliasSet);
                    }
                    aliasSet.add(from);
                }
            }

            // Type map data
            assert typeData != null;
            Map<String, Type> typeDataMap = new HashMap<String, Type>();
            Set<SpecialType> specialTypeSet = null;

            for (String[] typeDataEntry : typeData) {
                String legacyTypeId = typeDataEntry[0];
                String bcpTypeId = typeDataEntry[1];

                // special types
                boolean isSpecialType = false;
                for (SpecialType st : SpecialType.values()) {
                    if (legacyTypeId.equals(st.toString())) {
                        isSpecialType = true;
                        if (specialTypeSet == null) {
                            specialTypeSet = new HashSet<SpecialType>();
                        }
                        specialTypeSet.add(st);
                        break;
                    }
                }
                if (isSpecialType) {
                    continue;
                }

                boolean hasSameType = false;
                if (bcpTypeId == null) {
                    bcpTypeId = legacyTypeId;
                    hasSameType = true;
                }

                // Note: legacy type value should never be
                // equivalent to bcp type value of a different
                // type under the same key. So we use a single
                // map for lookup.
                Type t = new Type(legacyTypeId, bcpTypeId);
                typeDataMap.put(AsciiUtil.toLowerString(legacyTypeId), t);
                if (!hasSameType) {
                    typeDataMap.put(AsciiUtil.toLowerString(bcpTypeId), t);
                }

                // Also put aliases in the index
                Set<String> typeAliasSet = typeAliasMap.get(legacyTypeId);
                if (typeAliasSet != null) {
                    for (String alias : typeAliasSet) {
                        typeDataMap.put(AsciiUtil.toLowerString(alias), t);
                    }
                }
                Set<String> bcpTypeAliasSet = bcpTypeAliasMap.get(bcpTypeId);
                if (bcpTypeAliasSet != null) {
                    for (String alias : bcpTypeAliasSet) {
                        typeDataMap.put(AsciiUtil.toLowerString(alias), t);
                    }
                }
            }

            EnumSet<SpecialType> specialTypes = null;
            if (specialTypeSet != null) {
                specialTypes = EnumSet.copyOf(specialTypeSet);
            }

            KeyData keyData = new KeyData(legacyKeyId, bcpKeyId, typeDataMap, specialTypes);

            KEYMAP.put(AsciiUtil.toLowerString(legacyKeyId), keyData);
            if (!hasSameKey) {
                KEYMAP.put(AsciiUtil.toLowerString(bcpKeyId), keyData);
            }
        }
    }

    private static final Map<String, KeyData> KEYMAP = new HashMap<String, KeyData>();
    private static Map<String, Set<String>> BCP47_KEYS;

    static {
        // initFromTables();
        initFromResourceBundle();
    }

    public static Set<String> getBcp47Keys() {
        return BCP47_KEYS.keySet();
    };
    
    public static Set<String> getBcp47KeyTypes(String key) {
        return BCP47_KEYS.get(key);
    };

    public static boolean isDeprecated(String key) {
        return DEPRECATED_KEYS.contains(key);
    }

    public static boolean isDeprecated(String key, String type) {
        Set<String> deprecatedTypes = DEPRECATED_KEY_TYPES.get(key);
        if (deprecatedTypes == null) {
            return false;
        }
        return deprecatedTypes.contains(type);
    }

    public static ValueType getValueType(String key) {
        ValueType type = VALUE_TYPES.get(key);
        return type == null ? ValueType.single : type;
    }
}
