/*   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.impl.common.Chars;
import org.apache.xmlbeans.impl.common.XMLNameHelper;
import org.apache.xmlbeans.impl.common.GenericXmlInputStream;
import org.apache.xmlbeans.impl.common.ValidatorListener.Event;
import org.apache.xmlbeans.impl.common.ValidatorListener;
import org.apache.xmlbeans.impl.common.XmlWhitespace;
import org.apache.xmlbeans.impl.schema.BuiltinSchemaTypeSystem;
import org.apache.xmlbeans.SchemaType;
import org.apache.xmlbeans.SchemaTypeLoader;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlError;
import org.apache.xmlbeans.XmlOptions;
import org.apache.xmlbeans.XMLStreamValidationException;
import java.util.Map;
import java.util.AbstractCollection;
import java.util.Iterator;
import java.util.Collections;

import org.apache.xmlbeans.xml.stream.Attribute;
import org.apache.xmlbeans.xml.stream.AttributeIterator;
import org.apache.xmlbeans.xml.stream.CharacterData;
import org.apache.xmlbeans.xml.stream.StartElement;
import org.apache.xmlbeans.xml.stream.XMLEvent;
import org.apache.xmlbeans.xml.stream.XMLInputStream;
import org.apache.xmlbeans.xml.stream.XMLName;
import org.apache.xmlbeans.xml.stream.XMLStreamException;
import javax.xml.namespace.QName;

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 = (SchemaType) options.get( XmlOptions.DOCUMENT_TYPE );

        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 boolean getXsiType ( Chars chars )
    {
        if (_xsiType == null)
            return false;

        chars.string = _xsiType;
        chars.buffer = null;

        return true;
    }
    
    public boolean getXsiNil ( Chars chars )
    {
        if (_xsiNil == null)
            return false;

        chars.string = _xsiNil;
        chars.buffer = null;

        return true;
    }

    public boolean getXsiLoc ( Chars chars )
    {
        if (_xsiLoc == null)
            return false;

        chars.string = _xsiLoc;
        chars.buffer = null;

        return true;
    }

    public boolean getXsiNoLoc ( Chars chars )
    {
        if (_xsiNoLoc == null)
            return false;

        chars.string = _xsiNoLoc;
        chars.buffer = null;

        return true;
    }

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

    public void getText ( Chars chars )
    {
        chars.string = _text.toString();
        chars.buffer = null;
    }

    public void getText ( Chars chars, int wsr )
    {
        chars.string = XmlWhitespace.collapse( _text.toString(), wsr );
        chars.buffer = null;
    }

    // TODO - very expensive to get a string here
    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 StringBuffer   _text = new StringBuffer();
    private boolean        _finished;
    private String         _xsiType;
    private String         _xsiNil;
    private String         _xsiLoc;
    private String         _xsiNoLoc;
    private XMLName        _name;
    private StartElement   _startElement;
}