/*
 * Copyright 2004,2005 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.axiom.om.impl.serialize;

import java.util.ArrayList;

import org.apache.axiom.om.OMSerializer;
import org.apache.axiom.om.impl.util.OMSerializerUtil;

import javax.xml.namespace.NamespaceContext;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;

/**
 * Class StreamingOMSerializer
 */
public class StreamingOMSerializer implements XMLStreamConstants, OMSerializer {

    private static int namespaceSuffix = 0;
    public static final String NAMESPACE_PREFIX = "ns";

    /*
    * The behavior of the serializer is such that it returns when it encounters the
    * starting element for the second time. The depth variable tracks the depth of the
    * serilizer and tells it when to return.
    * Note that it is assumed that this serialization starts on an Element.
    */

    /**
     * Field depth
     */
    private int depth = 0;

    /**
     * Method serialize.
     *
     * @param node
     * @param writer
     * @throws XMLStreamException
     */
    public void serialize(XMLStreamReader node, XMLStreamWriter writer)
            throws XMLStreamException {
        serializeNode(node, writer);
    }

    /**
     * Method serializeNode.
     *
     * @param reader
     * @param writer
     * @throws XMLStreamException
     */
    protected void serializeNode(XMLStreamReader reader, XMLStreamWriter writer)
            throws XMLStreamException {
        //TODO We get the StAXWriter at this point and uses it hereafter assuming that this is the only entry point to this class.
        // If there can be other classes calling methodes of this we might need to change methode signatures to OMOutputer
        while (reader.hasNext()) {
            int event = reader.next();
            if (event == START_ELEMENT) {
                serializeElement(reader, writer);
                depth++;
            } else if (event == ATTRIBUTE) {
                serializeAttributes(reader, writer);
            } else if (event == CHARACTERS) {
                serializeText(reader, writer);
            } else if (event == COMMENT) {
                serializeComment(reader, writer);
            } else if (event == CDATA) {
                serializeCData(reader, writer);
            } else if (event == END_ELEMENT) {
                serializeEndElement(writer);
                depth--;
            }else if (event == START_DOCUMENT) {
                depth++; //if a start document is found then increment the depth
            } else if (event == END_DOCUMENT) {
                if (depth!=0) depth--;  //for the end document - reduce the depth
                try {
                    serializeEndElement(writer);
                } catch (Exception e) {
                    //TODO: log exceptions
                }
            }
            if (depth == 0) {
                break;
            }
        }
    }

