/*
 *******************************************************************************
 * Copyright (C) 2007-2008, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */

package com.ibm.icu.text;

import com.ibm.icu.util.ULocale;
import com.ibm.icu.impl.Utility;

import java.io.Serializable;

import java.text.ParseException;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

/** 
 * <p>Defines rules for mapping positive double values onto a small set of
 * keywords. Serializable so can be used in formatters, which are
 * serializable. Rules are constructed from a text description, consisting
 * of a series of keywords and conditions.  The {@link #select} method
 * examines each condition in order and returns the keyword for the
 * first condition that matches the number.  If none match,
 * {@link #KEYWORD_OTHER} is returned.</p>
 * <p>
 * Examples:<pre>
 *   "one: n is 1; few: n in 2..4"</pre></p>
 * <p>
 * This defines two rules, for 'one' and 'few'.  The condition for
 * 'one' is "n is 1" which means that the number must be equal to
 * 1 for this condition to pass.  The condition for 'few' is
 * "n in 2..4" which means that the number must be between 2 and
 * 4 inclusive - and be an integer - for this condition to pass. All other
 * numbers are assigned the keyword "other" by the default rule.</p>
 * <p><pre>
 *   "zero: n is 0; one: n is 1; zero: n mod 100 in 1..19"</pre>
 * This illustrates that the same keyword can be defined multiple times.
 * Each rule is examined in order, and the first keyword whose condition
 * passes is the one returned.  Also notes that a modulus is applied
 * to n in the last rule.  Thus its condition holds for 119, 219, 319...</p>
 * <p><pre>
 *   "one: n is 1; few: n mod 10 in 2..4 and n mod 100 not in 12..14"</pre></p>
 * <p>
 * This illustrates conjunction and negation.  The condition for 'few'
 * has two parts, both of which must be met: "n mod 10 in 2..4" and
 * "n mod 100 not in 12..14".  The first part applies a modulus to n
 * before the test as in the previous example.  The second part applies
 * a different modulus and also uses negation, thus it matches all
 * numbers _not_ in 12, 13, 14, 112, 113, 114, 212, 213, 214...</p>
 * <p>
 * Syntax:<pre>
 * rules         = rule (';' rule)*
 * rule          = keyword ':' condition
 * keyword       = <identifier>
 * condition     = and_condition ('or' and_condition)*
 * and_condition = relation ('and' relation)*
 * relation      = is_relation | in_relation | within_relation | 'n' <EOL>
 * is_relation   = expr 'is' ('not')? value
 * in_relation   = expr ('not')? 'in' range
 * within_relation = expr ('not')? 'within' range
 * expr          = 'n' ('mod' value)?
 * value         = digit+
 * digit         = 0|1|2|3|4|5|6|7|8|9
 * range         = value'..'value
 * </pre></p>
 * <p>
 * The difference between 'in' and 'within' is that 'in' only includes
 * integers in the specified range, while 'within' includes all values.</p>
 * @draft ICU 3.8
 * @provisional This API might change or be removed in a future release.
 */
public class PluralRules implements Serializable {
    private static final long serialVersionUID = 1;

    private static final Map ruleMap; // from locale string to PluralRules

    private final RuleList rules;
    private final Set keywords;
    private int repeatLimit; // for equality test

    // Standard keywords.

    /** 
     * Common name for the 'zero' plural form. 
     * @draft ICU 3.8 
     * @provisional This API might change or be removed in a future release.
     */
    public static final String KEYWORD_ZERO = "zero";

    /** 
     * Common name for the 'singular' plural form. 
     * @draft ICU 3.8
     * @provisional This API might change or be removed in a future release.
     */
    public static final String KEYWORD_ONE = "one";

    /**
     * Common name for the 'dual' plural form.
     * @draft ICU 3.8
     * @provisional This API might change or be removed in a future release.
     */
    public static final String KEYWORD_TWO = "two";

    /**
     * Common name for the 'paucal' or other special plural form.
     * @draft ICU 3.8
     * @provisional This API might change or be removed in a future release.
     */
    public static final String KEYWORD_FEW = "few";

