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

import java.io.ObjectStreamException;
import java.text.FieldPosition;
import java.text.ParseException;
import java.text.ParsePosition;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.MissingResourceException;
import java.util.Set;
import java.util.TreeMap;

import com.ibm.icu.impl.ICUResourceBundle;
import com.ibm.icu.util.Measure;
import com.ibm.icu.util.TimeUnit;
import com.ibm.icu.util.TimeUnitAmount;
import com.ibm.icu.util.ULocale;
import com.ibm.icu.util.ULocale.Category;
import com.ibm.icu.util.UResourceBundle;


/**
 * Format or parse a TimeUnitAmount, using plural rules for the units where available.
 *
 * <P>
 * Code Sample: 
 * <pre>
 *   // create a time unit instance.
 *   // only SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, and YEAR are supported
 *   TimeUnit timeUnit = TimeUnit.SECOND;
 *   // create time unit amount instance - a combination of Number and time unit
 *   TimeUnitAmount source = new TimeUnitAmount(2, timeUnit);
 *   // create time unit format instance
 *   TimeUnitFormat format = new TimeUnitFormat();
 *   // set the locale of time unit format
 *   format.setLocale(new ULocale("en"));
 *   // format a time unit amount
 *   String formatted = format.format(source);
 *   System.out.println(formatted);
 *   try {
 *       // parse a string into time unit amount
 *       TimeUnitAmount result = (TimeUnitAmount) format.parseObject(formatted);
 *       // result should equal to source 
 *   } catch (ParseException e) {
 *   }
 * </pre>
 *
 * <P>
 * @see TimeUnitAmount
 * @see MeasureFormat
 * @author markdavis
 * @deprecated ICU 53 use {@link MeasureFormat} instead.
 */
@Deprecated
public class TimeUnitFormat extends MeasureFormat {

    /**
     * Constant for full name style format. 
     * For example, the full name for "hour" in English is "hour" or "hours".
     * @deprecated ICU 53 see {@link MeasureFormat.FormatWidth}
     */
    @Deprecated
    public static final int FULL_NAME = 0;
    /**
     * Constant for abbreviated name style format. 
     * For example, the abbreviated name for "hour" in English is "hr" or "hrs".
     * @deprecated ICU 53 see {@link MeasureFormat.FormatWidth}
     */
    @Deprecated
    public static final int ABBREVIATED_NAME = 1;
    
    private static final int TOTAL_STYLES = 2;

    private static final long serialVersionUID = -3707773153184971529L;
  
    // These fields are supposed to be the same as the fields in mf. They
    // are here for serialization backward compatibility and to support parsing.
    private NumberFormat format;
    private ULocale locale;
    private int style;
     
    // We use this field in lieu of the super class because the super class
    // is immutable while this class is mutable. The contents of the super class
    // is an empty shell. Every public method of the super class is overridden to
    // delegate to this field. Each time this object mutates, it replaces this field with
    // a new immutable instance.
    private transient MeasureFormat mf;
    
    private transient Map<TimeUnit, Map<String, Object[]>> timeUnitToCountToPatterns;
    private transient PluralRules pluralRules;
    private transient boolean isReady;
    
    private static final String DEFAULT_PATTERN_FOR_SECOND = "{0} s";
    private static final String DEFAULT_PATTERN_FOR_MINUTE = "{0} min";
    private static final String DEFAULT_PATTERN_FOR_HOUR = "{0} h";
    private static final String DEFAULT_PATTERN_FOR_DAY = "{0} d";
    private static final String DEFAULT_PATTERN_FOR_WEEK = "{0} w";
    private static final String DEFAULT_PATTERN_FOR_MONTH = "{0} m";
    private static final String DEFAULT_PATTERN_FOR_YEAR = "{0} y";

    /**
     * Create empty format using full name style, for example, "hours". 
     * Use setLocale and/or setFormat to modify.
     * @deprecated ICU 53 use {@link MeasureFormat} instead.
     */
    @Deprecated
    public TimeUnitFormat() {
        mf = MeasureFormat.getInstance(ULocale.getDefault(), FormatWidth.WIDE);
        isReady = false;
        style = FULL_NAME;
    }

    /**
     * Create TimeUnitFormat given a ULocale, and using full name style.
     * @param locale   locale of this time unit formatter.
     * @deprecated ICU 53 use {@link MeasureFormat} instead.
     */
    @Deprecated
    public TimeUnitFormat(ULocale locale) {
        this(locale, FULL_NAME);
    }

