/*   Copyright 2004 The Apache Software Foundation
 *
 *   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 org.apache.xmlbeans.impl.marshal;

import org.apache.xmlbeans.XmlError;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.impl.common.InvalidLexicalValueException;
import org.apache.xmlbeans.impl.common.XmlWhitespace;
import org.apache.xmlbeans.impl.richParser.XMLStreamReaderExt;
import org.apache.xmlbeans.impl.util.XsTypeConverter;

import javax.xml.namespace.QName;
import javax.xml.stream.Location;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;

final class MarshalStreamUtils
{
    static final String XSI_NS = "http://www.w3.org/2001/XMLSchema-instance";
    static final String XSI_TYPE_ATTR = "type";
    static final String XSI_NIL_ATTR = "nil";
    static final String XSI_SCHEMA_LOCATION_ATTR = "schemaLocation";
    static final String XSI_NO_NS_SCHEMA_LOCATION_ATTR =
        "noNamespaceSchemaLocation";

    static final QName XSI_NIL_QNAME = new QName(XSI_NS, XSI_NIL_ATTR);
    static final QName XSI_TYPE_QNAME = new QName(XSI_NS, XSI_TYPE_ATTR);


    static void getXsiAttributes(XsiAttributeHolder holder,
                                 XMLStreamReaderExt reader,
                                 Collection errors)
        throws XMLStreamException
    {
        assert reader.isStartElement();

        holder.reset();

        final int att_cnt = reader.getAttributeCount();
        for (int att_idx = 0; att_idx < att_cnt; att_idx++) {
            if (!XSI_NS.equals(reader.getAttributeNamespace(att_idx)))
                continue;

            try {
                final String lname = reader.getAttributeLocalName(att_idx);
                if (XSI_TYPE_ATTR.equals(lname)) {
                    holder.xsiType = reader.getAttributeQNameValue(att_idx);
                } else if (XSI_NIL_ATTR.equals(lname)) {
                    holder.hasXsiNil = reader.getAttributeBooleanValue(att_idx);
                } else if (XSI_SCHEMA_LOCATION_ATTR.equals(lname)) {
                    holder.schemaLocation =
                        reader.getAttributeStringValue(att_idx,
                                                       XmlWhitespace.WS_COLLAPSE);
                } else if (XSI_NO_NS_SCHEMA_LOCATION_ATTR.equals(lname)) {
                    holder.noNamespaceSchemaLocation =
                        reader.getAttributeStringValue(att_idx,
                                                       XmlWhitespace.WS_COLLAPSE);
                }
            }
                //nothing should have been assigned, so keep going
                //TODO: use real location (maybe just pass context to this method).
            catch (InvalidLexicalValueException ilve) {
                addError(errors, ilve.getMessage(),
                         ilve.getLocation());
            }
        }
    }

    static QName getXsiType(XMLStreamReader reader, Collection errors)
    {
        assert reader.isStartElement();

        final int att_cnt = reader.getAttributeCount();
        for (int att_idx = 0; att_idx < att_cnt; att_idx++) {
            if (!XSI_NS.equals(reader.getAttributeNamespace(att_idx)))
                continue;

            final String lname = reader.getAttributeLocalName(att_idx);
            if (XSI_TYPE_ATTR.equals(lname)) {
                final String type_str = reader.getAttributeValue(att_idx);
                return XsTypeConverter.lexQName(type_str, errors,
                                                reader.getNamespaceContext());
            }
        }

        return null;
    }

    /**
     * go to next start element.  if reader is sitting on a start element
     * then no advancing will be done.  returns false if we hit an end element,
     * or the end of the steam, otherwise returns true
     *
     * @param reader
     * @return
     */
    static boolean advanceToNextStartElement(XMLStreamReader reader)
        throws XmlException
    {
        try {
            for (int state = reader.getEventType();
                 reader.hasNext();
                 state = reader.next()) {
                switch (state) {
                    case XMLStreamReader.START_ELEMENT:
                        return true;
                    case XMLStreamReader.END_ELEMENT:
                        return false;
                    case XMLStreamReader.END_DOCUMENT:
                        throw new XmlException("unexpected end of XML");
                    default:
                        break;
                }
            }
        }
        catch (XMLStreamException xse) {
            throw new XmlException(xse);
        }

        //end of the steam
        return false;
    }


    /**
     * Skip current element node and all its contents.
     * Reader must be on start element.
     * Skips just past the matching end element.
     * We are just counting start/end -- the parser is
     * dealing with well-formedness.
     *
     * @param reader
     */
    static void skipElement(XMLStreamReader reader)
        throws XmlException
    {
        assert reader.isStartElement();

        int cnt = -1;

        //TODO: seem to be rechecking assertion, why not skip one ahead...

        try {
            int event = reader.getEventType();

            while (true) {
                switch (event) {
                    case XMLStreamReader.START_ELEMENT:
                        cnt++;
                        break;
                    case XMLStreamReader.END_ELEMENT:
                        if (cnt == 0) {
                            if (reader.hasNext())
                                reader.next(); // move past end element
                            return;
                        } else {
                            cnt--;
                        }
                        break;
                    case XMLStreamReader.END_DOCUMENT:
                        //should not happen for well-formed xml
                        throw new XmlException("unexpected end of xml document");
                    default:
                        break;
                }

                if (reader.hasNext()) {
                    event = reader.next();
                } else {
                    throw new XmlException("unexpected end of xml stream");
                }
            }
        }
        catch (XMLStreamException xse) {
            throw new XmlException(xse);
        }
    }


    static void advanceToFirstItemOfInterest(XMLStreamReader rdr)
        throws XmlException
    {
        try {
            for (int state = rdr.getEventType(); rdr.hasNext(); state = rdr.next()) {
                switch (state) {
                    case XMLStreamReader.START_ELEMENT:
                        return;
                    case XMLStreamReader.END_ELEMENT:
                        throw new XmlException("unexpected end of XML");

                    case XMLStreamReader.PROCESSING_INSTRUCTION:
                        break;
                    case XMLStreamReader.CHARACTERS:
                        if (rdr.isWhiteSpace()) break;
                        {
                            final String text = rdr.getText();
                            final Location loc = rdr.getLocation();
                            String msg = "unexpected character data: " + text +
                                " at line " + loc.getLineNumber() +
                                " column " + loc.getColumnNumber();
                            throw new XmlException(msg);
                        }
                    case XMLStreamReader.COMMENT:
                    case XMLStreamReader.SPACE:
                    case XMLStreamReader.START_DOCUMENT:
                        break;
                    case XMLStreamReader.END_DOCUMENT:
                        throw new XmlException("unexpected end of XML");

                    case XMLStreamReader.ENTITY_REFERENCE:
                        break;

                    case XMLStreamReader.ATTRIBUTE:
                        throw new AssertionError("NAKED ATTRIBUTE UNIMPLEMENTED");

                    case XMLStreamReader.DTD:
                    case XMLStreamReader.CDATA:
                    case XMLStreamReader.NAMESPACE:
                    case XMLStreamReader.NOTATION_DECLARATION:
                    case XMLStreamReader.ENTITY_DECLARATION:
                        break;

                    default:
                        throw new XmlException("unexpected xml state:" + state +
                                               "in" + rdr);
                }
            }
        }
        catch (XMLStreamException xse) {
            throw new XmlException(xse);
        }
        throw new XmlException("unexpected end of xml stream");
    }


    static void addError(Collection errors,
                         String msg,
                         Location location)
    {
        addError(errors, msg, XmlError.SEVERITY_ERROR, location);
    }

    static void addError(Collection errors,
                         String msg,
                         int severity,
                         Location location)
    {
        assert location != null;

        String systemId = location.getSystemId();
        if (systemId == null) {
            systemId = "<unknown>"; // without this we get no line numbers
        }

        final XmlError err =
            XmlError.forLocation(msg,
                                 severity,
                                 systemId,
                                 location.getLineNumber(),
                                 location.getColumnNumber(),
                                 location.getCharacterOffset());
        errors.add(err);
    }

    static Object inputStreamToBytes(final InputStream val)
        throws IOException
    {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        int b;

        while ((b = val.read()) != -1) {
            baos.write(b);
        }

        return baos.toByteArray();
    }


}
