/*
 *******************************************************************************
 * Copyright (C) 2002-2011, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */
package com.ibm.icu.dev.test.util;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

import com.ibm.icu.lang.UCharacter;
import com.ibm.icu.lang.UProperty;
import com.ibm.icu.lang.UScript;
import com.ibm.icu.text.Normalizer;
import com.ibm.icu.text.UTF16;
import com.ibm.icu.util.VersionInfo;


/**
 * Provides a general interface for Unicode Properties, and
 * extracting sets based on those values.
 * @author Davis
 */

public class ICUPropertyFactory extends UnicodeProperty.Factory {

    static class ICUProperty extends UnicodeProperty {
        protected int propEnum = Integer.MIN_VALUE;

        protected ICUProperty(String propName, int propEnum) {
            setName(propName);
            this.propEnum = propEnum;
            setType(internalGetPropertyType(propEnum));
            if (propEnum == UProperty.DEFAULT_IGNORABLE_CODE_POINT || propEnum == UProperty.BIDI_CLASS || propEnum == UProperty.GENERAL_CATEGORY) {
                setUniformUnassigned(false);
            } else {
                setUniformUnassigned(true);
            }
        }

        boolean shownException = false;

        public String _getValue(int codePoint) {
            switch (propEnum) {
            case UProperty.AGE:
                return getAge(codePoint);
            case UProperty.BIDI_MIRRORING_GLYPH:
                return UTF16.valueOf(UCharacter.getMirror(codePoint));
            case UProperty.CASE_FOLDING:
                return UCharacter.foldCase(UTF16.valueOf(codePoint), true);
            case UProperty.ISO_COMMENT:
                return UCharacter.getISOComment(codePoint);
            case UProperty.LOWERCASE_MAPPING:
                return UCharacter.toLowerCase(Locale.ENGLISH, UTF16.valueOf(codePoint));
            case UProperty.NAME:
                return UCharacter.getName(codePoint);
            case UProperty.SIMPLE_CASE_FOLDING:
                return UTF16.valueOf(UCharacter.foldCase(codePoint, true));
            case UProperty.SIMPLE_LOWERCASE_MAPPING:
                return UTF16.valueOf(UCharacter.toLowerCase(codePoint));
            case UProperty.SIMPLE_TITLECASE_MAPPING:
                return UTF16.valueOf(UCharacter.toTitleCase(codePoint));
            case UProperty.SIMPLE_UPPERCASE_MAPPING:
                return UTF16.valueOf(UCharacter.toUpperCase(codePoint));
            case UProperty.TITLECASE_MAPPING:
                return UCharacter.toTitleCase(Locale.ENGLISH, UTF16.valueOf(codePoint), null);
            case UProperty.UNICODE_1_NAME:
                return UCharacter.getName1_0(codePoint);
            case UProperty.UPPERCASE_MAPPING:
                return UCharacter.toUpperCase(Locale.ENGLISH, UTF16.valueOf(codePoint));
            // case NFC: return Normalizer.normalize(codePoint, Normalizer.NFC);
            // case NFD: return Normalizer.normalize(codePoint, Normalizer.NFD);
            // case NFKC: return Normalizer.normalize(codePoint, Normalizer.NFKC);
            // case NFKD: return Normalizer.normalize(codePoint, Normalizer.NFKD);
            case isNFC:
                return String.valueOf(Normalizer.normalize(codePoint, Normalizer.NFC).equals(UTF16.valueOf(codePoint)));
            case isNFD:
                return String.valueOf(Normalizer.normalize(codePoint, Normalizer.NFD).equals(UTF16.valueOf(codePoint)));
            case isNFKC:
                return String
                        .valueOf(Normalizer.normalize(codePoint, Normalizer.NFKC).equals(UTF16.valueOf(codePoint)));
            case isNFKD:
                return String
                        .valueOf(Normalizer.normalize(codePoint, Normalizer.NFKD).equals(UTF16.valueOf(codePoint)));
            case isLowercase:
                return String.valueOf(UCharacter.toLowerCase(Locale.ENGLISH, UTF16.valueOf(codePoint)).equals(
                        UTF16.valueOf(codePoint)));
            case isUppercase:
                return String.valueOf(UCharacter.toUpperCase(Locale.ENGLISH, UTF16.valueOf(codePoint)).equals(
                        UTF16.valueOf(codePoint)));
            case isTitlecase:
                return String.valueOf(UCharacter.toTitleCase(Locale.ENGLISH, UTF16.valueOf(codePoint), null).equals(
                        UTF16.valueOf(codePoint)));
            case isCasefolded:
                return String.valueOf(UCharacter.foldCase(UTF16.valueOf(codePoint), true).equals(
                        UTF16.valueOf(codePoint)));
            case isCased:
                return String.valueOf(UCharacter.toLowerCase(Locale.ENGLISH, UTF16.valueOf(codePoint)).equals(
                        UTF16.valueOf(codePoint)));
            case UProperty.SCRIPT_EXTENSIONS: 
                return getStringScriptExtensions(codePoint);
            }
            if (propEnum < UProperty.INT_LIMIT) {
                int enumValue = -1;
                String value = null;
                try {
                    enumValue = UCharacter.getIntPropertyValue(codePoint, propEnum);
                    if (enumValue >= 0)
                        value = fixedGetPropertyValueName(propEnum, enumValue, UProperty.NameChoice.LONG);
                } catch (IllegalArgumentException e) {
                    if (!shownException) {
                        System.out.println("Fail: " + getName() + ", " + Integer.toHexString(codePoint));
                        shownException = true;
                    }
                }
                return value != null ? value : String.valueOf(enumValue);
            } else if (propEnum < UProperty.DOUBLE_LIMIT) {
                double num = UCharacter.getUnicodeNumericValue(codePoint);
                if (num == UCharacter.NO_NUMERIC_VALUE)
                    return null;
                return Double.toString(num);
                // TODO: Fix HACK -- API deficient
            }
            return null;
        }

