/*   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.validator;

import org.apache.xmlbeans.*;
import org.apache.xmlbeans.impl.common.GenericXmlInputStream;
import org.apache.xmlbeans.impl.common.ValidatorListener;
import org.apache.xmlbeans.impl.common.ValidatorListener.Event;
import org.apache.xmlbeans.impl.common.XMLNameHelper;
import org.apache.xmlbeans.impl.common.XmlWhitespace;
import org.apache.xmlbeans.impl.schema.BuiltinSchemaTypeSystem;
import org.apache.xmlbeans.xml.stream.CharacterData;
import org.apache.xmlbeans.xml.stream.*;

import javax.xml.namespace.QName;
import java.util.AbstractCollection;
import java.util.Collections;
import java.util.Iterator;
import java.util.Map;

/**
 * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API.
 */
public final class ValidatingXMLInputStream
    extends GenericXmlInputStream implements Event {
    public ValidatingXMLInputStream(
        XMLInputStream xis,
        SchemaTypeLoader typeLoader, SchemaType sType, XmlOptions options)
        throws XMLStreamException {
        _source = xis;

        // Figure out the root type

        options = XmlOptions.maskNull(options);

        SchemaType type = options.getDocumentType();

        if (type == null) {
            type = sType;
        }

        if (type == null) {
            type = BuiltinSchemaTypeSystem.ST_ANY_TYPE;

            xis = xis.getSubStream();

            if (xis.skip(XMLEvent.START_ELEMENT)) {
                SchemaType docType =
                    typeLoader.findDocumentType(
                        XMLNameHelper.getQName(xis.next().getName()));

                if (docType != null) {
                    type = docType;
                }
            }

            xis.close();
        }

        // Create the validator

        _validator =
            new Validator(
                type, null, typeLoader, options, new ExceptionXmlErrorListener());

        nextEvent(ValidatorListener.BEGIN);
    }

    // TODO - this is the quick and dirty impl of streaming validation,
    // may objects are created (like strings) which can be optimized

    protected XMLEvent nextEvent() throws XMLStreamException {
        XMLEvent e = _source.next();

        if (e == null) {
            if (!_finished) {
                flushText();
                nextEvent(ValidatorListener.END);
                _finished = true;
            }
        } else {
            switch (e.getType()) {
                case XMLEvent.CHARACTER_DATA:
                case XMLEvent.SPACE: {
                    CharacterData cd = (CharacterData) e;

                    if (cd.hasContent()) {
                        _text.append(cd.getContent());
                    }

                    break;
                }
                case XMLEvent.START_ELEMENT: {
                    StartElement se = (StartElement) e;

                    flushText();

                    // Used for prefix to namespace mapping
                    _startElement = se;

                    // Prepare the xsi:* values

                    AttributeIterator attrs = se.getAttributes();

                    while (attrs.hasNext()) {
                        Attribute attr = attrs.next();

                        XMLName attrName = attr.getName();

                        if ("http://www.w3.org/2001/XMLSchema-instance".equals(
                            attrName.getNamespaceUri())) {
                            String local = attrName.getLocalName();

                            if (local.equals("type")) {
                                _xsiType = attr.getValue();
                            } else if (local.equals("nil")) {
                                _xsiNil = attr.getValue();
                            } else if (local.equals("schemaLocation")) {
                                _xsiLoc = attr.getValue();
                            } else if (local.equals("noNamespaceSchemaLocation")) {
                                _xsiNoLoc = attr.getValue();
                            }
                        }
                    }

                    // Emit the START

                    // TODO - should delay the aquisition of the name
                    _name = e.getName();

                    nextEvent(ValidatorListener.BEGIN);

                    // Emit the attrs

                    attrs = se.getAttributes();

                    while (attrs.hasNext()) {
                        Attribute attr = attrs.next();

                        XMLName attrName = attr.getName();

                        if ("http://www.w3.org/2001/XMLSchema-instance".equals(
                            attrName.getNamespaceUri())) {
                            String local = attrName.getLocalName();

                            if (local.equals("type")) {
                                continue;
                            } else if (local.equals("nil")) {
                                continue;
                            } else if (local.equals("schemaLocation")) {
                                continue;
                            } else if (local.equals("noNamespaceSchemaLocation")) {
                                continue;
                            }
                        }

                        // TODO - God, this is lame :-)

                        _text.append(attr.getValue());
                        _name = attr.getName();

                        nextEvent(ValidatorListener.ATTR);
                    }

                    clearText();

                    _startElement = null;

                    break;
                }

                case XMLEvent.END_ELEMENT: {
                    flushText();

                    nextEvent(ValidatorListener.END);

                    break;
                }
            }
        }

        return e;
    }

    private void clearText() {
        _text.delete(0, _text.length());
    }

    private void flushText() throws XMLStreamException {
        if (_text.length() > 0) {
            nextEvent(ValidatorListener.TEXT);
            clearText();
        }
    }

    public String getNamespaceForPrefix(String prefix) {
        if (_startElement == null) {
            return null;
        }

        Map map = _startElement.getNamespaceMap();

        if (map == null) {
            return null;
        }

        return (String) map.get(prefix);
    }

    public XmlCursor getLocationAsCursor() {
        return null;
    }

    public javax.xml.stream.Location getLocation() {
        try {
            final org.apache.xmlbeans.xml.stream.Location xeLoc = _source.peek().getLocation();

            if (xeLoc == null) {
                return null;
            }

            javax.xml.stream.Location loc = new javax.xml.stream.Location() {
                public int getLineNumber() {
                    return xeLoc.getLineNumber();
                }

                public int getColumnNumber() {
                    return xeLoc.getColumnNumber();
                }

                public int getCharacterOffset() {
                    return -1;
                }

                public String getPublicId() {
                    return xeLoc.getPublicId();
                }

                public String getSystemId() {
                    return xeLoc.getSystemId();
                }
            };

            return loc;
        } catch (XMLStreamException e) {
            return null;
        }
    }

    public String getXsiType() {
        return _xsiType;
    }

    public String getXsiNil() {
        return _xsiNil;
    }

    public String getXsiLoc() {
        return _xsiLoc;
    }

    public String getXsiNoLoc() {
        return _xsiNoLoc;
    }

    public QName getName() {
        return XMLNameHelper.getQName(_name);
    }

    public String getText() {
        return _text.toString();
    }

    public String getText(int wsr) {
        return XmlWhitespace.collapse(_text.toString(), wsr);
    }

    public boolean textIsWhitespace() {
        for (int i = 0; i < _text.length(); i++) {
            switch (_text.charAt(i)) {
                case ' ':
                case '\n':
                case '\r':
                case '\t':
                    break;

                default:
                    return false;
            }
        }

        return true;
    }

    private final class ExceptionXmlErrorListener extends AbstractCollection {
        public boolean add(Object o) {
            assert ValidatingXMLInputStream.this._exception == null;

            ValidatingXMLInputStream.this._exception =
                new XMLStreamValidationException((XmlError) o);

            return false;
        }

        public Iterator iterator() {
            return Collections.EMPTY_LIST.iterator();
        }

        public int size() {
            return 0;
        }
    }

    private void nextEvent(int kind)
        throws XMLStreamException {
        assert _exception == null;

        _validator.nextEvent(kind, this);

        if (_exception != null) {
            throw _exception;
        }
    }

    private XMLStreamValidationException _exception;

    private XMLInputStream _source;
    private Validator _validator;
    private StringBuilder _text = new StringBuilder();
    private boolean _finished;
    private String _xsiType;
    private String _xsiNil;
    private String _xsiLoc;
    private String _xsiNoLoc;
    private XMLName _name;
    private StartElement _startElement;
}