/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you 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.common;

import javax.xml.stream.XMLStreamReader;

import org.apache.axiom.om.OMException;
import org.apache.axiom.om.OMNode;
import org.apache.axiom.om.OMSourcedElement;
import org.apache.axiom.om.OMXMLParserWrapper;
import org.apache.axiom.om.OMXMLStreamReader;
import org.apache.axiom.om.OMXMLStreamReaderConfiguration;
import org.apache.axiom.om.impl.OMNodeEx;
import org.apache.axiom.om.impl.builder.OMFactoryEx;
import org.apache.axiom.om.impl.builder.StAXOMBuilder;
import org.apache.axiom.om.util.OMXMLStreamReaderValidator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public final class OMContainerHelper {
    private static final Log log = LogFactory.getLog(OMContainerHelper.class);
    
    private static final OMXMLStreamReaderConfiguration defaultReaderConfiguration = new OMXMLStreamReaderConfiguration();
    
    private OMContainerHelper() {}
    
    public static XMLStreamReader getXMLStreamReader(IContainer container, boolean cache) {
        return getXMLStreamReader(container, cache, defaultReaderConfiguration);
    }
    
    public static XMLStreamReader getXMLStreamReader(IContainer container, boolean cache, OMXMLStreamReaderConfiguration configuration) {
        OMXMLParserWrapper builder = container.getBuilder();
        if (builder != null && builder instanceof StAXOMBuilder) {
            if (!container.isComplete()) {
                if (((StAXOMBuilder) builder).isLookahead()) {
                    buildNext(container);
                }
            }
        }
        
        // The om tree was built by hand and is already complete
        OMXMLStreamReader reader;
        boolean done = container.isComplete();
        if ((builder == null) && done) {
            reader = new OMStAXWrapper(null, container, false, configuration.isPreserveNamespaceContext());
        } else {
            if ((builder == null) && !cache) {
                throw new UnsupportedOperationException(
                "This element was not created in a manner to be switched");
            }
            if (builder != null && builder.isCompleted() && !cache && !done) {
                throw new UnsupportedOperationException(
                "The parser is already consumed!");
            }
            reader = new OMStAXWrapper(builder, container, cache, configuration.isPreserveNamespaceContext());
        }
        
        if (configuration.isNamespaceURIInterning()) {
            reader = new NamespaceURIInterningXMLStreamReaderWrapper(reader);
        }
        
        // If debug is enabled, wrap the OMXMLStreamReader in a validator.
        // The validator will check for mismatched events to help determine if the OMStAXWrapper
        // is functioning correctly.  All problems are reported as debug.log messages
        
        if (log.isDebugEnabled()) {
            reader = 
                new OMXMLStreamReaderValidator(reader, // delegate to actual reader
                     false); // log problems (true will cause exceptions to be thrown)
        }
        
        return reader;
    }
    
    public static void addChild(IContainer container, OMNode omNode, boolean fromBuilder) {
        OMNodeEx child;
        if (fromBuilder) {
            // If the new child was provided by the builder, we know that it was created by
            // the same factory
            child = (OMNodeEx)omNode;
        } else {
            // Careful here: if the child was created by another Axiom implementation, it doesn't
            // necessarily implement OMNodeEx
            if (omNode.getOMFactory().getMetaFactory() == container.getOMFactory().getMetaFactory()) {
                child = (OMNodeEx)omNode;
            } else {
                child = (OMNodeEx)((OMFactoryEx)container.getOMFactory()).importNode(omNode);
            }
            if (!container.isComplete()) {
                container.build();
            }
            if (child.getParent() == container && child == container.getLastKnownOMChild()) {
                // The child is already the last node. 
                // We don't need to detach and re-add it.
                return;
            }
        }
        if (child.getParent() != null) {
            child.detach();
        }
        
        child.setParent(container);

        if (container.getFirstOMChildIfAvailable() == null) {
            container.setFirstChild(child);
        } else {
            OMNode lastChild = container.getLastKnownOMChild();
            child.setPreviousOMSibling(lastChild);
            ((OMNodeEx)lastChild).setNextOMSibling(child);
        }
        container.setLastChild(child);

        // For a normal OMNode, the incomplete status is
        // propogated up the tree.  
        // However, a OMSourcedElement is self-contained 
        // (it has an independent parser source).
        // So only propogate the incomplete setting if this
        // is a normal OMNode
        if (!fromBuilder && !child.isComplete() && 
            !(child instanceof OMSourcedElement)) {
            container.setComplete(false);
        }
    }
    
    public static void build(IContainer container) {
        OMXMLParserWrapper builder = container.getBuilder();
        if (builder != null && builder.isCompleted()) {
            log.debug("Builder is already complete.");
        }
        while (!container.isComplete()) {

            builder.next();    
            if (builder.isCompleted() && !container.isComplete()) {
                log.debug("Builder is complete.  Setting OMObject to complete.");
                container.setComplete(true);
            }
        }
    }
    
    public static void buildNext(IParentNode that) {
        OMXMLParserWrapper builder = that.getBuilder();
        if (builder != null) {
            if (((StAXOMBuilder)builder).isClosed()) {
                throw new OMException("The builder has already been closed");
            } else if (!builder.isCompleted()) {
                builder.next();
            } else {
                // If the builder is suddenly complete, but the completion status of the node
                // doesn't change, then this means that we built the wrong nodes
                throw new IllegalStateException("Builder is already complete");
            }         
        }
    }
    
    public static OMNode getFirstOMChild(IParentNode that) {
        OMNode firstChild;
        while ((firstChild = that.getFirstOMChildIfAvailable()) == null && !that.isComplete()) {
            buildNext(that);
        }
        return firstChild;
    }
}