        private String getAge(int codePoint) {
            String temp = UCharacter.getAge(codePoint).toString();
            if (temp.equals("0.0.0.0"))
                return "unassigned";
            if (temp.endsWith(".0.0"))
                return temp.substring(0, temp.length() - 4);
            return temp;
        }

        /**
         * @param valueAlias null if unused.
         * @param valueEnum -1 if unused
         * @param nameChoice
         * @return
         */
        private String getFixedValueAlias(String valueAlias, int valueEnum, int nameChoice) {
            if (propEnum >= UProperty.STRING_START) {
                if (nameChoice > UProperty.NameChoice.LONG)
                    throw new IllegalArgumentException();
                if (nameChoice != UProperty.NameChoice.LONG)
                    return null;
                return "<string>";
            } else if (propEnum >= UProperty.DOUBLE_START) {
                if (nameChoice > UProperty.NameChoice.LONG)
                    throw new IllegalArgumentException();
                if (nameChoice != UProperty.NameChoice.LONG)
                    return null;
                return "<number>";
            }
            if (valueAlias != null && !valueAlias.equals("<integer>")) {
                valueEnum = fixedGetPropertyValueEnum(propEnum, valueAlias);
            }
            // because these are defined badly, there may be no normal (long) name.
            // if there is
            String result = fixedGetPropertyValueName(propEnum, valueEnum, nameChoice);
            if (result != null)
                return result;
            // HACK try other namechoice
            if (nameChoice == UProperty.NameChoice.LONG) {
                result = fixedGetPropertyValueName(propEnum, valueEnum, UProperty.NameChoice.SHORT);
                if (result != null)
                    return result;
                if (isCombiningClassProperty())
                    return null;
                return "<integer>";
            }
            return null;
        }

        public boolean isCombiningClassProperty() {
            return (propEnum == UProperty.CANONICAL_COMBINING_CLASS
                    || propEnum == UProperty.LEAD_CANONICAL_COMBINING_CLASS
                    || propEnum == UProperty.TRAIL_CANONICAL_COMBINING_CLASS);
        }

        private static int fixedGetPropertyValueEnum(int propEnum, String valueAlias) {
            try {
                if (propEnum < BINARY_LIMIT) {
                    propEnum = UProperty.ALPHABETIC;
                }
                return UCharacter.getPropertyValueEnum(propEnum, valueAlias);
            } catch (Exception e) {
                return Integer.parseInt(valueAlias);
            }
        }