    /**
     * @param reader
     * @param writer
     * @throws XMLStreamException
     */
    protected void serializeElement(XMLStreamReader reader,
                                    XMLStreamWriter writer)
            throws XMLStreamException {
        
    	// Note: To serialize the start tag, we must follow the order dictated by the JSR-173 (StAX) specification.
    	// Please keep this code in sync with the code in OMSerializerUtil.serializeStartpart
    
    	// The algorithm is:
        // ... generate setPrefix/setDefaultNamespace for each namespace declaration if the prefix is unassociated.
    	// ... generate setPrefix/setDefaultNamespace if the prefix of the element is unassociated
    	// ... generate setPrefix/setDefaultNamespace for each unassociated prefix of the attributes.
    	//
    	// ... generate writeStartElement (See NOTE_A)
    	//
    	// ... generate writeNamespace/writerDefaultNamespace for the new namespace declarations determine during the "set" processing
    	// ... generate writeAttribute for each attribute
    	
    	// NOTE_A: To confuse matters, some StAX vendors (including woodstox), believe that the setPrefix bindings 
    	// should occur after the writeStartElement.  If this is the case, the writeStartElement is generated first.
    	
    	ArrayList  writePrefixList = null;
    	ArrayList  writeNSList = null;
    	

    	// Get the prefix and namespace of the element.  "" and null are identical.
        String ePrefix = reader.getPrefix();
    	ePrefix = (ePrefix != null && ePrefix.length() == 0) ? null : ePrefix;
    	String eNamespace = reader.getNamespaceURI();
    	eNamespace = (eNamespace != null && eNamespace.length() == 0) ? null : eNamespace;
    	
    	// Write the startElement if required
		boolean setPrefixFirst = OMSerializerUtil.isSetPrefixBeforeStartElement(writer);
        if (!setPrefixFirst) {
        	if (eNamespace != null) {
        		if (ePrefix == null) {
        			writer.writeStartElement("", reader.getLocalName(), eNamespace);
        		} else {
        			writer.writeStartElement(ePrefix, reader.getLocalName(), eNamespace);
        		}
        	} else {
        		writer.writeStartElement(reader.getLocalName());
        	}
        }
    	
        // Generate setPrefix for the namespace declarations
        int count = reader.getNamespaceCount();
        for (int i = 0; i < count; i++) {
        	String prefix = reader.getNamespacePrefix(i);
        	prefix = (prefix != null && prefix.length() == 0) ? null : prefix;
        	String namespace = reader.getNamespaceURI(i);
        	namespace = (namespace != null && namespace.length() == 0) ? null : namespace;
        	
        	String newPrefix = generateSetPrefix(prefix, namespace, writer);
        	// If this is a new association, remember it so that it can written out later
        	if (newPrefix != null) {
        		if (writePrefixList == null) {
        			writePrefixList= new ArrayList();
        			writeNSList = new ArrayList();
        		}
        		if (!writePrefixList.contains(newPrefix)) {
        			writePrefixList.add(newPrefix);
        			writeNSList.add(namespace);
        		}
        	}
        }
        
        // Generate setPrefix for the element
        // If the prefix is not associated with a namespace yet, remember it so that we can
    	// write out a namespace declaration
    	String newPrefix = generateSetPrefix(ePrefix, eNamespace, writer);
    	// If this is a new association, remember it so that it can written out later
    	if (newPrefix != null) {
    		if (writePrefixList == null) {
    			writePrefixList= new ArrayList();
    			writeNSList = new ArrayList();
    		}
    		if (!writePrefixList.contains(newPrefix)) {
    			writePrefixList.add(newPrefix);
    			writeNSList.add(eNamespace);
    		}
    	}
    
        // Now Generate setPrefix for each attribute
        count = reader.getAttributeCount();
        for (int i = 0; i < count; i++) {
            String prefix = reader.getAttributePrefix(i);
            prefix = (prefix != null && prefix.length() == 0) ? null : prefix;
            String namespace = reader.getAttributeNamespace(i);
            namespace = (namespace != null && namespace.length() == 0) ? null : namespace;
            
            // Default prefix referencing is not allowed on an attribute
            if (prefix == null && namespace != null) {
            	String writerPrefix = writer.getPrefix(namespace);
            	writerPrefix = (writerPrefix != null && writerPrefix.length() == 0) ? null : writerPrefix;
            	prefix = (writerPrefix != null) ? 
            			writerPrefix :
            	        generateUniquePrefix(writer.getNamespaceContext());
            }
            newPrefix = generateSetPrefix(prefix, namespace, writer);
            // If the prefix is not associated with a namespace yet, remember it so that we can
        	// write out a namespace declaration
        	if (newPrefix != null) {
        		if (writePrefixList == null) {
        			writePrefixList= new ArrayList();
        			writeNSList = new ArrayList();
        		}
        		if (!writePrefixList.contains(newPrefix)) {
        			writePrefixList.add(newPrefix);
        			writeNSList.add(namespace);
        		}
        	}
        }
        
        // Now write the startElement
        if (setPrefixFirst) {
        	if (eNamespace != null) {
        		if (ePrefix == null) {
        			writer.writeStartElement("", reader.getLocalName(), eNamespace);
        		} else {
        			writer.writeStartElement(ePrefix, reader.getLocalName(), eNamespace);
        		}
        	} else {
        		writer.writeStartElement(reader.getLocalName());
        	}
        }

        // Now write out the list of namespace declarations in this list that we constructed
    	// while doing the "set" processing.
    	if (writePrefixList != null) {
        	for (int i=0; i<writePrefixList.size(); i++) {
        		String prefix = (String) writePrefixList.get(i);
        		String namespace = (String) writeNSList.get(i);	
        		if (prefix != null) {
            		writer.writeNamespace(prefix, namespace);
            	} else {
            		writer.writeDefaultNamespace(namespace);
            	}
        	}
        }
    	
        // Now write the attributes
        count = reader.getAttributeCount();
        for (int i = 0; i < count; i++) {
            String prefix = reader.getAttributePrefix(i);
            prefix = (prefix != null && prefix.length() == 0) ? null : prefix;
            String namespace = reader.getAttributeNamespace(i);
            namespace = (namespace != null && namespace.length() == 0) ? null : namespace;
            
            
            if (prefix == null && namespace != null) {
            	// Default namespaces are not allowed on an attribute reference.
                // Earlier in this code, a unique prefix was added for this case...now obtain and use it
            	prefix = writer.getPrefix(namespace);
            } else if (namespace != null) {
            	// Use the writer's prefix if it is different
            	String writerPrefix = writer.getPrefix(namespace);
            	if (!prefix.equals(writerPrefix)) {
            		prefix = writerPrefix;
            	}
            }
            if (namespace != null) {
            	// Qualified attribute
            	writer.writeAttribute(prefix, namespace,
                    reader.getAttributeLocalName(i),
                    reader.getAttributeValue(i));
            } else {
            	// Unqualified attribute
            	writer.writeAttribute(reader.getAttributeLocalName(i),
                        reader.getAttributeValue(i));
            }
        }
    }

