/*
 * Copyright (C) 2008 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.google.android.util;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.io.Reader;

import android.util.Xml;
import android.util.Log;

/**
 * This is an abstraction of a pull parser that provides several benefits:<ul>
 *   <li>it is easier to use robustly because it makes it trivial to handle unexpected tags (which
 *   might have children)</li>
 *   <li>it makes the handling of text (cdata) blocks more convenient</li>
 *   <li>it provides convenient methods for getting a mandatory attribute (and throwing an exception
 *   if it is missing) or an optional attribute (and using a default value if it is missing)
 * </ul>
 */
public class SimplePullParser {
    public static final String TEXT_TAG = "![CDATA[";

    private String mLogTag = null;
    private final XmlPullParser mParser;
    private String mCurrentStartTag;

    /**
     * Constructs a new SimplePullParser to parse the stream
     * @param stream stream to parse
     * @param encoding the encoding to use
     */
    public SimplePullParser(InputStream stream, String encoding)
            throws ParseException, IOException {
        try {
            XmlPullParser parser = Xml.newPullParser();
            parser.setInput(stream, encoding);
            moveToStartDocument(parser);
            mParser = parser;
            mCurrentStartTag = null;
        } catch (XmlPullParserException e) {
            throw new ParseException(e);
        }
    }

    /**
     * Constructs a new SimplePullParser to parse the xml
     * @param parser the underlying parser to use
     */
    public SimplePullParser(XmlPullParser parser) {
        mParser = parser;
        mCurrentStartTag = null;
    }

    /**
     * Constructs a new SimplePullParser to parse the xml
     * @param xml the xml to parse
     */
    public SimplePullParser(String xml) throws IOException, ParseException {
        this(new StringReader(xml));
    }

    /**
     * Constructs a new SimplePullParser to parse the xml
     * @param reader a reader containing the xml
     */
    public SimplePullParser(Reader reader) throws IOException, ParseException {
        try {
            XmlPullParser parser = Xml.newPullParser();
            parser.setInput(reader);
            moveToStartDocument(parser);
            mParser = parser;
            mCurrentStartTag = null;
        } catch (XmlPullParserException e) {
            throw new ParseException(e);
        }
    }

    private static void moveToStartDocument(XmlPullParser parser)
            throws XmlPullParserException, IOException {
        int eventType;
        eventType = parser.getEventType();
        if (eventType != XmlPullParser.START_DOCUMENT) {
            throw new XmlPullParserException("Not at start of response");
        }
    }

    /**
     * Enables logging to the provided log tag. A basic representation of the xml will be logged as
     * the xml is parsed. No logging is done unless this is called.
     *
     * @param logTag the log tag to use when logging
     */
    public void setLogTag(String logTag) {
        mLogTag = logTag;
    }

    /**
     * Returns the tag of the next element whose depth is parentDepth plus one
     * or null if there are no more such elements before the next start tag. When this returns,
     * getDepth() and all methods relating to attributes will refer to the element whose tag is
     * returned.
     *
     * @param parentDepth the depth of the parrent of the item to be returned
     * @param textBuilder if null then text blocks will be ignored. If
     *   non-null then text blocks will be added to the builder and TEXT_TAG
     *   will be returned when one is found
     * @return the next of the next child element's tag, TEXT_TAG if a text block is found, or null
     *   if there are no more child elements or DATA blocks
     * @throws IOException propogated from the underlying parser
     * @throws ParseException if there was an error parsing the xml.
     */
    public String nextTagOrText(int parentDepth, StringBuilder textBuilder)
            throws IOException, ParseException {
        while (true) {
            int eventType = 0;
            try {
                eventType = mParser.next();
            } catch (XmlPullParserException e) {
                throw new ParseException(e);
            }
            int depth = mParser.getDepth();
            mCurrentStartTag = null;

            if (eventType == XmlPullParser.START_TAG && depth == parentDepth + 1) {
                mCurrentStartTag = mParser.getName();
                if (mLogTag != null && Log.isLoggable(mLogTag, Log.DEBUG)) {
                    StringBuilder sb = new StringBuilder();
                    for (int i = 0; i < depth; i++) sb.append("  ");
                    sb.append("<").append(mParser.getName());
                    int count = mParser.getAttributeCount();
                    for (int i = 0; i < count; i++) {
                        sb.append(" ");
                        sb.append(mParser.getAttributeName(i));
                        sb.append("=\"");
                        sb.append(mParser.getAttributeValue(i));
                        sb.append("\"");
                    }
                    sb.append(">");
                    Log.d(mLogTag, sb.toString());
                }
                return mParser.getName();
            }

            if (eventType == XmlPullParser.END_TAG && depth == parentDepth) {
                if (mLogTag != null && Log.isLoggable(mLogTag, Log.DEBUG)) {
                    StringBuilder sb = new StringBuilder();
                    for (int i = 0; i < depth; i++) sb.append("  ");
                    sb.append("</>"); // Not quite valid xml but it gets the job done.
                    Log.d(mLogTag, sb.toString());
                }
                return null;
            }

            if (eventType == XmlPullParser.END_DOCUMENT && parentDepth == 0) {
                return null;
            }

            if (eventType == XmlPullParser.TEXT && depth == parentDepth) {
                if (textBuilder == null) {
                    continue;
                }
                String text = mParser.getText();
                textBuilder.append(text);
                return TEXT_TAG;
            }
        }
    }