        static Map fixSkeleton = new HashMap();

        private static String fixedGetPropertyValueName(int propEnum, int valueEnum, int nameChoice) {
            String value = UCharacter.getPropertyValueName(propEnum, valueEnum, nameChoice);
            String newValue = (String) fixSkeleton.get(value);
            if (newValue == null) {
                newValue = value;
                if (propEnum == UProperty.JOINING_GROUP) {
                    newValue = newValue == null ? null : newValue.toLowerCase(Locale.ENGLISH);
                }
                newValue = regularize(newValue, true);
                fixSkeleton.put(value, newValue);
            }
            return newValue;
        }

        public List _getNameAliases(List result) {
            if (result == null)
                result = new ArrayList();
            // String alias = String_Extras.get(propEnum);
            // if (alias == null)
            String alias = Binary_Extras.get(propEnum);
            if (alias != null) {
                addUnique(alias, result);
            } else {
                addUnique(getFixedPropertyName(propEnum, UProperty.NameChoice.SHORT), result);
                addUnique(getFixedPropertyName(propEnum, UProperty.NameChoice.LONG), result);
            }
            return result;
        }

        public String getFixedPropertyName(int propName, int nameChoice) {
            try {
                return UCharacter.getPropertyName(propEnum, nameChoice);
            } catch (IllegalArgumentException e) {
                return null;
            }
        }

        private static Map cccHack = new HashMap();
        private static Set cccExtras = new HashSet();
        static {
            for (int i = 0; i <= 255; ++i) {
                String alias = UCharacter.getPropertyValueName(UProperty.CANONICAL_COMBINING_CLASS, i,
                        UProperty.NameChoice.LONG);
                String numStr = String.valueOf(i);
                if (alias != null) {
                    cccHack.put(alias, numStr);
                } else {
                    cccHack.put(numStr, numStr);
                    cccExtras.add(numStr);
                }
            }
        }

        public List _getAvailableValues(List result) {
            if (result == null)
                result = new ArrayList();
            if (propEnum == UProperty.AGE) {
                addAllUnique(getAges(), result);
                return result;

            }
            if (propEnum < UProperty.INT_LIMIT) {
                if (Binary_Extras.isInRange(propEnum)) {
                    propEnum = UProperty.BINARY_START; // HACK
                }
                int start = UCharacter.getIntPropertyMinValue(propEnum);
                int end = UCharacter.getIntPropertyMaxValue(propEnum);
                for (int i = start; i <= end; ++i) {
                    String alias = getFixedValueAlias(null, i, UProperty.NameChoice.LONG);
                    String alias2 = getFixedValueAlias(null, i, UProperty.NameChoice.SHORT);
                    if (alias == null) {
                        alias = alias2;
                        if (alias == null && isCombiningClassProperty()) {
                            alias = String.valueOf(i);
                        }
                    }
                    // System.out.println(propertyAlias + "\t" + i + ":\t" + alias);
                    addUnique(alias, result);
                }
            } else if (propEnum >= UProperty.DOUBLE_START && propEnum < UProperty.DOUBLE_LIMIT) {
                UnicodeMap map = getUnicodeMap();
                Collection values = map.values();
                addAllUnique(values, result);
            } else {
                String alias = getFixedValueAlias(null, -1, UProperty.NameChoice.LONG);
                addUnique(alias, result);
            }
            return result;
        }

        static String[] AGES = null;

        private String[] getAges() {
            if (AGES == null) {
                Set ages = new TreeSet();
                for (int i = 0; i < 0x10FFFF; ++i) {
                    ages.add(getAge(i));
                }
                AGES = (String[]) ages.toArray(new String[ages.size()]);
            }
            return AGES;
        }

        public List _getValueAliases(String valueAlias, List result) {
            if (result == null)
                result = new ArrayList();
            if (propEnum == UProperty.AGE) {
                addUnique(valueAlias, result);
                return result;
            }
            if (isCombiningClassProperty()) {
                addUnique(cccHack.get(valueAlias), result); // add number
            }
            int type = getType();
            if (type == UnicodeProperty.NUMERIC || type == EXTENDED_NUMERIC) {
                addUnique(valueAlias, result);
                if (valueAlias.endsWith(".0")) {
                    addUnique(valueAlias.substring(0, valueAlias.length() - 2), result);
                }
            } else {
                for (int nameChoice = UProperty.NameChoice.SHORT;; ++nameChoice) {
                    try {
                        addUnique(getFixedValueAlias(valueAlias, -1, nameChoice), result);
                    } catch (Exception e) {
                        break;
                    }
                }
            }
            return result;
        }

