/*
 * Copyright (C) 2007 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.util.Log;

import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.ArrayList;

/**
 * Parses RFC 2445 iCalendar objects.
 */
public class ICalendar {

    private static final String TAG = "Sync";

    // TODO: keep track of VEVENT, VTODO, VJOURNAL, VFREEBUSY, VTIMEZONE, VALARM
    // components, by type field or by subclass?  subclass would allow us to
    // enforce grammars.

    /**
     * Exception thrown when an iCalendar object has invalid syntax.
     */
    public static class FormatException extends Exception {
        public FormatException() {
            super();
        }

        public FormatException(String msg) {
            super(msg);
        }

        public FormatException(String msg, Throwable cause) {
            super(msg, cause);
        }
    }

    /**
     * A component within an iCalendar (VEVENT, VTODO, VJOURNAL, VFEEBUSY,
     * VTIMEZONE, VALARM).
     */
    public static class Component {

        // components
        static final String BEGIN = "BEGIN";
        static final String END = "END";
        private static final String NEWLINE = "\n";
        public static final String VCALENDAR = "VCALENDAR";
        public static final String VEVENT = "VEVENT";
        public static final String VTODO = "VTODO";
        public static final String VJOURNAL = "VJOURNAL";
        public static final String VFREEBUSY = "VFREEBUSY";
        public static final String VTIMEZONE = "VTIMEZONE";
        public static final String VALARM = "VALARM";

        private final String mName;
        private final Component mParent; // see if we can get rid of this
        private LinkedList<Component> mChildren = null;
        private final LinkedHashMap<String, ArrayList<Property>> mPropsMap =
                new LinkedHashMap<String, ArrayList<Property>>();

        /**
         * Creates a new component with the provided name.
         * @param name The name of the component.
         */
        public Component(String name, Component parent) {
            mName = name;
            mParent = parent;
        }

        /**
         * Returns the name of the component.
         * @return The name of the component.
         */
        public String getName() {
            return mName;
        }

        /**
         * Returns the parent of this component.
         * @return The parent of this component.
         */
        public Component getParent() {
            return mParent;
        }

        /**
         * Helper that lazily gets/creates the list of children.
         * @return The list of children.
         */
        protected LinkedList<Component> getOrCreateChildren() {
            if (mChildren == null) {
                mChildren = new LinkedList<Component>();
            }
            return mChildren;
        }

        /**
         * Adds a child component to this component.
         * @param child The child component.
         */
        public void addChild(Component child) {
            getOrCreateChildren().add(child);
        }

        /**
         * Returns a list of the Component children of this component.  May be
         * null, if there are no children.
         *
         * @return A list of the children.
         */
        public List<Component> getComponents() {
            return mChildren;
        }

        /**
         * Adds a Property to this component.
         * @param prop
         */
        public void addProperty(Property prop) {
            String name= prop.getName();
            ArrayList<Property> props = mPropsMap.get(name);
            if (props == null) {
                props = new ArrayList<Property>();
                mPropsMap.put(name, props);
            }
            props.add(prop);
        }

        /**
         * Returns a set of the property names within this component.
         * @return A set of property names within this component.
         */
        public Set<String> getPropertyNames() {
            return mPropsMap.keySet();
        }

        /**
         * Returns a list of properties with the specified name.  Returns null
         * if there are no such properties.
         * @param name The name of the property that should be returned.
         * @return A list of properties with the requested name.
         */
        public List<Property> getProperties(String name) {
            return mPropsMap.get(name);
        }

        /**
         * Returns the first property with the specified name.  Returns null
         * if there is no such property.
         * @param name The name of the property that should be returned.
         * @return The first property with the specified name.
         */
        public Property getFirstProperty(String name) {
            List<Property> props = mPropsMap.get(name);
            if (props == null || props.size() == 0) {
                return null;
            }
            return props.get(0);
        }

        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            toString(sb);
            sb.append(NEWLINE);
            return sb.toString();
        }

