/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.calendarcommon2;

import android.text.TextUtils;
import android.text.format.Time;
import android.util.Log;
import android.util.TimeFormatException;

import java.util.Calendar;
import java.util.HashMap;

/**
 * Event recurrence utility functions.
 */
public class EventRecurrence {
    private static String TAG = "EventRecur";

    public static final int SECONDLY = 1;
    public static final int MINUTELY = 2;
    public static final int HOURLY = 3;
    public static final int DAILY = 4;
    public static final int WEEKLY = 5;
    public static final int MONTHLY = 6;
    public static final int YEARLY = 7;

    public static final int SU = 0x00010000;
    public static final int MO = 0x00020000;
    public static final int TU = 0x00040000;
    public static final int WE = 0x00080000;
    public static final int TH = 0x00100000;
    public static final int FR = 0x00200000;
    public static final int SA = 0x00400000;

    public Time      startDate;     // set by setStartDate(), not parse()

    public int       freq;          // SECONDLY, MINUTELY, etc.
    public String    until;
    public int       count;
    public int       interval;
    public int       wkst;          // SU, MO, TU, etc.

    /* lists with zero entries may be null references */
    public int[]     bysecond;
    public int       bysecondCount;
    public int[]     byminute;
    public int       byminuteCount;
    public int[]     byhour;
    public int       byhourCount;
    public int[]     byday;
    public int[]     bydayNum;
    public int       bydayCount;
    public int[]     bymonthday;
    public int       bymonthdayCount;
    public int[]     byyearday;
    public int       byyeardayCount;
    public int[]     byweekno;
    public int       byweeknoCount;
    public int[]     bymonth;
    public int       bymonthCount;
    public int[]     bysetpos;
    public int       bysetposCount;

    /** maps a part string to a parser object */
    private static HashMap<String,PartParser> sParsePartMap;
    static {
        sParsePartMap = new HashMap<String,PartParser>();
        sParsePartMap.put("FREQ", new ParseFreq());
        sParsePartMap.put("UNTIL", new ParseUntil());
        sParsePartMap.put("COUNT", new ParseCount());
        sParsePartMap.put("INTERVAL", new ParseInterval());
        sParsePartMap.put("BYSECOND", new ParseBySecond());
        sParsePartMap.put("BYMINUTE", new ParseByMinute());
        sParsePartMap.put("BYHOUR", new ParseByHour());
        sParsePartMap.put("BYDAY", new ParseByDay());
        sParsePartMap.put("BYMONTHDAY", new ParseByMonthDay());
        sParsePartMap.put("BYYEARDAY", new ParseByYearDay());
        sParsePartMap.put("BYWEEKNO", new ParseByWeekNo());
        sParsePartMap.put("BYMONTH", new ParseByMonth());
        sParsePartMap.put("BYSETPOS", new ParseBySetPos());
        sParsePartMap.put("WKST", new ParseWkst());
    }

    /* values for bit vector that keeps track of what we have already seen */
    private static final int PARSED_FREQ = 1 << 0;
    private static final int PARSED_UNTIL = 1 << 1;
    private static final int PARSED_COUNT = 1 << 2;
    private static final int PARSED_INTERVAL = 1 << 3;
    private static final int PARSED_BYSECOND = 1 << 4;
    private static final int PARSED_BYMINUTE = 1 << 5;
    private static final int PARSED_BYHOUR = 1 << 6;
    private static final int PARSED_BYDAY = 1 << 7;
    private static final int PARSED_BYMONTHDAY = 1 << 8;
    private static final int PARSED_BYYEARDAY = 1 << 9;
    private static final int PARSED_BYWEEKNO = 1 << 10;
    private static final int PARSED_BYMONTH = 1 << 11;
    private static final int PARSED_BYSETPOS = 1 << 12;
    private static final int PARSED_WKST = 1 << 13;

    /** maps a FREQ value to an integer constant */
    private static final HashMap<String,Integer> sParseFreqMap = new HashMap<String,Integer>();
    static {
        sParseFreqMap.put("SECONDLY", SECONDLY);
        sParseFreqMap.put("MINUTELY", MINUTELY);
        sParseFreqMap.put("HOURLY", HOURLY);
        sParseFreqMap.put("DAILY", DAILY);
        sParseFreqMap.put("WEEKLY", WEEKLY);
        sParseFreqMap.put("MONTHLY", MONTHLY);
        sParseFreqMap.put("YEARLY", YEARLY);
    }