        /* (non-Javadoc)
         * @see com.ibm.icu.dev.test.util.UnicodePropertySource#getPropertyType()
         */
        private int internalGetPropertyType(int prop) {
            switch (prop) {
            case UProperty.AGE:
            case UProperty.BLOCK:
            case UProperty.SCRIPT:
                return UnicodeProperty.CATALOG;
            case UProperty.ISO_COMMENT:
            case UProperty.NAME:
            case UProperty.UNICODE_1_NAME:
            case UProperty.SCRIPT_EXTENSIONS:
                return UnicodeProperty.MISC;
            case UProperty.BIDI_MIRRORING_GLYPH:
            case UProperty.CASE_FOLDING:
            case UProperty.LOWERCASE_MAPPING:
            case UProperty.SIMPLE_CASE_FOLDING:
            case UProperty.SIMPLE_LOWERCASE_MAPPING:
            case UProperty.SIMPLE_TITLECASE_MAPPING:
            case UProperty.SIMPLE_UPPERCASE_MAPPING:
            case UProperty.TITLECASE_MAPPING:
            case UProperty.UPPERCASE_MAPPING:
                return UnicodeProperty.EXTENDED_STRING;
            }
            if (prop < UProperty.BINARY_START)
                return UnicodeProperty.UNKNOWN;
            if (prop < UProperty.BINARY_LIMIT)
                return UnicodeProperty.BINARY;
            if (prop < UProperty.INT_START)
                return UnicodeProperty.EXTENDED_BINARY;
            if (prop < UProperty.INT_LIMIT)
                return UnicodeProperty.ENUMERATED;
            if (prop < UProperty.DOUBLE_START)
                return UnicodeProperty.EXTENDED_ENUMERATED;
            if (prop < UProperty.DOUBLE_LIMIT)
                return UnicodeProperty.NUMERIC;
            if (prop < UProperty.STRING_START)
                return UnicodeProperty.EXTENDED_NUMERIC;
            if (prop < UProperty.STRING_LIMIT)
                return UnicodeProperty.STRING;
            return UnicodeProperty.EXTENDED_STRING;
        }

        /*
         * (non-Javadoc)
         * 
         * @see com.ibm.icu.dev.test.util.UnicodeProperty#getVersion()
         */
        public String _getVersion() {
            return VersionInfo.ICU_VERSION.toString();
        }
    }

  /*{
            matchIterator = new UnicodeSetIterator(
                new UnicodeSet("[^[:Cn:]-[:Default_Ignorable_Code_Point:]]"));
        }*/



    /*
     * Other Missing Functions:
            Expands_On_NFC
            Expands_On_NFD
            Expands_On_NFKC
            Expands_On_NFKD
            Composition_Exclusion
            Decomposition_Mapping
            FC_NFKC_Closure
            ISO_Comment
            NFC_Quick_Check
            NFD_Quick_Check
            NFKC_Quick_Check
            NFKD_Quick_Check
            Special_Case_Condition
            Unicode_Radical_Stroke
     */

    static final Names Binary_Extras = new Names(UProperty.BINARY_LIMIT,
          new String[] {
          "isNFC", "isNFD", "isNFKC", "isNFKD",
          "isLowercase", "isUppercase", "isTitlecase", "isCasefolded", "isCased",
    });

//    static final Names String_Extras = new Names(UProperty.STRING_LIMIT,
//          new String[] {
//          "toNFC", "toNFD", "toNFKC", "toNKFD",
//    });