        /**
         * Helper method that appends this component to a StringBuilder.  The
         * caller is responsible for appending a newline at the end of the
         * component.
         */
        public void toString(StringBuilder sb) {
            sb.append(BEGIN);
            sb.append(":");
            sb.append(mName);
            sb.append(NEWLINE);

            // append the properties
            for (String propertyName : getPropertyNames()) {
                for (Property property : getProperties(propertyName)) {
                    property.toString(sb);
                    sb.append(NEWLINE);
                }
            }

            // append the sub-components
            if (mChildren != null) {
                for (Component component : mChildren) {
                    component.toString(sb);
                    sb.append(NEWLINE);
                }
            }

            sb.append(END);
            sb.append(":");
            sb.append(mName);
        }
    }

    /**
     * A property within an iCalendar component (e.g., DTSTART, DTEND, etc.,
     * within a VEVENT).
     */
    public static class Property {
        // properties
        // TODO: do we want to list these here?  the complete list is long.
        public static final String DTSTART = "DTSTART";
        public static final String DTEND = "DTEND";
        public static final String DURATION = "DURATION";
        public static final String RRULE = "RRULE";
        public static final String RDATE = "RDATE";
        public static final String EXRULE = "EXRULE";
        public static final String EXDATE = "EXDATE";
        // ... need to add more.
        
        private final String mName;
        private LinkedHashMap<String, ArrayList<Parameter>> mParamsMap =
                new LinkedHashMap<String, ArrayList<Parameter>>();
        private String mValue; // TODO: make this final?

        /**
         * Creates a new property with the provided name.
         * @param name The name of the property.
         */
        public Property(String name) {
            mName = name;
        }

        /**
         * Creates a new property with the provided name and value.
         * @param name The name of the property.
         * @param value The value of the property.
         */
        public Property(String name, String value) {
            mName = name;
            mValue = value;
        }

        /**
         * Returns the name of the property.
         * @return The name of the property.
         */
        public String getName() {
            return mName;
        }

        /**
         * Returns the value of this property.
         * @return The value of this property.
         */
        public String getValue() {
            return mValue;
        }

        /**
         * Sets the value of this property.
         * @param value The desired value for this property.
         */
        public void setValue(String value) {
            mValue = value;
        }        

        /**
         * Adds a {@link Parameter} to this property.
         * @param param The parameter that should be added.
         */
        public void addParameter(Parameter param) {
            ArrayList<Parameter> params = mParamsMap.get(param.name);
            if (params == null) {
                params = new ArrayList<Parameter>();
                mParamsMap.put(param.name, params);
            }
            params.add(param);
        }

        /**
         * Returns the set of parameter names for this property.
         * @return The set of parameter names for this property.
         */
        public Set<String> getParameterNames() {
            return mParamsMap.keySet();
        }

        /**
         * Returns the list of parameters with the specified name.  May return
         * null if there are no such parameters.
         * @param name The name of the parameters that should be returned.
         * @return The list of parameters with the specified name.
         */
        public List<Parameter> getParameters(String name) {
            return mParamsMap.get(name);
        }

        /**
         * Returns the first parameter with the specified name.  May return
         * nll if there is no such parameter.
         * @param name The name of the parameter that should be returned.
         * @return The first parameter with the specified name.
         */
        public Parameter getFirstParameter(String name) {
            ArrayList<Parameter> params = mParamsMap.get(name);
            if (params == null || params.size() == 0) {
                return null;
            }
            return params.get(0);
        }

        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            toString(sb);
            return sb.toString();
        }

        /**
         * Helper method that appends this property to a StringBuilder.  The
         * caller is responsible for appending a newline after this property.
         */
        public void toString(StringBuilder sb) {
            sb.append(mName);
            Set<String> parameterNames = getParameterNames();
            for (String parameterName : parameterNames) {
                for (Parameter param : getParameters(parameterName)) {
                    sb.append(";");
                    param.toString(sb);
                }
            }
            sb.append(":");
            sb.append(mValue);
        }
    }

    /**
     * A parameter defined for an iCalendar property.
     */
    // TODO: make this a proper class rather than a struct?
    public static class Parameter {
        public String name;
        public String value;

        /**
         * Creates a new empty parameter.
         */
        public Parameter() {
        }

        /**
         * Creates a new parameter with the specified name and value.
         * @param name The name of the parameter.
         * @param value The value of the parameter.
         */
        public Parameter(String name, String value) {
            this.name = name;
            this.value = value;
        }

        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            toString(sb);
            return sb.toString();
        }

        /**
         * Helper method that appends this parameter to a StringBuilder.
         */
        public void toString(StringBuilder sb) {
            sb.append(name);
            sb.append("=");
            sb.append(value);
        }
    }

    private static final class ParserState {
        // public int lineNumber = 0;
        public String line; // TODO: just point to original text
        public int index;
    }

    // use factory method
    private ICalendar() {
    }

    // TODO: get rid of this -- handle all of the parsing in one pass through
    // the text.
    private static String normalizeText(String text) {
        // it's supposed to be \r\n, but not everyone does that
        text = text.replaceAll("\r\n", "\n");
        text = text.replaceAll("\r", "\n");

        // we deal with line folding, by replacing all "\n " strings
        // with nothing.  The RFC specifies "\r\n " to be folded, but
        // we handle "\n " and "\r " too because we can get those.
        text = text.replaceAll("\n ", "");

        return text;
    }

    /**
     * Parses text into an iCalendar component.  Parses into the provided
     * component, if not null, or parses into a new component.  In the latter
     * case, expects a BEGIN as the first line.  Returns the provided or newly
     * created top-level component.
     */
    // TODO: use an index into the text, so we can make this a recursive
    // function?
    private static Component parseComponentImpl(Component component,
                                                String text)
            throws FormatException {
        Component current = component;
        ParserState state = new ParserState();
        state.index = 0;

        // split into lines
        String[] lines = text.split("\n");

        // each line is of the format:
        // name *(";" param) ":" value
        for (String line : lines) {
            try {
                current = parseLine(line, state, current);
                // if the provided component was null, we will return the root
                // NOTE: in this case, if the first line is not a BEGIN, a
                // FormatException will get thrown.   
                if (component == null) {
                    component = current;
                }
            } catch (FormatException fe) {
                if (false) {
                    Log.v(TAG, "Cannot parse " + line, fe);
                }
                // for now, we ignore the parse error.  Google Calendar seems
                // to be emitting some misformatted iCalendar objects.
            }
            continue;
        }
        return component;
    }

    /**
     * Parses a line into the provided component.  Creates a new component if
     * the line is a BEGIN, adding the newly created component to the provided
     * parent.  Returns whatever component is the current one (to which new
     * properties will be added) in the parse.
     */
    private static Component parseLine(String line, ParserState state,
                                       Component component)
            throws FormatException {
        state.line = line;
        int len = state.line.length();

        // grab the name
        char c = 0;
        for (state.index = 0; state.index < len; ++state.index) {
            c = line.charAt(state.index);
            if (c == ';' || c == ':') {
                break;
            }
        }
        String name = line.substring(0, state.index);

        if (component == null) {
            if (!Component.BEGIN.equals(name)) {
                throw new FormatException("Expected BEGIN");
            }
        }

        Property property;
        if (Component.BEGIN.equals(name)) {
            // start a new component
            String componentName = extractValue(state);
            Component child = new Component(componentName, component);
            if (component != null) {
                component.addChild(child);
            }
            return child;
        } else if (Component.END.equals(name)) {
            // finish the current component
            String componentName = extractValue(state);
            if (component == null ||
                    !componentName.equals(component.getName())) {
                throw new FormatException("Unexpected END " + componentName);
            }
            return component.getParent();
        } else {
            property = new Property(name);
        }

        if (c == ';') {
            Parameter parameter = null;
            while ((parameter = extractParameter(state)) != null) {
                property.addParameter(parameter);
            }
        }
        String value = extractValue(state);
        property.setValue(value);
        component.addProperty(property);
        return component;
    }

    /**
     * Extracts the value ":..." on the current line.  The first character must
     * be a ':'.
     */
    private static String extractValue(ParserState state)
            throws FormatException {
        String line = state.line;
        if (state.index >= line.length() || line.charAt(state.index) != ':') {
            throw new FormatException("Expected ':' before end of line in "
                    + line);
        }
        String value = line.substring(state.index + 1);
        state.index = line.length() - 1;
        return value;
    }

    /**
     * Extracts the next parameter from the line, if any.  If there are no more
     * parameters, returns null.
     */
    private static Parameter extractParameter(ParserState state)
            throws FormatException {
        String text = state.line;
        int len = text.length();
        Parameter parameter = null;
        int startIndex = -1;
        int equalIndex = -1;
        while (state.index < len) {
            char c = text.charAt(state.index);
            if (c == ':') {
                if (parameter != null) {
                    if (equalIndex == -1) {
                        throw new FormatException("Expected '=' within "
                                + "parameter in " + text);
                    }
                    parameter.value = text.substring(equalIndex + 1,
                                                     state.index);
                }
                return parameter; // may be null
            } else if (c == ';') {
                if (parameter != null) {
                    if (equalIndex == -1) {
                        throw new FormatException("Expected '=' within "
                                + "parameter in " + text);
                    }
                    parameter.value = text.substring(equalIndex + 1,
                                                     state.index);
                    return parameter;
                } else {
                    parameter = new Parameter();
                    startIndex = state.index;
                }
            } else if (c == '=') {
                equalIndex = state.index;
                if ((parameter == null) || (startIndex == -1)) {
                    throw new FormatException("Expected ';' before '=' in "
                            + text);
                }
                parameter.name = text.substring(startIndex + 1, equalIndex);
            } else if (c == '"') {
                if (parameter == null) {
                    throw new FormatException("Expected parameter before '\"' in " + text);
                }
                if (equalIndex == -1) {
                    throw new FormatException("Expected '=' within parameter in " + text);
                }
                if (state.index > equalIndex + 1) {
                    throw new FormatException("Parameter value cannot contain a '\"' in " + text);
                }
                final int endQuote = text.indexOf('"', state.index + 1);
                if (endQuote < 0) {
                    throw new FormatException("Expected closing '\"' in " + text);
                }
                parameter.value = text.substring(state.index + 1, endQuote);
                state.index = endQuote + 1;
                return parameter;
            }
            ++state.index;
        }
        throw new FormatException("Expected ':' before end of line in " + text);
    }

    /**
     * Parses the provided text into an iCalendar object.  The top-level
     * component must be of type VCALENDAR.
     * @param text The text to be parsed.
     * @return The top-level VCALENDAR component.
     * @throws FormatException Thrown if the text could not be parsed into an
     * iCalendar VCALENDAR object.
     */
    public static Component parseCalendar(String text) throws FormatException {
        Component calendar = parseComponent(null, text);
        if (calendar == null || !Component.VCALENDAR.equals(calendar.getName())) {
            throw new FormatException("Expected " + Component.VCALENDAR);
        }
        return calendar;
    }

    /**
     * Parses the provided text into an iCalendar event.  The top-level
     * component must be of type VEVENT.
     * @param text The text to be parsed.
     * @return The top-level VEVENT component.
     * @throws FormatException Thrown if the text could not be parsed into an
     * iCalendar VEVENT.
     */
    public static Component parseEvent(String text) throws FormatException {
        Component event = parseComponent(null, text);
        if (event == null || !Component.VEVENT.equals(event.getName())) {
            throw new FormatException("Expected " + Component.VEVENT);
        }
        return event;
    }

    /**
     * Parses the provided text into an iCalendar component.
     * @param text The text to be parsed.
     * @return The top-level component.
     * @throws FormatException Thrown if the text could not be parsed into an
     * iCalendar component.
     */
    public static Component parseComponent(String text) throws FormatException {
        return parseComponent(null, text);
    }

    /**
     * Parses the provided text, adding to the provided component.
     * @param component The component to which the parsed iCalendar data should
     * be added.
     * @param text The text to be parsed.
     * @return The top-level component.
     * @throws FormatException Thrown if the text could not be parsed as an
     * iCalendar object.
     */
    public static Component parseComponent(Component component, String text)
        throws FormatException {
        text = normalizeText(text);
        return parseComponentImpl(component, text);
    }
}