    /** maps a two-character weekday string to an integer constant */
    private static final HashMap<String,Integer> sParseWeekdayMap = new HashMap<String,Integer>();
    static {
        sParseWeekdayMap.put("SU", SU);
        sParseWeekdayMap.put("MO", MO);
        sParseWeekdayMap.put("TU", TU);
        sParseWeekdayMap.put("WE", WE);
        sParseWeekdayMap.put("TH", TH);
        sParseWeekdayMap.put("FR", FR);
        sParseWeekdayMap.put("SA", SA);
    }

    /** If set, allow lower-case recurrence rule strings.  Minor performance impact. */
    private static final boolean ALLOW_LOWER_CASE = true;

    /** If set, validate the value of UNTIL parts.  Minor performance impact. */
    private static final boolean VALIDATE_UNTIL = false;

    /** If set, require that only one of {UNTIL,COUNT} is present.  Breaks compat w/ old parser. */
    private static final boolean ONLY_ONE_UNTIL_COUNT = false;


    /**
     * Thrown when a recurrence string provided can not be parsed according
     * to RFC2445.
     */
    public static class InvalidFormatException extends RuntimeException {
        InvalidFormatException(String s) {
            super(s);
        }
    }


    public void setStartDate(Time date) {
        startDate = date;
    }

    /**
     * Converts one of the Calendar.SUNDAY constants to the SU, MO, etc.
     * constants.  btw, I think we should switch to those here too, to
     * get rid of this function, if possible.
     */
    public static int calendarDay2Day(int day)
    {
        switch (day)
        {
            case Calendar.SUNDAY:
                return SU;
            case Calendar.MONDAY:
                return MO;
            case Calendar.TUESDAY:
                return TU;
            case Calendar.WEDNESDAY:
                return WE;
            case Calendar.THURSDAY:
                return TH;
            case Calendar.FRIDAY:
                return FR;
            case Calendar.SATURDAY:
                return SA;
            default:
                throw new RuntimeException("bad day of week: " + day);
        }
    }

    public static int timeDay2Day(int day)
    {
        switch (day)
        {
            case Time.SUNDAY:
                return SU;
            case Time.MONDAY:
                return MO;
            case Time.TUESDAY:
                return TU;
            case Time.WEDNESDAY:
                return WE;
            case Time.THURSDAY:
                return TH;
            case Time.FRIDAY:
                return FR;
            case Time.SATURDAY:
                return SA;
            default:
                throw new RuntimeException("bad day of week: " + day);
        }
    }
    public static int day2TimeDay(int day)
    {
        switch (day)
        {
            case SU:
                return Time.SUNDAY;
            case MO:
                return Time.MONDAY;
            case TU:
                return Time.TUESDAY;
            case WE:
                return Time.WEDNESDAY;
            case TH:
                return Time.THURSDAY;
            case FR:
                return Time.FRIDAY;
            case SA:
                return Time.SATURDAY;
            default:
                throw new RuntimeException("bad day of week: " + day);
        }
    }

    /**
     * Converts one of the SU, MO, etc. constants to the Calendar.SUNDAY
     * constants.  btw, I think we should switch to those here too, to
     * get rid of this function, if possible.
     */
    public static int day2CalendarDay(int day)
    {
        switch (day)
        {
            case SU:
                return Calendar.SUNDAY;
            case MO:
                return Calendar.MONDAY;
            case TU:
                return Calendar.TUESDAY;
            case WE:
                return Calendar.WEDNESDAY;
            case TH:
                return Calendar.THURSDAY;
            case FR:
                return Calendar.FRIDAY;
            case SA:
                return Calendar.SATURDAY;
            default:
                throw new RuntimeException("bad day of week: " + day);
        }
    }

    /**
     * Converts one of the internal day constants (SU, MO, etc.) to the
     * two-letter string representing that constant.
     *
     * @param day one the internal constants SU, MO, etc.
     * @return the two-letter string for the day ("SU", "MO", etc.)
     *
     * @throws IllegalArgumentException Thrown if the day argument is not one of
     * the defined day constants.
     */
    private static String day2String(int day) {
        switch (day) {
        case SU:
            return "SU";
        case MO:
            return "MO";
        case TU:
            return "TU";
        case WE:
            return "WE";
        case TH:
            return "TH";
        case FR:
            return "FR";
        case SA:
            return "SA";
        default:
            throw new IllegalArgumentException("bad day argument: " + day);
        }
    }