    /**
     * Common name for the arabic (11 to 99) plural form.
     * @draft ICU 3.8
     * @provisional This API might change or be removed in a future release.
     */
    public static final String KEYWORD_MANY = "many";

    /**
     * Common name for the default plural form.  This name is returned
     * for values to which no other form in the rule applies.  It 
     * can additionally be assigned rules of its own.
     * @draft ICU 3.8
     * @provisional This API might change or be removed in a future release.
     */
    public static final String KEYWORD_OTHER = "other";

    /**
     * The set of all characters a valid keyword can start with.
     */
    private static final UnicodeSet START_CHARS = 
        new UnicodeSet("[[:ID_Start:][_]]");

    /**
     * The set of all characters a valid keyword can contain after 
     * the first character.
     */
    private static final UnicodeSet CONT_CHARS = 
        new UnicodeSet("[:ID_Continue:]");

    /**
     * The default constraint that is always satisfied.
     */
    private static final Constraint NO_CONSTRAINT = new Constraint() {
        private static final long serialVersionUID = 9163464945387899416L;

        public boolean isFulfilled(double n) {
            return true;
        }
        public String toString() {
            return "n is any";
        }

        public int updateRepeatLimit(int limit) {
            return limit;
        }
      };

    /**
     * The default rule that always returns "other".
     */
    private static final Rule DEFAULT_RULE = new Rule() {
        private static final long serialVersionUID = -5677499073940822149L;

        public String getKeyword() {
            return KEYWORD_OTHER;
        }

        public boolean appliesTo(double n) {
            return true;
        }

        public String toString() {
            return "(" + KEYWORD_OTHER + ")";
        }

        public int updateRepeatLimit(int limit) {
            return limit;
        }
      };


    /**
     * The default rules that accept any number and return 
     * {@link #KEYWORD_OTHER}.
     * @draft ICU 3.8
     * @provisional This API might change or be removed in a future release.
     */
    public static final PluralRules DEFAULT =
        new PluralRules(new RuleChain(DEFAULT_RULE));

    /**
     * Parses a plural rules description and returns a PluralRules.
     * @param description the rule description.
     * @throws ParseException if the description cannot be parsed.
     *    The exception index is typically not set, it will be -1.
     * @draft ICU 3.8
     * @provisional This API might change or be removed in a future release.
     */
    public static PluralRules parseDescription(String description) 
        throws ParseException {

        description = description.trim();
        if (description.length() == 0) {
          return DEFAULT;
        }

        return new PluralRules(parseRuleChain(description));
    }

    /**
     * Creates a PluralRules from a description if it is parsable,
     * otherwise returns null.
     * @param description the rule description.
     * @return the PluralRules
     * @draft ICU 3.8
     * @provisional This API might change or be removed in a future release.
     */
    public static PluralRules createRules(String description) {
        try {
            return parseDescription(description);
        } catch(ParseException e) {
            return null;
        }
    }

    /** 
     * A constraint on a number.
     */
    private interface Constraint extends Serializable {
        /** 
         * Returns true if the number fulfills the constraint.
         * @param n the number to test, >= 0.
         */
        boolean isFulfilled(double n);

        /** 
         * Returns the larger of limit or the limit of this constraint.
         * If the constraint is a simple range test, this is the higher
         * end of the range; if it is a modulo test, this is the modulus.
         *
         * @param limit the target limit
         * @return the new limit
         */
        int updateRepeatLimit(int limit);
    }

    /**
     * A pluralization rule.  .
     */
    private interface Rule extends Serializable {
        /** Returns the keyword that names this rule. */
        String getKeyword();
        /** Returns true if the rule applies to the number. */
        boolean appliesTo(double n);
        /** Returns the larger of limit and this rule's limit. */
        int updateRepeatLimit(int limit);
    }

    /**
     * A list of rules to apply in order.
     */
    private interface RuleList extends Serializable {
        /** Returns the keyword of the first rule that applies to the number. */
        String select(double n);

        /** Returns the set of defined keywords. */
        Set getKeywords();

        /** Return the value at which this rulelist starts repeating. */
        int getRepeatLimit();
    }