    /**
     * Create TimeUnitFormat given a Locale, and using full name style.
     * @param locale   locale of this time unit formatter.
     * @deprecated ICU 53 use {@link MeasureFormat} instead.
     */
    @Deprecated
    public TimeUnitFormat(Locale locale) {
        this(locale, FULL_NAME);
    }

    /**
     * Create TimeUnitFormat given a ULocale and a formatting style.
     * @param locale   locale of this time unit formatter.
     * @param style    format style, either FULL_NAME or ABBREVIATED_NAME style.
     * @throws IllegalArgumentException if the style is not FULL_NAME or
     *                                  ABBREVIATED_NAME style.
     * @deprecated ICU 53 use {@link MeasureFormat} instead.
     */
    @Deprecated
    public TimeUnitFormat(ULocale locale, int style) {
        if (style < FULL_NAME || style >= TOTAL_STYLES) {
            throw new IllegalArgumentException("style should be either FULL_NAME or ABBREVIATED_NAME style");
        }
        mf = MeasureFormat.getInstance(
                locale, style == FULL_NAME ? FormatWidth.WIDE : FormatWidth.SHORT);
        this.style = style;
        
        // Needed for getLocale(ULocale.VALID_LOCALE)
        setLocale(locale, locale);
        this.locale = locale;
        isReady = false;
    }
    
    private TimeUnitFormat(ULocale locale, int style, NumberFormat numberFormat) {
        this(locale, style);
        if (numberFormat != null) {
            setNumberFormat((NumberFormat) numberFormat.clone());
        }
    }

    /**
     * Create TimeUnitFormat given a Locale and a formatting style.
     * @deprecated ICU 53 use {@link MeasureFormat} instead.
     */
    @Deprecated
    public TimeUnitFormat(Locale locale, int style) {
        this(ULocale.forLocale(locale),  style);
    }

    /**
     * Set the locale used for formatting or parsing.
     * @param locale   locale of this time unit formatter.
     * @return this, for chaining.
     * @deprecated ICU 53 see {@link MeasureFormat}.
     */
    @Deprecated
    public TimeUnitFormat setLocale(ULocale locale) {
        if (locale != this.locale){
            mf = mf.withLocale(locale);
            
            // Needed for getLocale(ULocale.VALID_LOCALE)
            setLocale(locale, locale);
            this.locale = locale;
            isReady = false;
        }
        return this;
    }
    
    /**
     * Set the locale used for formatting or parsing.
     * @param locale   locale of this time unit formatter.
     * @return this, for chaining.
     * @deprecated ICU 53 see {@link MeasureFormat}.
     */
    @Deprecated
    public TimeUnitFormat setLocale(Locale locale) {
        return setLocale(ULocale.forLocale(locale));
    }
    
    /**
     * Set the format used for formatting or parsing. Passing null is equivalent to passing
     * {@link NumberFormat#getNumberInstance(ULocale)}.
     * @param format   the number formatter.
     * @return this, for chaining.
     * @deprecated ICU 53 see {@link MeasureFormat}.
     */
    @Deprecated
    public TimeUnitFormat setNumberFormat(NumberFormat format) {
        if (format == this.format) {
            return this;
        }
        if (format == null) {
            if (locale == null) {
                isReady = false;
                mf = mf.withLocale(ULocale.getDefault());
            } else {
                this.format = NumberFormat.getNumberInstance(locale);
                mf = mf.withNumberFormat(this.format);
            }
        } else {
            this.format = format;
            mf = mf.withNumberFormat(this.format);
        }
        return this;
    }


    /**
     * Format a TimeUnitAmount.
     * @see java.text.Format#format(java.lang.Object, java.lang.StringBuffer, java.text.FieldPosition)
     * @deprecated ICU 53 see {@link MeasureFormat}.
     */
    @Deprecated
    public StringBuffer format(Object obj, StringBuffer toAppendTo,
            FieldPosition pos) {
        return mf.format(obj, toAppendTo, pos);
    }
    