    private static void appendNumbers(StringBuilder s, String label,
                                        int count, int[] values)
    {
        if (count > 0) {
            s.append(label);
            count--;
            for (int i=0; i<count; i++) {
                s.append(values[i]);
                s.append(",");
            }
            s.append(values[count]);
        }
    }

    private void appendByDay(StringBuilder s, int i)
    {
        int n = this.bydayNum[i];
        if (n != 0) {
            s.append(n);
        }

        String str = day2String(this.byday[i]);
        s.append(str);
    }

    @Override
    public String toString()
    {
        StringBuilder s = new StringBuilder();

        s.append("FREQ=");
        switch (this.freq)
        {
            case SECONDLY:
                s.append("SECONDLY");
                break;
            case MINUTELY:
                s.append("MINUTELY");
                break;
            case HOURLY:
                s.append("HOURLY");
                break;
            case DAILY:
                s.append("DAILY");
                break;
            case WEEKLY:
                s.append("WEEKLY");
                break;
            case MONTHLY:
                s.append("MONTHLY");
                break;
            case YEARLY:
                s.append("YEARLY");
                break;
        }

        if (!TextUtils.isEmpty(this.until)) {
            s.append(";UNTIL=");
            s.append(until);
        }

        if (this.count != 0) {
            s.append(";COUNT=");
            s.append(this.count);
        }

        if (this.interval != 0) {
            s.append(";INTERVAL=");
            s.append(this.interval);
        }

        if (this.wkst != 0) {
            s.append(";WKST=");
            s.append(day2String(this.wkst));
        }

        appendNumbers(s, ";BYSECOND=", this.bysecondCount, this.bysecond);
        appendNumbers(s, ";BYMINUTE=", this.byminuteCount, this.byminute);
        appendNumbers(s, ";BYSECOND=", this.byhourCount, this.byhour);

        // day
        int count = this.bydayCount;
        if (count > 0) {
            s.append(";BYDAY=");
            count--;
            for (int i=0; i<count; i++) {
                appendByDay(s, i);
                s.append(",");
            }
            appendByDay(s, count);
        }

        appendNumbers(s, ";BYMONTHDAY=", this.bymonthdayCount, this.bymonthday);
        appendNumbers(s, ";BYYEARDAY=", this.byyeardayCount, this.byyearday);
        appendNumbers(s, ";BYWEEKNO=", this.byweeknoCount, this.byweekno);
        appendNumbers(s, ";BYMONTH=", this.bymonthCount, this.bymonth);
        appendNumbers(s, ";BYSETPOS=", this.bysetposCount, this.bysetpos);

        return s.toString();
    }

    public boolean repeatsOnEveryWeekDay() {
        if (this.freq != WEEKLY) {
            return false;
        }

        int count = this.bydayCount;
        if (count != 5) {
            return false;
        }

        for (int i = 0 ; i < count ; i++) {
            int day = byday[i];
            if (day == SU || day == SA) {
                return false;
            }
        }

        return true;
    }

    /**
     * Determines whether this rule specifies a simple monthly rule by weekday, such as
     * "FREQ=MONTHLY;BYDAY=3TU" (the 3rd Tuesday of every month).
     * <p>
     * Negative days, e.g. "FREQ=MONTHLY;BYDAY=-1TU" (the last Tuesday of every month),
     * will cause "false" to be returned.
     * <p>
     * Rules that fire every week, such as "FREQ=MONTHLY;BYDAY=TU" (every Tuesday of every
     * month) will cause "false" to be returned.  (Note these are usually expressed as
     * WEEKLY rules, and hence are uncommon.)
     *
     * @return true if this rule is of the appropriate form
     */
    public boolean repeatsMonthlyOnDayCount() {
        if (this.freq != MONTHLY) {
            return false;
        }

        if (bydayCount != 1 || bymonthdayCount != 0) {
            return false;
        }

        if (bydayNum[0] <= 0) {
            return false;
        }

        return true;
    }