    // default data
    static {
        String[] ruledata = {
          "other: n/ja,ko,tr,vi",  // not strictly necessary, default for all
          "zero: n is 0; one: n is 1; two: n is 2; few: n in 3..10; " +
          "many: n in 11..99/ar",
            "one: n is 1/da,de,el,en,eo,es,et,fi,fo,he,hu,it,nb,nl,nn,no,pt,sv",
            "one: n in 0..1/fr,pt_BR",
            "zero: n is 0; one: n mod 10 is 1 and n mod 100 is not 11/lv",
            "one: n is 1; two: n is 2/ga",
            "zero: n is 0; one: n is 1; zero: n mod 100 in 1..19/ro",
            "other: n mod 100 in 11..19; one: n mod 10 is 1; " + 
                "few: n mod 10 in 2..9/lt",
            "one: n mod 10 is 1 and n mod 100 is not 11; " +
                "few: n mod 10 in 2..4 " +
                "and n mod 100 not in 12..14/hr,ru,sr,uk",
            "one: n is 1; few: n in 2..4/cs,sk",
            "one: n is 1; few: n mod 10 in 2..4 and n mod 100 not in 12..14/pl",
            "one: n mod 100 is 1; two: n mod 100 is 2; " +
                "few: n mod 100 in 3..4/sl",
        };

        HashMap map = new HashMap();
        for (int i = 0; i < ruledata.length; ++i) {
            String[] data = Utility.split(ruledata[i], '/');
            try {
              PluralRules pluralRules = parseDescription(data[0]);
              String[] locales = Utility.split(data[1], ',');
              for (int j = 0; j < locales.length; ++j) {
                map.put(locales[j].trim(), pluralRules);
              }
            } catch (Exception e) {
              System.err.println("PluralRules init failure, " + 
                                 e.getMessage() + " at line " + i);
            }
        }
           
        ruleMap = map;
    }

    /**
     * syntax:
     * condition :     or_condition
     *                 and_condition
     * or_condition :  and_condition 'or' condition
     * and_condition : relation
     *                 relation 'and' relation
     * relation :      is_relation
     *                 in_relation
     *                 within_relation
     *                 'n' EOL
     * is_relation :   expr 'is' value
     *                 expr 'is' 'not' value
     * in_relation :   expr 'in' range
     *                 expr 'not' 'in' range
     * within_relation : expr 'within' range
     *                   expr 'not' 'within' range
     * expr :          'n'
     *                 'n' 'mod' value
     * value :         digit+
     * digit :         0|1|2|3|4|5|6|7|8|9
     * range :         value'..'value
     */
    private static Constraint parseConstraint(String description) 
        throws ParseException {

        description = description.trim().toLowerCase(Locale.ENGLISH);

        Constraint result = null;
        String[] or_together = Utility.splitString(description, "or");
        for (int i = 0; i < or_together.length; ++i) {
            Constraint andConstraint = null;
            String[] and_together = Utility.splitString(or_together[i], "and");
            for (int j = 0; j < and_together.length; ++j) {
                Constraint newConstraint = NO_CONSTRAINT;

                String condition = and_together[j].trim();
                String[] tokens = Utility.splitWhitespace(condition);

                int mod = 0;
                boolean inRange = true;
                boolean integersOnly = true;
                long lowBound = -1;
                long highBound = -1;

                boolean isRange = false;

                int x = 0;
                String t = tokens[x++];
                if (!"n".equals(t)) {
                    throw unexpected(t, condition);
                }
                if (x < tokens.length) {
                    t = tokens[x++];
                    if ("mod".equals(t)) {
                        mod = Integer.parseInt(tokens[x++]);
                        t = nextToken(tokens, x++, condition);
                    }
                    if ("is".equals(t)) {
                        t = nextToken(tokens, x++, condition);
                        if ("not".equals(t)) {
                            inRange = false;
                            t = nextToken(tokens, x++, condition);
                        }
                    } else {
                        isRange = true;
                        if ("not".equals(t)) {
                            inRange = false;
                            t = nextToken(tokens, x++, condition);
                        }
                        if ("in".equals(t)) {
                            t = nextToken(tokens, x++, condition);
                        } else if ("within".equals(t)) {
                            integersOnly = false;
                            t = nextToken(tokens, x++, condition);
                        } else {
                            throw unexpected(t, condition);
                        }
                    }

                    if (isRange) {
                        String[] pair = Utility.splitString(t, "..");
                        if (pair.length == 2) {
                            lowBound = Long.parseLong(pair[0]);
                            highBound = Long.parseLong(pair[1]);
                        } else {
                            throw unexpected(t, condition);
                        }
                    } else {
                        lowBound = highBound = Long.parseLong(t);
                    }

                    if (x != tokens.length) {
                        throw unexpected(tokens[x], condition);
                    }

                    newConstraint = 
                        new RangeConstraint(mod, inRange, integersOnly, lowBound, highBound);
                }

                if (andConstraint == null) {
                    andConstraint = newConstraint;
                } else {
                    andConstraint = new AndConstraint(andConstraint, 
                                                      newConstraint);
                }
            }

            if (result == null) {
                result = andConstraint;
            } else {
                result = new OrConstraint(result, andConstraint);
            }
        }

        return result;
    }