    /**
     * Parse a TimeUnitAmount.
     * @see java.text.Format#parseObject(java.lang.String, java.text.ParsePosition)
     * @deprecated ICU 53 see {@link MeasureFormat}.
     */
    @Deprecated
    @Override
    public TimeUnitAmount parseObject(String source, ParsePosition pos) {
        if (!isReady) {
            setup();
        }
        Number resultNumber = null;
        TimeUnit resultTimeUnit = null;
        int oldPos = pos.getIndex();
        int newPos = -1;
        int longestParseDistance = 0;
        String countOfLongestMatch = null;
        // we don't worry too much about speed on parsing, but this can be optimized later if needed.
        // Parse by iterating through all available patterns
        // and looking for the longest match.
        for (TimeUnit timeUnit : timeUnitToCountToPatterns.keySet()) {
            Map<String, Object[]> countToPattern = timeUnitToCountToPatterns.get(timeUnit);
            for (Entry<String, Object[]> patternEntry : countToPattern.entrySet()) {
                String count = patternEntry.getKey();
                for (int styl = FULL_NAME; styl < TOTAL_STYLES; ++styl) {
                    MessageFormat pattern = (MessageFormat) (patternEntry.getValue())[styl];
                    pos.setErrorIndex(-1);
                    pos.setIndex(oldPos);
                    // see if we can parse
                    Object parsed = pattern.parseObject(source, pos);
                    if (pos.getErrorIndex() != -1 || pos.getIndex() == oldPos) {
                        // nothing parsed
                        continue;
                    }
                    Number temp = null;
                    if (((Object[]) parsed).length != 0) {
                        // pattern with Number as beginning,
                        // such as "{0} d".
                        // check to make sure that the timeUnit is consistent
                        Object tempObj = ((Object[]) parsed)[0];
                        if (tempObj instanceof Number) {
                            temp = (Number) tempObj;
                        } else {
                            // Since we now format the number ourselves, parseObject will likely give us back a String
                            // for
                            // the number. When this happens we must parse the formatted number ourselves.
                            try {
                                temp = format.parse(tempObj.toString());
                            } catch (ParseException e) {
                                continue;
                            }
                        }
                    }
                    int parseDistance = pos.getIndex() - oldPos;
                    if (parseDistance > longestParseDistance) {
                        resultNumber = temp;
                        resultTimeUnit = timeUnit;
                        newPos = pos.getIndex();
                        longestParseDistance = parseDistance;
                        countOfLongestMatch = count;
                    }
                }
            }
        }
        /*
         * After find the longest match, parse the number. Result number could be null for the pattern without number
         * pattern. such as unit pattern in Arabic. When result number is null, use plural rule to set the number.
         */
        if (resultNumber == null && longestParseDistance != 0) {
            // set the number using plurrual count
            if (countOfLongestMatch.equals("zero")) {
                resultNumber = Integer.valueOf(0);
            } else if (countOfLongestMatch.equals("one")) {
                resultNumber = Integer.valueOf(1);
            } else if (countOfLongestMatch.equals("two")) {
                resultNumber = Integer.valueOf(2);
            } else {
                // should not happen.
                // TODO: how to handle?
                resultNumber = Integer.valueOf(3);
            }
        }
        if (longestParseDistance == 0) {
            pos.setIndex(oldPos);
            pos.setErrorIndex(0);
            return null;
        } else {
            pos.setIndex(newPos);
            pos.setErrorIndex(-1);
            return new TimeUnitAmount(resultNumber, resultTimeUnit);
        }
    }
    
    private void setup() {
        if (locale == null) {
            if (format != null) {
                locale = format.getLocale(null);
            } else {
                locale = ULocale.getDefault(Category.FORMAT);
            }
            // Needed for getLocale(ULocale.VALID_LOCALE)
            setLocale(locale, locale);
        }
        if (format == null) {
            format = NumberFormat.getNumberInstance(locale);
        }
        pluralRules = PluralRules.forLocale(locale);
        timeUnitToCountToPatterns = new HashMap<TimeUnit, Map<String, Object[]>>();
        Set<String> pluralKeywords = pluralRules.getKeywords();
        setup("units/duration", timeUnitToCountToPatterns, FULL_NAME, pluralKeywords);
        setup("unitsShort/duration", timeUnitToCountToPatterns, ABBREVIATED_NAME, pluralKeywords);
        isReady = true;
    }
    