    /**
     * Determines whether two integer arrays contain identical elements.
     * <p>
     * The native implementation over-allocated the arrays (and may have stuff left over from
     * a previous run), so we can't just check the arrays -- the separately-maintained count
     * field also matters.  We assume that a null array will have a count of zero, and that the
     * array can hold as many elements as the associated count indicates.
     * <p>
     * TODO: replace this with Arrays.equals() when the old parser goes away.
     */
    private static boolean arraysEqual(int[] array1, int count1, int[] array2, int count2) {
        if (count1 != count2) {
            return false;
        }

        for (int i = 0; i < count1; i++) {
            if (array1[i] != array2[i])
                return false;
        }

        return true;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (!(obj instanceof EventRecurrence)) {
            return false;
        }

        EventRecurrence er = (EventRecurrence) obj;
        return  (startDate == null ?
                        er.startDate == null : Time.compare(startDate, er.startDate) == 0) &&
                freq == er.freq &&
                (until == null ? er.until == null : until.equals(er.until)) &&
                count == er.count &&
                interval == er.interval &&
                wkst == er.wkst &&
                arraysEqual(bysecond, bysecondCount, er.bysecond, er.bysecondCount) &&
                arraysEqual(byminute, byminuteCount, er.byminute, er.byminuteCount) &&
                arraysEqual(byhour, byhourCount, er.byhour, er.byhourCount) &&
                arraysEqual(byday, bydayCount, er.byday, er.bydayCount) &&
                arraysEqual(bydayNum, bydayCount, er.bydayNum, er.bydayCount) &&
                arraysEqual(bymonthday, bymonthdayCount, er.bymonthday, er.bymonthdayCount) &&
                arraysEqual(byyearday, byyeardayCount, er.byyearday, er.byyeardayCount) &&
                arraysEqual(byweekno, byweeknoCount, er.byweekno, er.byweeknoCount) &&
                arraysEqual(bymonth, bymonthCount, er.bymonth, er.bymonthCount) &&
                arraysEqual(bysetpos, bysetposCount, er.bysetpos, er.bysetposCount);
    }

    @Override public int hashCode() {
        // We overrode equals, so we must override hashCode().  Nobody seems to need this though.
        throw new UnsupportedOperationException();
    }

    /**
     * Resets parser-modified fields to their initial state.  Does not alter startDate.
     * <p>
     * The original parser always set all of the "count" fields, "wkst", and "until",
     * essentially allowing the same object to be used multiple times by calling parse().
     * It's unclear whether this behavior was intentional.  For now, be paranoid and
     * preserve the existing behavior by resetting the fields.
     * <p>
     * We don't need to touch the integer arrays; they will either be ignored or
     * overwritten.  The "startDate" field is not set by the parser, so we ignore it here.
     */
    private void resetFields() {
        until = null;
        freq = count = interval = bysecondCount = byminuteCount = byhourCount =
            bydayCount = bymonthdayCount = byyeardayCount = byweeknoCount = bymonthCount =
            bysetposCount = 0;
    }