    /** Returns a parse exception wrapping the token and context strings. */
    private static ParseException unexpected(String token, String context) {
        return new ParseException("unexpected token '" + token +
                                  "' in '" + context + "'", -1);
    }

    /** 
     * Returns the token at x if available, else throws a parse exception.
     */
    private static String nextToken(String[] tokens, int x, String context) 
        throws ParseException {
        if (x < tokens.length) {
            return tokens[x];
        }
        throw new ParseException("missing token at end of '" + context + "'", -1);
    }

    /**
     * Syntax:
     * rule : keyword ':' condition
     * keyword: <identifier>
     */
    private static Rule parseRule(String description) throws ParseException {
        int x = description.indexOf(':');
        if (x == -1) {
            throw new ParseException("missing ':' in rule description '" +
                                     description + "'", 0);
        }

        String keyword = description.substring(0, x).trim();
        if (!isValidKeyword(keyword)) {
          throw new ParseException("keyword '" + keyword +
                                   " is not valid", 0);
        }

        description = description.substring(x+1).trim();
        if (description.length() == 0) {
          throw new ParseException("missing constraint in '" + 
                                   description + "'", x+1);
        }
        Constraint constraint = parseConstraint(description);
        Rule rule = new ConstrainedRule(keyword, constraint);
        return rule;
    }

    /**
     * Syntax:
     * rules : rule
     *         rule ';' rules
     */
    private static RuleChain parseRuleChain(String description) 
        throws ParseException {

        RuleChain rc = null;
        String[] rules = Utility.split(description, ';');
        for (int i = 0; i < rules.length; ++i) {
            Rule r = parseRule(rules[i].trim());
            if (rc == null) {
                rc = new RuleChain(r);
            } else {
                rc = rc.addRule(r);
            }
        }
        return rc;
    }

    /** 
     * An implementation of Constraint representing a modulus, 
     * a range of values, and include/exclude. Provides lots of
     * convenience factory methods.
     */
    private static class RangeConstraint implements Constraint, Serializable {
        private static final long serialVersionUID = 1;
      
        private int mod;
        private boolean inRange;
        private boolean integersOnly;
        private long lowerBound;
        private long upperBound;

        public boolean isFulfilled(double n) {
            if (integersOnly && (n - (long)n) != 0.0) {
                return !inRange;
            }
            if (mod != 0) {
                n = n % mod;    // java % handles double numerator the way we want
            }
            return inRange == (n >= lowerBound && n <= upperBound);
        }

        RangeConstraint(int mod, boolean inRange, boolean integersOnly,
                        long lowerBound, long upperBound) {
            this.mod = mod;
            this.inRange = inRange;
            this.integersOnly = integersOnly;
            this.lowerBound = lowerBound;
            this.upperBound = upperBound;
        }