    private void setup(String resourceKey, Map<TimeUnit, Map<String, Object[]>> timeUnitToCountToPatterns, int style,
            Set<String> pluralKeywords) {
        // fill timeUnitToCountToPatterns from resource file
        try {
            ICUResourceBundle resource = (ICUResourceBundle) UResourceBundle.getBundleInstance(
                    ICUResourceBundle.ICU_BASE_NAME, locale);
            ICUResourceBundle unitsRes = resource.getWithFallback(resourceKey);
            int size = unitsRes.getSize();
            for (int index = 0; index < size; ++index) {
                String timeUnitName = unitsRes.get(index).getKey();
                TimeUnit timeUnit = null;
                if (timeUnitName.equals("year")) {
                    timeUnit = TimeUnit.YEAR;
                } else if (timeUnitName.equals("month")) {
                    timeUnit = TimeUnit.MONTH;
                } else if (timeUnitName.equals("day")) {
                    timeUnit = TimeUnit.DAY;
                } else if (timeUnitName.equals("hour")) {
                    timeUnit = TimeUnit.HOUR;
                } else if (timeUnitName.equals("minute")) {
                    timeUnit = TimeUnit.MINUTE;
                } else if (timeUnitName.equals("second")) {
                    timeUnit = TimeUnit.SECOND;
                } else if (timeUnitName.equals("week")) {
                    timeUnit = TimeUnit.WEEK;
                } else {
                    continue;
                }
                ICUResourceBundle oneUnitRes = unitsRes.getWithFallback(timeUnitName);
                int count = oneUnitRes.getSize();
                Map<String, Object[]> countToPatterns = timeUnitToCountToPatterns.get(timeUnit);
                if (countToPatterns == null) {
                    countToPatterns = new TreeMap<String, Object[]>();
                    timeUnitToCountToPatterns.put(timeUnit, countToPatterns);
                }
                for (int pluralIndex = 0; pluralIndex < count; ++pluralIndex) {
                    String pluralCount = oneUnitRes.get(pluralIndex).getKey();
                    if (!pluralKeywords.contains(pluralCount))
                        continue;
                    String pattern = oneUnitRes.get(pluralIndex).getString();
                    final MessageFormat messageFormat = new MessageFormat(pattern, locale);
                    // save both full name and abbreviated name in one table
                    // is good space-wise, but it degrades performance,
                    // since it needs to check whether the needed space
                    // is already allocated or not.
                    Object[] pair = countToPatterns.get(pluralCount);
                    if (pair == null) {
                        pair = new Object[2];
                        countToPatterns.put(pluralCount, pair);
                    }
                    pair[style] = messageFormat;
                }
            }
        } catch (MissingResourceException e) {
        }
        // there should be patterns for each plural rule in each time unit.
        // For each time unit,
        // for each plural rule, following is unit pattern fall-back rule:
        // ( for example: "one" hour )
        // look for its unit pattern in its locale tree.
        // if pattern is not found in its own locale, such as de_DE,
        // look for the pattern in its parent, such as de,
        // keep looking till found or till root.
        // if the pattern is not found in root either,
        // fallback to plural count "other",
        // look for the pattern of "other" in the locale tree:
        // "de_DE" to "de" to "root".
        // If not found, fall back to value of
        // static variable DEFAULT_PATTERN_FOR_xxx, such as "{0} h".
        //
        // Following is consistency check to create pattern for each
        // plural rule in each time unit using above fall-back rule.
        //
        final TimeUnit[] timeUnits = TimeUnit.values();
        Set<String> keywords = pluralRules.getKeywords();
        for (int i = 0; i < timeUnits.length; ++i) {
            // for each time unit,
            // get all the patterns for each plural rule in this locale.
            final TimeUnit timeUnit = timeUnits[i];
            Map<String, Object[]> countToPatterns = timeUnitToCountToPatterns.get(timeUnit);
            if (countToPatterns == null) {
                countToPatterns = new TreeMap<String, Object[]>();
                timeUnitToCountToPatterns.put(timeUnit, countToPatterns);
            }
            for (String pluralCount : keywords) {
                if (countToPatterns.get(pluralCount) == null || countToPatterns.get(pluralCount)[style] == null) {
                    // look through parents
                    searchInTree(resourceKey, style, timeUnit, pluralCount, pluralCount, countToPatterns);
                }
            }
        }
    }

