/*
 **************************************************************************
 * 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>
 * @deprecated use {@link MeasureFormat} instead.
 * @see TimeUnitAmount
 * @see MeasureFormat
 * @author markdavis
 * @stable ICU 4.0
 */
public class TimeUnitFormat extends MeasureFormat {

    /**
     * Constant for full name style format. 
     * For example, the full name for "hour" in English is "hour" or "hours".
     * @stable ICU 4.2
     */
    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".
     * @stable ICU 4.2
     */
    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.
     * @stable ICU 4.0
     */
    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.
     * @stable ICU 4.0
     */
    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.
     * @stable ICU 4.0
     */
    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.
     * @stable ICU 4.2
     */
    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.
     * @stable ICU 4.2
     */
    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.
     * @stable ICU 4.0
     */
    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.
     * @stable ICU 4.0
     */
    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.
     * @stable ICU 4.0
     */
    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)
     * @stable ICU 4.0
     */
    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)
     * @stable ICU 4.0
     */
    @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

    /**
     * @draft ICU 53
     * @provisional
     */
    @Override
    public String formatMeasures(Measure... measures) {
        return mf.formatMeasures(measures);
    }
    
    /**
     * @draft ICU 53
     * @provisional
     */
    @Override
    public <T extends Appendable> T formatMeasures(
            T appendable, FieldPosition fieldPosition, Measure... measures) {
        return mf.formatMeasures(appendable, fieldPosition, measures);
    }
    
    /**
     * @draft ICU 53
     * @provisional
     */
    @Override
    public MeasureFormat.FormatWidth getWidth() {
        return mf.getWidth();
    }
    
    /**
     * @draft ICU 53
     * @provisional
     */
    @Override
    public ULocale getLocale() {
        return mf.getLocale();
    }
    
    
    /**
     * @draft ICU 53
     * @provisional
     */
    @Override
    public NumberFormat getNumberFormat() {
        return mf.getNumberFormat();
    }
    
    /**
     * @draft ICU 53
     * @provisional
     */
    @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);
    }
}