    /**
     * Generate setPrefix/setDefaultNamespace if the prefix is not associated
     * @param prefix
     * @param namespace
     * @param writer
     * @return prefix name if a setPrefix/setDefaultNamespace is performed
     */
    private String generateSetPrefix(String prefix, String namespace, XMLStreamWriter writer) throws XMLStreamException {
    	return OMSerializerUtil.generateSetPrefix(prefix, namespace, writer);
    }
    
    /**
     * Method serializeEndElement.
     *
     * @param writer
     * @throws XMLStreamException
     */
    protected void serializeEndElement(XMLStreamWriter writer)
            throws XMLStreamException {
        writer.writeEndElement();
    }

    /**
     * @param reader
     * @param writer
     * @throws XMLStreamException
     */
    protected void serializeText(XMLStreamReader reader,
                                 XMLStreamWriter writer)
            throws XMLStreamException {
        writer.writeCharacters(reader.getText());
    }

    /**
     * Method serializeCData.
     *
     * @param reader
     * @param writer
     * @throws XMLStreamException
     */
    protected void serializeCData(XMLStreamReader reader,
                                  XMLStreamWriter writer)
            throws XMLStreamException {
        writer.writeCData(reader.getText());
    }

    /**
     * Method serializeComment.
     *
     * @param reader
     * @param writer
     * @throws XMLStreamException
     */
    protected void serializeComment(XMLStreamReader reader,
                                    XMLStreamWriter writer)
            throws XMLStreamException {
        writer.writeComment(reader.getText());
    }

    /**
     * @param reader
     * @param writer
     * @throws XMLStreamException
     */
    protected void serializeAttributes(XMLStreamReader reader,
                                       XMLStreamWriter writer)
            throws XMLStreamException {
        int count = reader.getAttributeCount();
        String prefix = null;
        String namespaceName = null;
        String writerPrefix=null;
        for (int i = 0; i < count; i++) {
            prefix = reader.getAttributePrefix(i);
            namespaceName = reader.getAttributeNamespace(i);
            /*
               Due to parser implementations returning null as the namespace URI
              (for the empty namespace) we need to make sure that we deal with
              a namespace name that is not null. The best way to work around this
              issue is to set the namespace uri to "" if it is null
            */
            if (namespaceName==null) namespaceName="";

            writerPrefix =writer.getNamespaceContext().getPrefix(namespaceName);

            if (!"".equals(namespaceName)){
                //prefix has already being declared but this particular attrib has a
                //no prefix attached. So use the prefix provided by the writer
                if (writerPrefix!=null && (prefix==null || prefix.equals(""))){
                    writer.writeAttribute(writerPrefix, namespaceName,
                            reader.getAttributeLocalName(i),
                            reader.getAttributeValue(i));

                    //writer prefix is available but different from the current
                    //prefix of the attrib. We should be decalring the new prefix
                    //as a namespace declaration
                }else if (prefix!=null && !"".equals(prefix)&& !prefix.equals(writerPrefix)){
                    writer.writeNamespace(prefix,namespaceName);
                    writer.writeAttribute(prefix, namespaceName,
                            reader.getAttributeLocalName(i),
                            reader.getAttributeValue(i));

                    //prefix is null (or empty), but the namespace name is valid! it has not
                    //being written previously also. So we need to generate a prefix
                    //here
                }else{
                    prefix = generateUniquePrefix(writer.getNamespaceContext());
                    writer.writeNamespace(prefix,namespaceName);
                    writer.writeAttribute(prefix, namespaceName,
                            reader.getAttributeLocalName(i),
                            reader.getAttributeValue(i));
                }
            }else{
                //empty namespace is equal to no namespace!
                writer.writeAttribute(reader.getAttributeLocalName(i),
                        reader.getAttributeValue(i));
            }


        }
    }

    /**
     * Generates a unique namespace prefix that is not in the
     * scope of the NamespaceContext
     * @param nsCtxt
     * @return string
     */
    private String generateUniquePrefix(NamespaceContext nsCtxt){
        String prefix = NAMESPACE_PREFIX + namespaceSuffix++;
        //null should be returned if the prefix is not bound!
        while(nsCtxt.getNamespaceURI(prefix)!=null){
            prefix = NAMESPACE_PREFIX + namespaceSuffix++;
        }

        return prefix;
    }
    /**
     * Method serializeNamespace.
     * @param prefix
     * @param URI
     * @param writer
     * @throws XMLStreamException
     */
    private void serializeNamespace(String prefix,
                                    String URI,
                                    XMLStreamWriter writer)
            throws XMLStreamException {
        String prefix1 = writer.getPrefix(URI);
        if (prefix1 == null) {
            writer.writeNamespace(prefix, URI);
            writer.setPrefix(prefix, URI);
        }
    }
}