    // srcPluralCount is the original plural count on which the pattern is
    // searched for.
    // searchPluralCount is the fallback plural count.
    // For example, to search for pattern for ""one" hour",
    // "one" is the srcPluralCount,
    // if the pattern is not found even in root, fallback to
    // using patterns of plural count "other",
    // then, "other" is the searchPluralCount.
    private void searchInTree(String resourceKey, int styl, TimeUnit timeUnit, String srcPluralCount,
            String searchPluralCount, Map<String, Object[]> countToPatterns) {
        ULocale parentLocale = locale;
        String srcTimeUnitName = timeUnit.toString();
        while (parentLocale != null) {
            try {
                // look for pattern for srcPluralCount in locale tree
                ICUResourceBundle unitsRes = (ICUResourceBundle) UResourceBundle.getBundleInstance(
                        ICUResourceBundle.ICU_BASE_NAME, parentLocale);
                unitsRes = unitsRes.getWithFallback(resourceKey);
                ICUResourceBundle oneUnitRes = unitsRes.getWithFallback(srcTimeUnitName);
                String pattern = oneUnitRes.getStringWithFallback(searchPluralCount);
                final MessageFormat messageFormat = new MessageFormat(pattern, locale);
                Object[] pair = countToPatterns.get(srcPluralCount);
                if (pair == null) {
                    pair = new Object[2];
                    countToPatterns.put(srcPluralCount, pair);
                }
                pair[styl] = messageFormat;
                return;
            } catch (MissingResourceException e) {
            }
            parentLocale = parentLocale.getFallback();
        }
        // if no unitsShort resource was found even after fallback to root locale
        // then search the units resource fallback from the current level to root
        if (parentLocale == null && resourceKey.equals("unitsShort")) {
            searchInTree("units", styl, timeUnit, srcPluralCount, searchPluralCount, countToPatterns);
            if (countToPatterns != null && countToPatterns.get(srcPluralCount) != null
                    && countToPatterns.get(srcPluralCount)[styl] != null) {
                return;
            }
        }
        // if not found the pattern for this plural count at all,
        // fall-back to plural count "other"
        if (searchPluralCount.equals("other")) {
            // set default fall back the same as the resource in root
            MessageFormat messageFormat = null;
            if (timeUnit == TimeUnit.SECOND) {
                messageFormat = new MessageFormat(DEFAULT_PATTERN_FOR_SECOND, locale);
            } else if (timeUnit == TimeUnit.MINUTE) {
                messageFormat = new MessageFormat(DEFAULT_PATTERN_FOR_MINUTE, locale);
            } else if (timeUnit == TimeUnit.HOUR) {
                messageFormat = new MessageFormat(DEFAULT_PATTERN_FOR_HOUR, locale);
            } else if (timeUnit == TimeUnit.WEEK) {
                messageFormat = new MessageFormat(DEFAULT_PATTERN_FOR_WEEK, locale);
            } else if (timeUnit == TimeUnit.DAY) {
                messageFormat = new MessageFormat(DEFAULT_PATTERN_FOR_DAY, locale);
            } else if (timeUnit == TimeUnit.MONTH) {
                messageFormat = new MessageFormat(DEFAULT_PATTERN_FOR_MONTH, locale);
            } else if (timeUnit == TimeUnit.YEAR) {
                messageFormat = new MessageFormat(DEFAULT_PATTERN_FOR_YEAR, locale);
            }
            Object[] pair = countToPatterns.get(srcPluralCount);
            if (pair == null) {
                pair = new Object[2];
                countToPatterns.put(srcPluralCount, pair);
            }
            pair[styl] = messageFormat;
        } else {
            // fall back to rule "other", and search in parents
            searchInTree(resourceKey, styl, timeUnit, srcPluralCount, "other", countToPatterns);
        }
    }
    
    // boilerplate code to make TimeUnitFormat otherwise follow the contract of
    // MeasureFormat

    
    /**
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Deprecated
    @Override
    public StringBuilder formatMeasures(
            StringBuilder appendTo, FieldPosition fieldPosition, Measure... measures) {
        return mf.formatMeasures(appendTo, fieldPosition, measures);
    }
    
    /**
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Deprecated
    @Override
    public MeasureFormat.FormatWidth getWidth() {
        return mf.getWidth();
    }
    
    /**
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Deprecated
    @Override
    public NumberFormat getNumberFormat() {
        return mf.getNumberFormat();
    }
    
    /**
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Deprecated
    @Override
    public Object clone() {
        TimeUnitFormat result = (TimeUnitFormat) super.clone();
        result.format = (NumberFormat) format.clone();
        return result;
    }
    // End boilerplate.
    
    // Serialization
    
    private Object writeReplace() throws ObjectStreamException {
        return mf.toTimeUnitProxy();
    }
    
    // Preserve backward serialize backward compatibility.
    private Object readResolve() throws ObjectStreamException {
        return new TimeUnitFormat(locale, style, format);
    }
}