    /**
     * Parses an rfc2445 recurrence rule string into its component pieces.  Attempting to parse
     * malformed input will result in an EventRecurrence.InvalidFormatException.
     *
     * @param recur The recurrence rule to parse (in un-folded form).
     */
    public void parse(String recur) {
        /*
         * From RFC 2445 section 4.3.10:
         *
         * recur = "FREQ"=freq *(
         *       ; either UNTIL or COUNT may appear in a 'recur',
         *       ; but UNTIL and COUNT MUST NOT occur in the same 'recur'
         *
         *       ( ";" "UNTIL" "=" enddate ) /
         *       ( ";" "COUNT" "=" 1*DIGIT ) /
         *
         *       ; the rest of these keywords are optional,
         *       ; but MUST NOT occur more than once
         *
         *       ( ";" "INTERVAL" "=" 1*DIGIT )          /
         *       ( ";" "BYSECOND" "=" byseclist )        /
         *       ( ";" "BYMINUTE" "=" byminlist )        /
         *       ( ";" "BYHOUR" "=" byhrlist )           /
         *       ( ";" "BYDAY" "=" bywdaylist )          /
         *       ( ";" "BYMONTHDAY" "=" bymodaylist )    /
         *       ( ";" "BYYEARDAY" "=" byyrdaylist )     /
         *       ( ";" "BYWEEKNO" "=" bywknolist )       /
         *       ( ";" "BYMONTH" "=" bymolist )          /
         *       ( ";" "BYSETPOS" "=" bysplist )         /
         *       ( ";" "WKST" "=" weekday )              /
         *       ( ";" x-name "=" text )
         *       )
         *
         *  The rule parts are not ordered in any particular sequence.
         *
         * Examples:
         *   FREQ=MONTHLY;INTERVAL=2;COUNT=10;BYDAY=1SU,-1SU
         *   FREQ=YEARLY;INTERVAL=4;BYMONTH=11;BYDAY=TU;BYMONTHDAY=2,3,4,5,6,7,8
         *
         * Strategy:
         * (1) Split the string at ';' boundaries to get an array of rule "parts".
         * (2) For each part, find substrings for left/right sides of '=' (name/value).
         * (3) Call a <name>-specific parsing function to parse the <value> into an
         *     output field.
         *
         * By keeping track of which names we've seen in a bit vector, we can verify the
         * constraints indicated above (FREQ appears first, none of them appear more than once --
         * though x-[name] would require special treatment), and we have either UNTIL or COUNT
         * but not both.
         *
         * In general, RFC 2445 property names (e.g. "FREQ") and enumerations ("TU") must
         * be handled in a case-insensitive fashion, but case may be significant for other
         * properties.  We don't have any case-sensitive values in RRULE, except possibly
         * for the custom "X-" properties, but we ignore those anyway.  Thus, we can trivially
         * convert the entire string to upper case and then use simple comparisons.
         *
         * Differences from previous version:
         * - allows lower-case property and enumeration values [optional]
         * - enforces that FREQ appears first
         * - enforces that only one of UNTIL and COUNT may be specified
         * - allows (but ignores) X-* parts
         * - improved validation on various values (e.g. UNTIL timestamps)
         * - error messages are more specific
         *
         * TODO: enforce additional constraints listed in RFC 5545, notably the "N/A" entries
         * in section 3.3.10.  For example, if FREQ=WEEKLY, we should reject a rule that
         * includes a BYMONTHDAY part.
         */

        /* TODO: replace with "if (freq != 0) throw" if nothing requires this */
        resetFields();

        int parseFlags = 0;
        String[] parts;
        if (ALLOW_LOWER_CASE) {
            parts = recur.toUpperCase().split(";");
        } else {
            parts = recur.split(";");
        }
        for (String part : parts) {
            // allow empty part (e.g., double semicolon ";;")
            if (TextUtils.isEmpty(part)) {
                continue;
            }
            int equalIndex = part.indexOf('=');
            if (equalIndex <= 0) {
                /* no '=' or no LHS */
                throw new InvalidFormatException("Missing LHS in " + part);
            }

            String lhs = part.substring(0, equalIndex);
            String rhs = part.substring(equalIndex + 1);
            if (rhs.length() == 0) {
                throw new InvalidFormatException("Missing RHS in " + part);
            }

            /*
             * In lieu of a "switch" statement that allows string arguments, we use a
             * map from strings to parsing functions.
             */
            PartParser parser = sParsePartMap.get(lhs);
            if (parser == null) {
                if (lhs.startsWith("X-")) {
                    //Log.d(TAG, "Ignoring custom part " + lhs);
                    continue;
                }
                throw new InvalidFormatException("Couldn't find parser for " + lhs);
            } else {
                int flag = parser.parsePart(rhs, this);
                if ((parseFlags & flag) != 0) {
                    throw new InvalidFormatException("Part " + lhs + " was specified twice");
                }
                parseFlags |= flag;
            }
        }

        // If not specified, week starts on Monday.
        if ((parseFlags & PARSED_WKST) == 0) {
            wkst = MO;
        }

        // FREQ is mandatory.
        if ((parseFlags & PARSED_FREQ) == 0) {
            throw new InvalidFormatException("Must specify a FREQ value");
        }

        // Can't have both UNTIL and COUNT.
        if ((parseFlags & (PARSED_UNTIL | PARSED_COUNT)) == (PARSED_UNTIL | PARSED_COUNT)) {
            if (ONLY_ONE_UNTIL_COUNT) {
                throw new InvalidFormatException("Must not specify both UNTIL and COUNT: " + recur);
            } else {
                Log.w(TAG, "Warning: rrule has both UNTIL and COUNT: " + recur);
            }
        }
    }

    /**
     * Base class for the RRULE part parsers.
     */
    abstract static class PartParser {
        /**
         * Parses a single part.
         *
         * @param value The right-hand-side of the part.
         * @param er The EventRecurrence into which the result is stored.
         * @return A bit value indicating which part was parsed.
         */
        public abstract int parsePart(String value, EventRecurrence er);

