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

/*
 * XSEC
 *
 * XSECXMLNSStack := NS Stack for simple canonicalisation
 *
 * $Id$
 *
 */


// XSEC
#include <xsec/framework/XSECDefs.hpp>
#include <xsec/framework/XSECError.hpp>
#include <xsec/canon/XSECXMLNSStack.hpp>

#include "../utils/XSECDOMUtils.hpp"

// Xerces

XERCES_CPP_NAMESPACE_USE

// --------------------------------------------------------------------------------
//           Holder structures
// --------------------------------------------------------------------------------

typedef struct XSECNSHolderStruct {

	XERCES_CPP_NAMESPACE_QUALIFIER DOMNode	* mp_ns;		// Actual NS attribute
	XERCES_CPP_NAMESPACE_QUALIFIER DOMNode	* mp_owner;		// Owner Element

	struct XSECNSHolderStruct				* mp_hides;		// WHat does this NS hide?
	struct XSECNSHolderStruct				* mp_next;		// Next in list

	XERCES_CPP_NAMESPACE_QUALIFIER DOMNode	* mp_printed;	// Node at which it was printed

	bool									m_isDefault;	// Is this a default NS?

} XSECNSHolder;

typedef struct XSECNSElementStruct {

	XERCES_CPP_NAMESPACE_QUALIFIER DOMNode	* mp_elt;		// Element
	struct XSECNSHolderStruct				* mp_firstNS;	// WHat does this NS hide?

} XSECNSElement;

// --------------------------------------------------------------------------------
//           Construct/Destruct
// --------------------------------------------------------------------------------


XSECXMLNSStack::XSECXMLNSStack() {

}

XSECXMLNSStack::~XSECXMLNSStack() {

	// Need to iterate through the Stack to 
	XSECNSElement * t;
	XSECNSHolder * u, *v;
	
	while (m_elements.size() > 0) {
		t = m_elements.top();
		u = t->mp_firstNS;
		while (u != NULL) {
			v = u->mp_next;
			delete u;
			u = v;
		}
		delete t;
		m_elements.pop();
	}
}


// --------------------------------------------------------------------------------
//           Stack Functions
// --------------------------------------------------------------------------------
void XSECXMLNSStack::pushElement(XERCES_CPP_NAMESPACE_QUALIFIER DOMNode * elt) {

	XSECNSElement * t;
	XSECnew(t, XSECNSElement);

	t->mp_elt = elt;
	t->mp_firstNS = NULL;

	m_elements.push(t);

}

void XSECXMLNSStack::popElement() {

	// First - are there any namespaces to remove from the currently visible list?
	XSECNSHolder * t, *u;
	XSECNSElement * e = m_elements.top();

	// Iterate through the current namespaces vector
	XSECNSHolderVectorType::iterator it = m_currentNS.begin();

	while (it != m_currentNS.end()) {

		t = *it;
		if (t->mp_owner == e->mp_elt) {

			// Need to delete this
			m_currentNS.erase(it);
			if (t->mp_hides != NULL) {
				m_currentNS.push_back(t->mp_hides);
			}
			// TODO - Fix this, it is naieve and slow
			it = m_currentNS.begin();

		}
		else {
			if (t->mp_printed == e->mp_elt)
				t->mp_printed = NULL;
			it++;
		}

	}

	// OK - Now we delete the NS nodes
	t = e->mp_firstNS;
	while (t != NULL) {
		u = t->mp_next;
		delete t;
		t = u;
	}

	// Now delete the element holder itself
	m_elements.pop();
	delete e;

}


// --------------------------------------------------------------------------------
//           NS Addition
// --------------------------------------------------------------------------------

void XSECXMLNSStack::addNamespace(XERCES_CPP_NAMESPACE_QUALIFIER DOMNode * ns) {

	// Create the new entry for this node
	XSECNSHolder * t, *u;
	XSECnew(t, XSECNSHolder);

	t->mp_hides = NULL;
	t->mp_next = NULL;
	t->mp_ns = ns;
	t->mp_owner = (m_elements.top())->mp_elt;
	t->mp_printed = NULL;

	t->m_isDefault = strEquals(ns->getNodeName(), DSIGConstants::s_unicodeStrXmlns);

	// Does this hide something in the current namespace list?
	XSECNSHolderVectorType::iterator it = m_currentNS.begin();

	while (it != m_currentNS.end()) {
		u = (*it);
		if (strEquals(u->mp_ns->getNodeName(), ns->getNodeName())) {

			// This hides a current NS entry
			t->mp_hides = u;
			m_currentNS.erase(it);
			it = m_currentNS.end();
		}
		else
			it++;
	}

	// Now push it onto the namespace vector
	m_currentNS.push_back(t);

	// Add me to the current element's namespaces
	XSECNSElement * e = m_elements.top();
	
	t->mp_next = e->mp_firstNS;
	e->mp_firstNS = t;

}

void XSECXMLNSStack::printNamespace(DOMNode * ns, DOMNode * elt) {

	XSECNSHolder * t;
	XSECNSHolderVectorType::iterator it = m_currentNS.begin();

	while (it != m_currentNS.end()) {
		t = (*it);
		// Fix for bug#47353, go ahead and track printing of default namespaces.
		if (t->mp_ns == ns) { //  && t->m_isDefault == false) {
			t->mp_printed = elt;
			break;
		}
		it++;
	}
}

// --------------------------------------------------------------------------------
//           NS Searching
// --------------------------------------------------------------------------------

DOMNode * XSECXMLNSStack::getFirstNamespace(void) {

	m_currentNSIterator = m_currentNS.begin();

	while (m_currentNSIterator != m_currentNS.end() && 
		(*m_currentNSIterator)->mp_printed != NULL)
		m_currentNSIterator++;

	if (m_currentNSIterator != m_currentNS.end())
		return (*m_currentNSIterator)->mp_ns;

	return NULL;

}

DOMNode * XSECXMLNSStack::getNextNamespace(void) {
	if (m_currentNSIterator == m_currentNS.end()) 
		return NULL;
	m_currentNSIterator++;
	while (m_currentNSIterator != m_currentNS.end() && 
		(*m_currentNSIterator)->mp_printed != NULL)
		m_currentNSIterator++;

	if (m_currentNSIterator == m_currentNS.end()) 
		return NULL;

	return (*m_currentNSIterator)->mp_ns;

}

// Fix for bug#47353, explicit check for non-empty default NS decl.
bool XSECXMLNSStack::isNonEmptyDefaultNS(void) {
    for (XSECNSHolderVectorType::iterator it = m_currentNS.begin(); it != m_currentNS.end(); ++it) {
        if ((*it)->m_isDefault) {
            const XMLCh* val = (*it)->mp_ns->getNodeValue();
            if (val && *val)
                return true;
        }
    }
    return false;
}