    static final int
        isNFC = UProperty.BINARY_LIMIT,
        isNFD = UProperty.BINARY_LIMIT+1,
        isNFKC = UProperty.BINARY_LIMIT+2,
        isNFKD = UProperty.BINARY_LIMIT+3,
        isLowercase = UProperty.BINARY_LIMIT+4,
        isUppercase = UProperty.BINARY_LIMIT+5,
        isTitlecase = UProperty.BINARY_LIMIT+6,
        isCasefolded = UProperty.BINARY_LIMIT+7,
        isCased = UProperty.BINARY_LIMIT+8,
        BINARY_LIMIT = UProperty.BINARY_LIMIT+9

//        NFC  = UProperty.STRING_LIMIT,
//        NFD  = UProperty.STRING_LIMIT+1,
//        NFKC = UProperty.STRING_LIMIT+2,
//        NFKD = UProperty.STRING_LIMIT+3
        ;

    protected ICUPropertyFactory() {
        Collection c = getInternalAvailablePropertyAliases(new ArrayList());
        Iterator it = c.iterator();
        while (it.hasNext()) {
            add(getInternalProperty((String) it.next()));
        }
    }

    static BitSet BITSET = new BitSet();
    /**
     * @param codePoint
     * @return
     */
    public static synchronized String getStringScriptExtensions(int codePoint) {
        UScript.getScriptExtensions(codePoint, BITSET);
        if (BITSET.cardinality() == 0) {
            int scriptCode = UScript.getScript(codePoint);
            return UScript.getName(scriptCode);
        }
        TreeMap<String,String> sorted = new TreeMap<String,String>();
        for (int scriptCode = BITSET.nextSetBit(0); scriptCode >= 0; scriptCode = BITSET.nextSetBit(scriptCode+1)) {
            // sort by short form
            sorted.put(UScript.getShortName(scriptCode), UScript.getName(scriptCode));
        }
        return CollectionUtilities.join(sorted.values(), " ");
    }

    private static ICUPropertyFactory singleton = null;

    public static synchronized ICUPropertyFactory make() {
        if (singleton != null)
            return singleton;
        singleton = new ICUPropertyFactory();
        return singleton;
    }

    public List getInternalAvailablePropertyAliases(List result) {
        int[][] ranges = {
                {UProperty.BINARY_START,    UProperty.BINARY_LIMIT},
                {UProperty.INT_START,       UProperty.INT_LIMIT},
                {UProperty.DOUBLE_START,    UProperty.DOUBLE_LIMIT},
                {UProperty.STRING_START,    UProperty.STRING_LIMIT},
                {UProperty.OTHER_PROPERTY_START, UProperty.OTHER_PROPERTY_LIMIT},

        };
        for (int i = 0; i < ranges.length; ++i) {
            for (int j = ranges[i][0]; j < ranges[i][1]; ++j) {
                String alias = UCharacter.getPropertyName(j, UProperty.NameChoice.LONG);
                UnicodeProperty.addUnique(alias, result);
                if (!result.contains(alias))
                    result.add(alias);
            }
        }
        // result.addAll(String_Extras.getNames());
        result.addAll(Binary_Extras.getNames());
        return result;
    }

    public UnicodeProperty getInternalProperty(String propertyAlias) {
        int propEnum;
        main: {
            int possibleItem = Binary_Extras.get(propertyAlias);
            if (possibleItem >= 0) {
                propEnum = possibleItem;
                break main;
            }
            // possibleItem = String_Extras.get(propertyAlias);
            // if (possibleItem >= 0) {
            // propEnum = possibleItem;
            // break main;
            // }
            propEnum = UCharacter.getPropertyEnum(propertyAlias);
        }
        return new ICUProperty(propertyAlias, propEnum);
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.ibm.icu.dev.test.util.UnicodePropertySource#getProperty(java.lang.String)
     */
    // TODO file bug on getPropertyValueName for Canonical_Combining_Class
    public static class Names {
        private String[] names;
        private int base;

        public Names(int base, String[] names) {
            this.base = base;
            this.names = names;
        }

        public int get(String name) {
            for (int i = 0; i < names.length; ++i) {
                if (name.equalsIgnoreCase(names[i]))
                    return base + i;
            }
            return -1;
        }

        public String get(int number) {
            number -= base;
            if (number < 0 || names.length <= number)
                return null;
            return names[number];
        }

        public boolean isInRange(int number) {
            number -= base;
            return (0 <= number && number < names.length);
        }

        public List getNames() {
            return Arrays.asList(names);
        }
    }
}