        /**
         * Parses an integer, with range-checking.
         *
         * @param str The string to parse.
         * @param minVal Minimum allowed value.
         * @param maxVal Maximum allowed value.
         * @param allowZero Is 0 allowed?
         * @return The parsed value.
         */
        public static int parseIntRange(String str, int minVal, int maxVal, boolean allowZero) {
            try {
                if (str.charAt(0) == '+') {
                    // Integer.parseInt does not allow a leading '+', so skip it manually.
                    str = str.substring(1);
                }
                int val = Integer.parseInt(str);
                if (val < minVal || val > maxVal || (val == 0 && !allowZero)) {
                    throw new InvalidFormatException("Integer value out of range: " + str);
                }
                return val;
            } catch (NumberFormatException nfe) {
                throw new InvalidFormatException("Invalid integer value: " + str);
            }
        }

        /**
         * Parses a comma-separated list of integers, with range-checking.
         *
         * @param listStr The string to parse.
         * @param minVal Minimum allowed value.
         * @param maxVal Maximum allowed value.
         * @param allowZero Is 0 allowed?
         * @return A new array with values, sized to hold the exact number of elements.
         */
        public static int[] parseNumberList(String listStr, int minVal, int maxVal,
                boolean allowZero) {
            int[] values;

            if (listStr.indexOf(",") < 0) {
                // Common case: only one entry, skip split() overhead.
                values = new int[1];
                values[0] = parseIntRange(listStr, minVal, maxVal, allowZero);
            } else {
                String[] valueStrs = listStr.split(",");
                int len = valueStrs.length;
                values = new int[len];
                for (int i = 0; i < len; i++) {
                    values[i] = parseIntRange(valueStrs[i], minVal, maxVal, allowZero);
                }
            }
            return values;
        }
   }

    /** parses FREQ={SECONDLY,MINUTELY,...} */
    private static class ParseFreq extends PartParser {
        @Override public int parsePart(String value, EventRecurrence er) {
            Integer freq = sParseFreqMap.get(value);
            if (freq == null) {
                throw new InvalidFormatException("Invalid FREQ value: " + value);
            }
            er.freq = freq;
            return PARSED_FREQ;
        }
    }
    /** parses UNTIL=enddate, e.g. "19970829T021400" */
    private static class ParseUntil extends PartParser {
        @Override public int parsePart(String value, EventRecurrence er) {
            if (VALIDATE_UNTIL) {
                try {
                    // Parse the time to validate it.  The result isn't retained.
                    Time until = new Time();
                    until.parse(value);
                } catch (TimeFormatException tfe) {
                    throw new InvalidFormatException("Invalid UNTIL value: " + value);
                }
            }
            er.until = value;
            return PARSED_UNTIL;
        }
    }
    /** parses COUNT=[non-negative-integer] */
    private static class ParseCount extends PartParser {
        @Override public int parsePart(String value, EventRecurrence er) {
            er.count = parseIntRange(value, Integer.MIN_VALUE, Integer.MAX_VALUE, true);
            if (er.count < 0) {
                Log.d(TAG, "Invalid Count. Forcing COUNT to 1 from " + value);
                er.count = 1; // invalid count. assume one time recurrence.
            }
            return PARSED_COUNT;
        }
    }
    /** parses INTERVAL=[non-negative-integer] */
    private static class ParseInterval extends PartParser {
        @Override public int parsePart(String value, EventRecurrence er) {
            er.interval = parseIntRange(value, Integer.MIN_VALUE, Integer.MAX_VALUE, true);
            if (er.interval < 1) {
                Log.d(TAG, "Invalid Interval. Forcing INTERVAL to 1 from " + value);
                er.interval = 1;
            }
            return PARSED_INTERVAL;
        }
    }
    /** parses BYSECOND=byseclist */
    private static class ParseBySecond extends PartParser {
        @Override public int parsePart(String value, EventRecurrence er) {
            int[] bysecond = parseNumberList(value, 0, 59, true);
            er.bysecond = bysecond;
            er.bysecondCount = bysecond.length;
            return PARSED_BYSECOND;
        }
    }
    /** parses BYMINUTE=byminlist */
    private static class ParseByMinute extends PartParser {
        @Override public int parsePart(String value, EventRecurrence er) {
            int[] byminute = parseNumberList(value, 0, 59, true);
            er.byminute = byminute;
            er.byminuteCount = byminute.length;
            return PARSED_BYMINUTE;
        }
    }
    /** parses BYHOUR=byhrlist */
    private static class ParseByHour extends PartParser {
        @Override public int parsePart(String value, EventRecurrence er) {
            int[] byhour = parseNumberList(value, 0, 23, true);
            er.byhour = byhour;
            er.byhourCount = byhour.length;
            return PARSED_BYHOUR;
        }
    }
    /** parses BYDAY=bywdaylist, e.g. "1SU,-1SU" */
    private static class ParseByDay extends PartParser {
        @Override public int parsePart(String value, EventRecurrence er) {
            int[] byday;
            int[] bydayNum;
            int bydayCount;

            if (value.indexOf(",") < 0) {
                /* only one entry, skip split() overhead */
                bydayCount = 1;
                byday = new int[1];
                bydayNum = new int[1];
                parseWday(value, byday, bydayNum, 0);
            } else {
                String[] wdays = value.split(",");
                int len = wdays.length;
                bydayCount = len;
                byday = new int[len];
                bydayNum = new int[len];
                for (int i = 0; i < len; i++) {
                    parseWday(wdays[i], byday, bydayNum, i);
                }
            }
            er.byday = byday;
            er.bydayNum = bydayNum;
            er.bydayCount = bydayCount;
            return PARSED_BYDAY;
        }