        public int updateRepeatLimit(int limit) {
          int mylimit = mod == 0 ? (int)upperBound : mod;
          return Math.max(mylimit, limit);
        }

        public String toString() {
            return "[mod: " + mod + " inRange: " + inRange +
                " integersOnly: " + integersOnly +
                " low: " + lowerBound + " high: " + upperBound + "]";
        }
    }

    /** Convenience base class for and/or constraints. */
    private static abstract class BinaryConstraint implements Constraint, 
                                                   Serializable {
        private static final long serialVersionUID = 1;
        protected final Constraint a;
        protected final Constraint b;
        private final String conjunction;

        protected BinaryConstraint(Constraint a, Constraint b, String c) {
            this.a = a;
            this.b = b;
            this.conjunction = c;
        }

        public int updateRepeatLimit(int limit) {
            return a.updateRepeatLimit(b.updateRepeatLimit(limit));
        }

        public String toString() {
            return a.toString() + conjunction + b.toString();
        }
    }
      
    /** A constraint representing the logical and of two constraints. */
    private static class AndConstraint extends BinaryConstraint {
        private static final long serialVersionUID = 7766999779862263523L;

        AndConstraint(Constraint a, Constraint b) {
            super(a, b, " && ");
        }

        public boolean isFulfilled(double n) {
            return a.isFulfilled(n) && b.isFulfilled(n);
        }
    }

    /** A constraint representing the logical or of two constraints. */
    private static class OrConstraint extends BinaryConstraint {
        private static final long serialVersionUID = 1405488568664762222L;

        OrConstraint(Constraint a, Constraint b) {
            super(a, b, " || ");
        }

        public boolean isFulfilled(double n) {
            return a.isFulfilled(n) || b.isFulfilled(n);
        }
    }

    /** 
     * Implementation of Rule that uses a constraint.
     * Provides 'and' and 'or' to combine constraints.  Immutable.
     */
    private static class ConstrainedRule implements Rule, Serializable {
        private static final long serialVersionUID = 1;
        private final String keyword;
        private final Constraint constraint;

        public ConstrainedRule(String keyword, Constraint constraint) {
            this.keyword = keyword;
            this.constraint = constraint;
        }

        public Rule and(Constraint c) {
            return new ConstrainedRule(keyword, new AndConstraint(constraint, c));
        }

        public Rule or(Constraint c) {
            return new ConstrainedRule(keyword, new OrConstraint(constraint, c));
        }

        public String getKeyword() {
            return keyword;
        }

        public boolean appliesTo(double n) {
            return constraint.isFulfilled(n);
        }

        public int updateRepeatLimit(int limit) {
            return constraint.updateRepeatLimit(limit);
        }

        public String toString() { 
            return keyword + ": " + constraint;
        }
    }

    /**
     * Implementation of RuleList that is itself a node in a linked list.
     * Immutable, but supports chaining with 'addRule'.
     */
    private static class RuleChain implements RuleList, Serializable {
        private static final long serialVersionUID = 1;
        private final Rule rule;
        private final RuleChain next;

        /** Creates a rule chain with the single rule. */
        public RuleChain(Rule rule) {
            this(rule, null);
        }

        private RuleChain(Rule rule, RuleChain next) {
            this.rule = rule;
            this.next = next;
        }

        public RuleChain addRule(Rule nextRule) {
            return new RuleChain(nextRule, this);
        }

        private Rule selectRule(double n) {
            Rule r = null;
            if (next != null) {
                r = next.selectRule(n);
            }
            if (r == null && rule.appliesTo(n)) {
                r = rule;
            }
            return r;
        }

        public String select(double n) {
            Rule r = selectRule(n);
            if (r == null) {
                return KEYWORD_OTHER;
            }
            return r.getKeyword();
        }

        public Set getKeywords() {
            Set result = new HashSet();
            result.add(KEYWORD_OTHER);
            RuleChain rc = this;
            while (rc != null) {
                result.add(rc.rule.getKeyword());
                rc = rc.next;
            }
            return result;
        }

        public int getRepeatLimit() {
          int result = 0;
          RuleChain rc = this;
          while (rc != null) {
            result = rc.rule.updateRepeatLimit(result);
            rc = rc.next;
          }
          return result;
        }