    /**
     * The same as nextTagOrTexxt(int, StringBuilder) but ignores text blocks.
     */
    public String nextTag(int parentDepth) throws IOException, ParseException {
        return nextTagOrText(parentDepth, null /* ignore text */);
    }

    /**
     * Returns the depth of the current element. The depth is 0 before the first
     * element has been returned, 1 after that, etc.
     *
     * @return the depth of the current element
     */
    public int getDepth() {
        return mParser.getDepth();
    }

    /**
     * Consumes the rest of the children, accumulating any text at this level into the builder.
     *
     * @param textBuilder the builder to contain any text
     * @throws IOException propogated from the XmlPullParser
     * @throws ParseException if there was an error parsing the xml.
     */
    public void readRemainingText(int parentDepth, StringBuilder textBuilder)
            throws IOException, ParseException {
        while (nextTagOrText(parentDepth, textBuilder) != null) {
        }
    }

    /**
     * Returns the number of attributes on the current element.
     *
     * @return the number of attributes on the current element
     */
    public int numAttributes() {
        return mParser.getAttributeCount();
    }

    /**
     * Returns the name of the nth attribute on the current element.
     *
     * @return the name of the nth attribute on the current element
     */
    public String getAttributeName(int i) {
        return mParser.getAttributeName(i);
    }

    /**
     * Returns the namespace of the nth attribute on the current element.
     *
     * @return the namespace of the nth attribute on the current element
     */
    public String getAttributeNamespace(int i) {
        return mParser.getAttributeNamespace(i);
    }

    /**
     * Returns the string value of the named attribute.
     *
     * @param namespace the namespace of the attribute
     * @param name the name of the attribute
     * @param defaultValue the value to return if the attribute is not specified
     * @return the value of the attribute
     */
    public String getStringAttribute(
            String namespace, String name, String defaultValue) {
        String value = mParser.getAttributeValue(namespace, name);
        if (null == value) return defaultValue;
        return value;
    }

    /**
     * Returns the string value of the named attribute. An exception will
     * be thrown if the attribute is not present.
     *
     * @param namespace the namespace of the attribute
     * @param name the name of the attribute @return the value of the attribute
     * @throws ParseException thrown if the attribute is missing
     */
    public String getStringAttribute(String namespace, String name) throws ParseException {
        String value = mParser.getAttributeValue(namespace, name);
        if (null == value) {
            throw new ParseException(
                    "missing '" + name + "' attribute on '" + mCurrentStartTag + "' element");
        }
        return value;
    }

    /**
     * Returns the string value of the named attribute. An exception will
     * be thrown if the attribute is not a valid integer.
     *
     * @param namespace the namespace of the attribute
     * @param name the name of the attribute
     * @param defaultValue the value to return if the attribute is not specified
     * @return the value of the attribute
     * @throws ParseException thrown if the attribute not a valid integer.
     */
    public int getIntAttribute(String namespace, String name, int defaultValue)
            throws ParseException {
        String value = mParser.getAttributeValue(namespace, name);
        if (null == value) return defaultValue;
        try {
            return Integer.parseInt(value);
        } catch (NumberFormatException e) {
            throw new ParseException("Cannot parse '" + value + "' as an integer");
        }
    }

    /**
     * Returns the string value of the named attribute. An exception will
     * be thrown if the attribute is not present or is not a valid integer.
     *
     * @param namespace the namespace of the attribute
     * @param name the name of the attribute @return the value of the attribute
     * @throws ParseException thrown if the attribute is missing or not a valid integer.
     */
    public int getIntAttribute(String namespace, String name)
            throws ParseException {
        String value = getStringAttribute(namespace, name);
        try {
            return Integer.parseInt(value);
        } catch (NumberFormatException e) {
            throw new ParseException("Cannot parse '" + value + "' as an integer");
        }
    }

    /**
     * Returns the string value of the named attribute. An exception will
     * be thrown if the attribute is not a valid long.
     *
     * @param namespace the namespace of the attribute
     * @param name the name of the attribute @return the value of the attribute
     * @throws ParseException thrown if the attribute is not a valid long.
     */
    public long getLongAttribute(String namespace, String name, long defaultValue)
            throws ParseException {
        String value = mParser.getAttributeValue(namespace, name);
        if (null == value) return defaultValue;
        try {
            return Long.parseLong(value);
        } catch (NumberFormatException e) {
            throw new ParseException("Cannot parse '" + value + "' as a long");
        }
    }

    /**
     * Returns the string value of the named attribute. An exception will
     * be thrown if the attribute is not present or is not a valid long.
     *
     * @param namespace the namespace of the attribute
     * @param name the name of the attribute @return the value of the attribute
     * @throws ParseException thrown if the attribute is missing or not a valid long.
     */
    public long getLongAttribute(String namespace, String name)
            throws ParseException {
        String value = getStringAttribute(namespace, name);
        try {
            return Long.parseLong(value);
        } catch (NumberFormatException e) {
            throw new ParseException("Cannot parse '" + value + "' as a long");
        }
    }

    public static final class ParseException extends Exception {
        public ParseException(String message) {
            super(message);
        }

        public ParseException(String message, Throwable cause) {
            super(message, cause);
        }

        public ParseException(Throwable cause) {
            super(cause);
        }
    }
}