        /** parses [int]weekday, putting the pieces into parallel array entries */
        private static void parseWday(String str, int[] byday, int[] bydayNum, int index) {
            int wdayStrStart = str.length() - 2;
            String wdayStr;

            if (wdayStrStart > 0) {
                /* number is included; parse it out and advance to weekday */
                String numPart = str.substring(0, wdayStrStart);
                int num = parseIntRange(numPart, -53, 53, false);
                bydayNum[index] = num;
                wdayStr = str.substring(wdayStrStart);
            } else {
                /* just the weekday string */
                wdayStr = str;
            }
            Integer wday = sParseWeekdayMap.get(wdayStr);
            if (wday == null) {
                throw new InvalidFormatException("Invalid BYDAY value: " + str);
            }
            byday[index] = wday;
        }
    }
    /** parses BYMONTHDAY=bymodaylist */
    private static class ParseByMonthDay extends PartParser {
        @Override public int parsePart(String value, EventRecurrence er) {
            int[] bymonthday = parseNumberList(value, -31, 31, false);
            er.bymonthday = bymonthday;
            er.bymonthdayCount = bymonthday.length;
            return PARSED_BYMONTHDAY;
        }
    }
    /** parses BYYEARDAY=byyrdaylist */
    private static class ParseByYearDay extends PartParser {
        @Override public int parsePart(String value, EventRecurrence er) {
            int[] byyearday = parseNumberList(value, -366, 366, false);
            er.byyearday = byyearday;
            er.byyeardayCount = byyearday.length;
            return PARSED_BYYEARDAY;
        }
    }
    /** parses BYWEEKNO=bywknolist */
    private static class ParseByWeekNo extends PartParser {
        @Override public int parsePart(String value, EventRecurrence er) {
            int[] byweekno = parseNumberList(value, -53, 53, false);
            er.byweekno = byweekno;
            er.byweeknoCount = byweekno.length;
            return PARSED_BYWEEKNO;
        }
    }
    /** parses BYMONTH=bymolist */
    private static class ParseByMonth extends PartParser {
        @Override public int parsePart(String value, EventRecurrence er) {
            int[] bymonth = parseNumberList(value, 1, 12, false);
            er.bymonth = bymonth;
            er.bymonthCount = bymonth.length;
            return PARSED_BYMONTH;
        }
    }
    /** parses BYSETPOS=bysplist */
    private static class ParseBySetPos extends PartParser {
        @Override public int parsePart(String value, EventRecurrence er) {
            int[] bysetpos = parseNumberList(value, Integer.MIN_VALUE, Integer.MAX_VALUE, true);
            er.bysetpos = bysetpos;
            er.bysetposCount = bysetpos.length;
            return PARSED_BYSETPOS;
        }
    }
    /** parses WKST={SU,MO,...} */
    private static class ParseWkst extends PartParser {
        @Override public int parsePart(String value, EventRecurrence er) {
            Integer wkst = sParseWeekdayMap.get(value);
            if (wkst == null) {
                throw new InvalidFormatException("Invalid WKST value: " + value);
            }
            er.wkst = wkst;
            return PARSED_WKST;
        }
    }
}