        public String toString() {
            String s = rule.toString();
            if (next != null) {
                s = next.toString() + "; " + s;
            }
            return s;
        }
    }

    // -------------------------------------------------------------------------
    // Static class methods.
    // -------------------------------------------------------------------------

    /**
     * Provides access to the predefined <code>PluralRules</code> for a given
     * locale.
     * 
     * @param locale The locale for which a <code>PluralRules</code> object is
     *   returned.
     * @return The predefined <code>PluralRules</code> object for this locale.
     *   If there's no predefined rules for this locale, the rules
     *   for the closest parent in the locale hierarchy that has one will
     *   be returned.  The final fallback always returns the default
     *   rules.
     * @draft ICU 3.8
     * @provisional This API might change or be removed in a future release.
     */
    public static PluralRules forLocale(ULocale locale) {
        PluralRules result = null;
        while (null == (result = (PluralRules) ruleMap.get(locale.getName()))) {
            locale = locale.getFallback();
            if (locale == null) {
              return DEFAULT;
            }
        }
        return result;
    }

    /**
     * Checks whether a token is a valid keyword.
     * 
     * @param token the token to be checked
     * @return true if the token is a valid keyword.
     */
     private static boolean isValidKeyword(String token) {
         if (token.length() > 0 && START_CHARS.contains(token.charAt(0))) {
             for (int i = 1; i < token.length(); ++i) {
                 if (!CONT_CHARS.contains(token.charAt(i))) {
                     return false;
                 }
             }
             return true;
         }
         return false;
     }

    /**
     * Creates a new <code>PluralRules</code> object.  Immutable.
     */
     private PluralRules(RuleList rules) {
         this.rules = rules;
         this.keywords = Collections.unmodifiableSet(rules.getKeywords());
     }

    /**
     * Given a number, returns the keyword of the first rule that applies to
     * the number.
     * 
     * @param number The number for which the rule has to be determined.
     * @return The keyword of the selected rule.
     * @draft ICU 3.8
     * @provisional This API might change or be removed in a future release.
     */
     public String select(double number) {
         return rules.select(number);
     }

    /**
     * Returns a set of all rule keywords used in this <code>PluralRules</code>
     * object.  The rule "other" is always present by default.
     * 
     * @return The set of keywords.
     * @draft ICU 3.8
     * @provisional This API might change or be removed in a future release.
     */
    public Set getKeywords() {
        return keywords;
    }

    /**
     * {@inheritDoc}
     * @draft ICU 3.8
     * @provisional This API might change or be removed in a future release.
     */
    public String toString() {
      return "keywords: " + keywords + " rules: " + rules.toString() + 
          " limit: " + getRepeatLimit();
    }

    /**
     * {@inheritDoc}
     * @draft ICU 3.8
     * @provisional This API might change or be removed in a future release.
     */
    public int hashCode() {
      return keywords.hashCode();
    }

    /**
     * {@inheritDoc}
     * @draft ICU 3.8
     * @provisional This API might change or be removed in a future release.
     */
    public boolean equals(Object rhs) {
        return rhs instanceof PluralRules && equals((PluralRules)rhs);
    }

    /**
     * Return tif rhs is equal to this.
     * @param rhs the PluralRules to compare to.
     * @return true if this and rhs are equal.
     * @draft ICU 3.8
     * @provisional This API might change or be removed in a future release.
     */
    public boolean equals(PluralRules rhs) {
      if (rhs == null) {
        return false;
      }
      if (rhs == this) { 
        return true;
      }
      if (!rhs.getKeywords().equals(keywords)) {
        return false;
      }

      int limit = Math.max(getRepeatLimit(), rhs.getRepeatLimit());
      for (int i = 0; i < limit; ++i) {
        if (!select(i).equals(rhs.select(i))) {
          return false;
        }
      }
      return true;
    }

    private int getRepeatLimit() {
      if (repeatLimit == 0) {
        repeatLimit = rules.getRepeatLimit() + 1;
      }
      return repeatLimit;
    }
}
