/*******************************************************************************
* Copyright (C) 2004-2006 Intel Corp. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
*  - Redistributions of source code must retain the above copyright notice,
*    this list of conditions and the following disclaimer.
*
*  - Redistributions in binary form must reproduce the above copyright notice,
*    this list of conditions and the following disclaimer in the documentation
*    and/or other materials provided with the distribution.
*
*  - Neither the name of Intel Corp. nor the names of its
*    contributors may be used to endorse or promote products derived from this
*    software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL Intel Corp. OR THE CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/

/**
 * @author Anas Nashif
 * @author Eugene Yarmosh
 */
#ifdef HAVE_CONFIG_H
#include <wsman_config.h>
#endif


#include "u/libu.h"
#include "wsman-xml-api.h"
#include "wsman-client-api.h"
#include "wsman-soap.h"
#include "wsman-xml.h"
#include "wsman-xml-binding.h"
#include "wsman-names.h"
/**
 * @defgroup XMLParserGeneric Generic XML Parser Interface
 * @brief Generic XML Parser interface functions
 *
 * @{
 */

/**
 * Create default namespace prefix
 * @param node XML node
 * @param uri Namespace URI
 * @param buf Text buffer
 * @param bufsize Buffer size
 */
struct __WsXmlNsData
{
    char* uri;
    char* prefix;
};
typedef struct __WsXmlNsData WsXmlNsData;

static WsXmlNsData     g_wsNsData[] =
{
	{XML_NS_SOAP_1_2, "s"},
	{XML_NS_ADDRESSING, "wsa"},
	{XML_NS_EVENTING, "wse"},
	{XML_NS_ENUMERATION, "wsen"},
	{XML_NS_SCHEMA_INSTANCE, "xsi"},
	{XML_NS_CIM_SCHEMA, "cim"},
	{XML_NS_WS_MAN_CAT, "cat"},
	{XML_NS_WSMAN_ID, "wsmid"},
	{XML_NS_XML_SCHEMA, "xs"},
	{XML_NS_WS_MAN, "wsman"},
	{XML_NS_CIM_BINDING, "wsmb"},
	{XML_NS_OPENWSMAN, "owsman"},
	{XML_NS_TRANSFER, "wxf"},
	{XML_NS_XML_NAMESPACES,"xml"},
	{NULL, NULL}
};

void
ws_xml_make_default_prefix(WsXmlNodeH node,
			   const char *uri, char *buf, int bufsize)
{
	WsXmlDocH doc = xml_parser_get_doc(node);
	if (!doc) {
		return;
	}

	int i = 0;
	if (doc != NULL && uri != NULL) {
		for (i = 0; g_wsNsData[i].uri != NULL; i++) {
			WsXmlNsData *nsd = &g_wsNsData[i];
			if (strcmp(uri, nsd->uri) == 0 && nsd->prefix) {
				snprintf(buf, bufsize, "%s",  nsd->prefix );
				return;
			}
		}
	}
	if(g_wsNsData[i].uri == NULL && bufsize >= 12)
		snprintf(buf, bufsize, "n%lu", ++doc->prefixIndex);
	else
		buf[0] = 0;
}

static int is_xml_val_true(const char *text)
{
	int retVal = 0;

	if (text) {
		const char *ptr = text;

		while (isdigit(*ptr))
			ptr++;

		if (*ptr) {
			if (!strcasecmp(text, "true") ||
			    !strcasecmp(text, "yes"))
				retVal = 1;
		} else {
			if (atoi(text) != 0)
				retVal = 1;
		}
	}

	return retVal;
}

/**
 * Enumerate namespaces in a node
 * @param node XML node
 * @param callback Namespace Enumeration callback
 * @param data Callback data
 */
static int
ns_enum_at_node(WsXmlNodeH node, WsXmlNsEnumCallback callback, void *data)
{
	int retVal = 0;

	if (node) {
		int i;
		WsXmlNsH ns;

		for (i = 0; (ns = ws_xml_get_ns(node, i)) != NULL; i++) {
			if ((retVal = callback(node, ns, data)) != 0)
				break;
		}
	}
	return retVal;
}


static char *make_qname(WsXmlNodeH node, const char *uri, const char *name)
{
	char *buf = NULL;
	if (name && uri && node) {
		size_t len = 1 + strlen(name);
		WsXmlNsH ns = xml_parser_ns_find(node, uri, NULL, 1, 1);
		const char *prefix = (!ns) ? NULL : ws_xml_get_ns_prefix(ns);

		if (prefix != NULL)
			len += 1 + strlen(prefix);

		buf = u_zalloc(len);
		if (!buf)
			return buf;

		if (prefix != NULL && name != NULL) {
			int ret = snprintf(buf, len, "%s:%s", prefix, name);
			if (ret < 0 || ret >= len) {
				u_free(buf);
				return NULL;
			}
		} else {
			strncpy(buf, name, len);
		}
	}
	return buf;
}


/**
 * Add QName attribute
 * @param node Parent XML node
 * @param nameNs Child Namespace
 * @param name Child Name
 * @param valueNs Namespace for value
 * @param value Child Value
 * @return Child XML node
 * @note
 * if namespaces has been changed after this function is called, itis caller's
 * responsibility to update QName fields accordingly
 */
WsXmlAttrH ws_xml_add_qname_attr(WsXmlNodeH node,
				 const char *nameNs,
				 const char *name,
				 const char *valueNs, const char *value)
{
	WsXmlAttrH attr = NULL;

	if (name && node && valueNs && value) {
		char *buf = make_qname(node, valueNs, value);
		if (buf != NULL) {
			attr =
			    ws_xml_add_node_attr(node, nameNs, name, buf);
			u_free(buf);
		}
	}

	return attr;
}

/**
 * Enumerate namespaces
 * @param node XML node
 * @param callback enumeration callback
 * @param data Callback data
 * @param bWalkUpTree Flag FIXME
 * @brief Enumerates all namespaces defined at the node and optionally (if bIncludeParents isn't zero)
 * walks up the parent chain
 */
void ws_xml_ns_enum(WsXmlNodeH node,
		    WsXmlNsEnumCallback callback,
		    void *data, int bWalkUpTree)
{
	while (node) {
		if (ns_enum_at_node(node, callback, data) || !bWalkUpTree)
			break;
		node = ws_xml_get_node_parent(node);
	}
}



/**
 * Create an empty envelope with a <b>Header</b> and a <b>Body</b>
 * @param soap Soap handler
 * @param soapVersion The SOAP version to be used for creating the envelope
 * @return An XMl document
 */
WsXmlDocH ws_xml_create_envelope( void )
{
	WsXmlDocH doc = NULL;

	if ((doc = ws_xml_create_doc(XML_NS_SOAP_1_2, SOAP_ENVELOPE)) != NULL) {
		WsXmlNodeH root = ws_xml_get_doc_root(doc);

		if (root == NULL ||
		    ws_xml_add_child(root, XML_NS_SOAP_1_2, "Header", NULL) == NULL ||
		    ws_xml_add_child(root, XML_NS_SOAP_1_2, "Body", NULL) == NULL) {
			ws_xml_destroy_doc(doc);
			doc = NULL;
		}
	}

	return doc;
}


/**
 * Duplicate an XML document
 * @param dstSoap Destination SOAP handle
 * @param srcDoc the Source document
 * @return The new XML document
 */
WsXmlDocH ws_xml_duplicate_doc( WsXmlDocH srcDoc)
{
	WsXmlDocH dst = NULL;
	WsXmlNodeH srcRoot = NULL;
	const char *name, *nsUri;

	if (!srcDoc)
		return NULL;

	srcRoot = ws_xml_get_doc_root(srcDoc);

	if (!srcRoot)
		return NULL;

	name = ws_xml_get_node_local_name(srcRoot);
	nsUri = ws_xml_get_node_name_ns(srcRoot);
	if ((dst = ws_xml_create_doc(nsUri, name)) != NULL) {
		int i;
		WsXmlNodeH node;
		WsXmlNodeH dstRoot = ws_xml_get_doc_root(dst);

		for (i = 0; (node = ws_xml_get_child(srcRoot,
						i, NULL, NULL)) != NULL; i++) {
			ws_xml_duplicate_tree(dstRoot, node);
		}
	}
	return dst;
}


/**
 * Duplicate an XML attribute
 * @param dstNode Destination XML node
 * @param srcNode Source Node
 */
void ws_xml_duplicate_attr(WsXmlNodeH dstNode, WsXmlNodeH srcNode)
{
	int i;
	WsXmlAttrH attr;
	for (i = 0; (attr = ws_xml_get_node_attr(srcNode, i)) != NULL; i++) {
		ws_xml_add_node_attr(dstNode,
				     ws_xml_get_attr_ns(attr),
				     ws_xml_get_attr_name(attr),
				     ws_xml_get_attr_value(attr));
	}
}

/**
 * Duplicate children of an XML node
 * @param dstNode Destination XML node
 * @param srcNode Source XML node
 */
int ws_xml_duplicate_children(WsXmlNodeH dstNode, WsXmlNodeH srcNode)
{
	int i;
	WsXmlNodeH child;
	for (i = 0;
	     (child = ws_xml_get_child(srcNode, i, NULL, NULL)) != NULL;
	     i++) {
		ws_xml_duplicate_tree(dstNode, child);
	}
	return i;
}


/**
 * Duplication complete XML tree
 * @param dstNode Destination XML node
 * @param srcNode Source XML node
 */
void ws_xml_duplicate_tree(WsXmlNodeH dstNode, WsXmlNodeH srcNode)
{
	WsXmlNodeH node;
	if (!srcNode || !dstNode) {
		error("NULL arguments: dst = %p; src = %p", dstNode,
		      srcNode);
		return;
	}
	node = ws_xml_add_child(dstNode,
				ws_xml_get_node_name_ns(srcNode),
				ws_xml_get_node_local_name(srcNode), NULL);
	if (!node) {
		error("could not add node");
		return;
	}
	ws_xml_duplicate_attr(node, srcNode);
	if (ws_xml_duplicate_children(node, srcNode) == 0) {
		// no children
		ws_xml_set_node_text(node, ws_xml_get_node_text(srcNode));
	}
}


void ws_xml_copy_node(WsXmlNodeH src, WsXmlNodeH dst)
{
	xml_parser_copy_node(src, dst);
}


int ws_xml_utf8_strlen(char *buf)
{
	return xml_parser_utf8_strlen(buf);
}

/**
 * Dump XML document contents into a Text buffer
 * @param doc XML document
 * @param buf The target buffer
 * @param ptrSize the size of the buffer
 * @param encoding The encoding to be used
 */
void ws_xml_dump_memory_enc(WsXmlDocH doc, char **buf, int *ptrSize,
			    const char *encoding)
{
	xml_parser_doc_to_memory(doc, buf, ptrSize, encoding);
}



/**
 * Free Memory
 * @param ptr Pointer to be freed
 */
void ws_xml_free_memory(void *ptr)
{
	xml_parser_free_memory(ptr);
}

WsXmlDocH ws_xml_clone_and_create_doc(WsXmlDocH doc,
		const char *rootNsUri,
		const char *rootName )
{
	return ws_xml_create_doc(rootNsUri, rootName);
}

/**
 * Initialize XML Parser
 * @param soap SOAP handle
 * @param nsData Array with namespace data
 */
int ws_xml_parser_initialize()
{
	xml_parser_initialize();
	return 1;
}


void ws_xml_parser_destroy()
{
	xml_parser_destroy();
}



/**
 * Get SOAP envelope header
 * @param doc XML document (Envelope)
 * @return XML node of the Header
 */
WsXmlNodeH ws_xml_get_soap_header(WsXmlDocH doc)
{
	return ws_xml_get_soap_element(doc, SOAP_HEADER);
}


/**
 * Enumerate Children
 * @param parent XML node parent
 * @param callback Enumeration callback
 * @param data Callback data
 * @param bRecursive Recursive flag
 * @return
 *
 */
int
ws_xml_enum_children(WsXmlNodeH parent,
		     WsXmlEnumCallback callback,
		     void *data, int bRecursive)
{
	int retVal = 0;
	int i;
	WsXmlNodeH child;

	for (i = 0;
	     (child = ws_xml_get_child(parent, i, NULL, NULL)) != NULL; i++) {
		if ((retVal =
		     ws_xml_enum_tree(child, callback, data,
				      bRecursive))) {
			break;
		}
	}
	return retVal;
}


/**
 * Get count of children
 * @param parent XML Node parent
 * @return Count of children in node
 */
int ws_xml_get_child_count(WsXmlNodeH parent)
{
	int count = 0;
	if (parent)
		count = xml_parser_get_count(parent, XML_COUNT_NODE, 0);
	return count;
}


/**
 * Enumerate XML tree
 * @param top Top XML node
 * @param callback Emumeration callback
 * @param data Callback data
 * @param bRecursive Recursive flag
 */
int ws_xml_enum_tree(WsXmlNodeH top, WsXmlEnumCallback callback,
		     void *data, int bRecursive)
{
	int retVal = 0;
	if (top) {
		if (!(retVal = callback(top, data)) && bRecursive) {
			retVal = ws_xml_enum_children(top, callback, data, bRecursive);
		}
	}
	return retVal;
}


/**
 * Get node namespace
 * @param node XML node
 * @return Namespace of node
 */
char *ws_xml_get_node_name_ns(WsXmlNodeH node)
{
	char *uri = NULL;
	if (node)
		uri = xml_parser_node_query(node, XML_NS_URI);

	return uri;
}


/**
 * Get node local name
 * @param node XML node
 * @return Node local name
 */
char *ws_xml_get_node_local_name(WsXmlNodeH node)
{
	char *name = NULL;
	if (node)
		name = xml_parser_node_query(node, XML_LOCAL_NAME);
	return name;
}


/**
 * Get XML Document root
 * @param doc XML document
 * @return XML root node
 */
WsXmlNodeH ws_xml_get_doc_root(WsXmlDocH doc)
{
	WsXmlNodeH node = NULL;
	if (doc != NULL)
		node = xml_parser_get_root(doc);
	return node;
}

/**
 * Get Node text
 * @param node XML node
 * @return XML node text
 */
char *ws_xml_get_node_text(WsXmlNodeH node)
{
	char *text = NULL;
	if (node) {
		text = xml_parser_node_query(node, XML_TEXT_VALUE);
	}
	return text;
}

/**
 * Read memory buffer into an XMl document
 * @param soap SOAP handler
 * @param buf Text buffer with XML string
 * @param size Buffer size
 * @param encoding Buffer encoding
 * @param options Parser options
 * @return XML document
 */
WsXmlDocH ws_xml_read_memory( const char *buf, size_t size, const char *encoding,
		unsigned long options)
{
	return xml_parser_memory_to_doc(buf, size, encoding, options);
}


WsXmlDocH ws_xml_read_file(const char *filename,
			   const char *encoding, unsigned long options)
{
	return xml_parser_file_to_doc( filename, encoding, options);
}


/**
 * Create XML document
 * @param soap SOAP handler
 * @param rootNsUri Root Namespace URI
 * @param rootName Root node name
 * @return XML document
 */
WsXmlDocH
ws_xml_create_doc( const char *rootNsUri, const char *rootName)
{
	WsXmlDocH wsDoc = (WsXmlDocH) u_zalloc(sizeof(*wsDoc));
	WsXmlNodeH rootNode;
	WsXmlNsH ns;
	char prefix[12];

	if (wsDoc == NULL) {
		error("No memory");
		return NULL;
	}
	if (!xml_parser_create_doc(wsDoc, rootName) ) {
		error("xml_parser_create_doc failed");
		u_free(wsDoc);
		return NULL;
	}

	if (rootNsUri == NULL) {
		return wsDoc;
	}

	rootNode = ws_xml_get_doc_root((WsXmlDocH) wsDoc);

	ws_xml_make_default_prefix(rootNode, rootNsUri, prefix,
				   sizeof(prefix));
	ns = xml_parser_ns_add(rootNode, rootNsUri, prefix);
	if (ns == NULL) {
		error("xml_parser_ns_add failed");
		ws_xml_destroy_doc(wsDoc);
		return NULL;
	}
	ws_xml_set_node_name(rootNode, rootNsUri, NULL);
	return wsDoc;
}



/**
 * Set node name
 * @param node XML node
 * @param nsUri Namespace URI
 * @param name Node name
 * @return status
 *
 */
int ws_xml_set_node_name(WsXmlNodeH node, const char *nsUri,
			 const char *name)
{
	int retVal = -1;

	if (node && (name || nsUri)) {
		if (name)
			retVal =
			    xml_parser_node_set(node, XML_LOCAL_NAME,
						name);
		else
			retVal = 0;

		if (!retVal && nsUri)
			retVal =
			    xml_parser_node_set(node, XML_NS_URI, nsUri);
	}

	return retVal;
}




/**
 * Destroy XML document
 * @param doc XML document
 */
void ws_xml_destroy_doc(WsXmlDocH doc)
{
	if (doc) {
		xml_parser_destroy_doc(doc);
		u_free(doc);
	}
}



/**
 * Callback for finding objects in tree
 * @param node XML node
 * @param _data Callback data
 * @return status
 */
static int find_in_tree_callback(WsXmlNodeH node, void *_data)
{
	FindInTreeCallbackData *data = (FindInTreeCallbackData *) _data;
	int retVal = ws_xml_is_node_qname(node, data->ns, data->name);

	if (retVal)
		data->node = node;

	return retVal;
}

/**
 * Find node in XML tree
 * @param head Head XML node
 * @param nsUri Namespace URI, NULL for wildcard
 * @param localName Node local name
 * @param bRecursive Recursive flag
 * @return Result XML node
 */
WsXmlNodeH ws_xml_find_in_tree(WsXmlNodeH head, const char *nsUri,
			       const char *localName, int bRecursive)
{
	FindInTreeCallbackData data;

	data.node = NULL;
	data.ns = nsUri;
	data.name = localName;

	ws_xml_enum_tree(head, find_in_tree_callback, &data, bRecursive);

	return data.node;
}


/**
 * Get SOAP body
 * @param doc XML document
 * @return Result XML node
 */
WsXmlNodeH ws_xml_get_soap_body(WsXmlDocH doc)
{
	return ws_xml_get_soap_element(doc, SOAP_BODY);
}



/**
 * Get SOAP element
 * @param doc XML document
 * @param name Node name
 * @return Result XML node
 */
WsXmlNodeH ws_xml_get_soap_element(WsXmlDocH doc, const char *name)
{
	WsXmlNodeH node = NULL;
	WsXmlNodeH env = ws_xml_get_soap_envelope(doc);
	char *soapUri = NULL;

	if (!env)
		return NULL;
	soapUri = ws_xml_get_node_name_ns(env);
	node = ws_xml_get_child(env, 0, NULL, NULL);
	if (!node)
		return NULL;
	if (!ws_xml_is_node_qname(node, soapUri, name)) {
		if (strcmp(name, SOAP_HEADER) != 0) {
			node = ws_xml_get_child(env, 1, NULL, NULL);
			if (node) {
				if (!ws_xml_is_node_qname(node, soapUri, name))
					node = NULL;
			}
		}
	}
	return node;
}

/**
 * Get XML child of a node
 * @param parent Parent node
 * @param index Index of the node to be returned
 * @param nsUri Namespace URI
 * @param localName Local name of the node
 * @return Result XML node
 */
WsXmlNodeH
ws_xml_get_child(WsXmlNodeH parent,
		 int index, const char *nsUri, const char *localName)
{
	WsXmlNodeH node = NULL;

	if (parent && index >= 0) {
		if (nsUri == NULL && localName == NULL)
			node = xml_parser_node_get(parent, index);
		else {
			int count = 0;
			node = xml_parser_get_first_child(parent);
			while (node != NULL) {
				if (ws_xml_is_node_qname (node, nsUri, localName)) {
					if (count == index)
						break;
					count++;
				}
				node = xml_parser_get_next_child(node);
			}
		}
	}

	return node;
}

/**
 * Is the XML node a qualified name
 * @param node XML node
 * @param nsUri Namespace URI
 * @param name node name
 * @return Returns 1 if node is QName
 * @brief Shortcats for QName manipulation name can be NULL, in this case just check namespace
 */
int ws_xml_is_node_qname(WsXmlNodeH node, const char *nsUri,
			 const char *name)
{
	int retVal = 0;
	char *nodeNsUri = NULL;
	if (!node)
		return 0;
	nodeNsUri = ws_xml_get_node_name_ns(node);
	if ((nsUri == NULL)
	    || (nsUri == nodeNsUri)
	    || (nsUri != NULL && nodeNsUri != NULL && !strcmp(nodeNsUri, nsUri))) {
		if (name == NULL || !strcmp(name, ws_xml_get_node_local_name(node)))
			retVal = 1;
	}
	return retVal;
}


/**
 * Count number of XML node children with same qualified name
 * (used to represent array elements)
 * @param parent XML node
 * @param nsUri Namespace URI
 * @param name children name to look for
 * @return Returns number of children of parent with this name
 * @brief Identical to ws_xml_get_child_count() if nsUri==NULL and name==NULL
 */
int 
ws_xml_get_child_count_by_qname(WsXmlNodeH parent, 
      const char *nsUri, const char *name)
{
	WsXmlNodeH node;
	int count;

	if (!parent)
	        return 0;
	if (nsUri == NULL && name == NULL) {
		return ws_xml_get_child_count(parent);
	}
	node = xml_parser_get_first_child(parent);
	count = 0;
	while (node != NULL) {
		if (ws_xml_is_node_qname(node, nsUri, name)) {
			count++;
		}
		node = xml_parser_get_next_child(node);
	}
	return count;
}


WsXmlDocH ws_xml_create_soap_envelope(void)
{
	return ws_xml_create_envelope();
}


/**
 * Get SOAP envelope
 * @param doc XML document
 * @return XML node with envelope
 */
WsXmlNodeH ws_xml_get_soap_envelope(WsXmlDocH doc)
{
	WsXmlNodeH root = ws_xml_get_doc_root(doc);
	if (ws_xml_is_node_qname(root, XML_NS_SOAP_1_2, SOAP_ENVELOPE)
	    || ws_xml_is_node_qname(root, XML_NS_SOAP_1_1, SOAP_ENVELOPE)) {
		return root;
	}
	return NULL;
}



/**
 * Get Node parent
 * @param node XML node
 * @return Node parent
 */
WsXmlNodeH ws_xml_get_node_parent(WsXmlNodeH node)
{
	WsXmlNodeH parent = NULL;
	if (node != NULL)
		parent = xml_parser_node_get(node, XML_ELEMENT_PARENT);

	return parent;
}

/**
 * Callback for finding Namespaces
 * @param node XML node
 * @param ns Namespace
 * @param _data Callback Data
 * @return status
 */
static int
ws_xml_find_ns_callback(WsXmlNodeH node, WsXmlNsH ns, void *_data)
{
	WsXmlFindNsData *data = (WsXmlFindNsData *) _data;
	char *curUri = ws_xml_get_ns_uri(ns);
	char *curPrefix = ws_xml_get_ns_prefix(ns);
	// debug("uri: %s prefix: %s", curUri, curPrefix );

	if (curUri == NULL) {
		return 0;
	}

	if ((data->nsUri != NULL && !strcmp(curUri, data->nsUri))
	    ||
	    (data->prefix != NULL && curPrefix != NULL &&
	     !strcmp(curPrefix, data->prefix))
	    || (data->nsUri == NULL && data->prefix == NULL &&
		curPrefix == NULL)) {
		data->node = node;
		data->ns = ns;
	}

	return (data->ns != NULL);
}


/**
 * Find namespace in an XML node
 * @param node XML node
 * @param nsUri Namespace URI
 * @param prefix Prefix
 * @param bWalkUpTree Flag FIXME
 * @brief
 * Looks up nsUri defined at the node and optionally
 * (if bIncludeParents isn't zero) walks up the parent chain
 * returns prefix for the namespace and node where it defined
 */
WsXmlNsH
ws_xml_find_ns(WsXmlNodeH node,
	       const char *nsUri, const char *prefix, int bWalkUpTree)
{
	WsXmlFindNsData data;

	data.node = NULL;
	data.ns = NULL;
	data.nsUri = nsUri;
	data.prefix = prefix;

	if ((nsUri || prefix) && node)
		ws_xml_ns_enum(node, ws_xml_find_ns_callback, &data,
			       bWalkUpTree);

	return data.ns;
}


char *ws_xml_get_node_name_ns_prefix(WsXmlNodeH node)
{
	char *prefix = NULL;
	if (node)
		prefix = xml_parser_node_query(node, XML_NS_PREFIX);
	return prefix;

}

char *ws_xml_get_node_name_ns_uri(WsXmlNodeH node)
{
	char *uri = NULL;
	if (node)
		uri = xml_parser_node_query(node, XML_NS_URI);
	return uri;

}


/**
 * Get count of Namespaces
 * @param node XML node
 * @param bWalkUpTree Tree Flag
 * @return Count
 */
int ws_xml_get_ns_count(WsXmlNodeH node, int bWalkUpTree)
{
	int count = xml_parser_get_count(node, XML_COUNT_NS, bWalkUpTree);

	return count;
}


/**
 * Get Namespace Prefix
 * @param ns Namespace
 * @return Prefix of Namespace
 */
char *ws_xml_get_ns_prefix(WsXmlNsH ns)
{
	if (ns)
		return xml_parser_ns_query(ns, XML_NS_PREFIX);
	return NULL;
}


/**
 * Get Namespace URI
 * @param ns Namespace
 * @return URI of namespace, NULL of not found
 */
char *ws_xml_get_ns_uri(WsXmlNsH ns)
{
	if (ns)
		return xml_parser_ns_query(ns, XML_NS_URI);
	return NULL;
}



/**
 * Get Namespace from a node
 * @param node XML node
 * @param index Index
 * @return Namespace
 */
WsXmlNsH ws_xml_get_ns(WsXmlNodeH node, int index)
{
	if (node)
		return xml_parser_ns_get(node, index);
	return NULL;
}

/**
 * Add child to an XML node
 * @param node XML node
 * @param nsUri Namespace URI
 * @param localName local name
 * @param val Value of the node
 * @return New XML node
 */
WsXmlNodeH
ws_xml_add_child(WsXmlNodeH node,
		 const char *nsUri, const char *localName, const char *val)
{
	WsXmlNodeH newNode = xml_parser_node_add(node, XML_LAST_CHILD, nsUri,
			localName, val, 0);
	return newNode;
}

/**
 *** Add a previous sibling to an XML node
 *** @param node XML node
 *** @param nsUri Namespace URI
 *** @param localName local name
 *** @param val Value of the node
 *** @return New XML node
 ***/
WsXmlNodeH
ws_xml_add_prev_sibling(WsXmlNodeH node,
		const char *nsUri, const char *localName, const char *val)
{
	WsXmlNodeH newNode = xml_parser_node_add(node, XML_ELEMENT_PREV, nsUri,
			localName, val, 0);
	return newNode;
}

WsXmlNodeH
ws_xml_add_child_sort(WsXmlNodeH node,
		 const char *nsUri, const char *localName, const char *val, int xmlescape)
{
	int i;
	WsXmlNodeH child, newNode = NULL;
	int count = ws_xml_get_child_count(node) ;
	if ( count == 0 ) {
		newNode = xml_parser_node_add(node, XML_LAST_CHILD, nsUri, localName, val, xmlescape);
	} else {
		for (i = 0; (child = ws_xml_get_child(node, i, NULL, NULL)) != NULL; i++) {
				char *name = ws_xml_get_node_local_name(child);
				if (strcmp(localName, name) < 0 ) {
					newNode = xml_parser_node_add(child, XML_ELEMENT_PREV, nsUri, localName, val, xmlescape);
					break;
				}
		}
		if (newNode == NULL) {
			newNode = xml_parser_node_add(node, XML_LAST_CHILD, nsUri, localName, val, xmlescape);
		}
	}
	return newNode;
}

WsXmlNodeH
ws_xml_add_empty_child_format(WsXmlNodeH node, const char *nsUri,
			      const char *format, ...)
{
	WsXmlNodeH newNode;
	va_list args;
	char buf[4096];
	va_start(args, format);
	vsnprintf(buf, 4096, format, args);
	va_end(args);
	newNode =
	    xml_parser_node_add(node, XML_LAST_CHILD, nsUri, buf, NULL, 0);

	return newNode;
}

WsXmlNodeH
ws_xml_add_child_format(WsXmlNodeH node, const char *nsUri,
			const char *localName, const char *format, ...)
{
	WsXmlNodeH newNode;
	va_list args;
	char buf[4096];
	va_start(args, format);
	vsnprintf(buf, 4096, format, args);
	va_end(args);
	newNode =
	    xml_parser_node_add(node, XML_LAST_CHILD, nsUri, localName,
				buf, 0);

	return newNode;
}


/**
 * Check of namespace prefix is OK.
 * @param ns Namespace
 * @param newPrefix New prefix
 * @param bDefault FIXME
 * @return 1 if Ok, 0 if not
 */
static int
is_ns_prefix_ok(WsXmlNsH ns, const char *newPrefix, int bDefault)
{
	int retVal = 0;
	char *curPrefix = xml_parser_ns_query(ns, XML_NS_PREFIX);

	if (bDefault) {
		if (curPrefix == NULL)
			retVal = 1;
	} else {
		if ((newPrefix == NULL && curPrefix != NULL)
		    ||
		    (newPrefix && curPrefix &&
		     !strcmp(newPrefix, curPrefix))) {
			retVal = 1;
		}
	}

	return retVal;
}




/**
 * Define Namespace
 * @param node XML node
 * @param nsUri Namespace URI
 * @param nsPrefix Namespace Prefix
 * @param bDefault FIXME
 * @return New Namespace
 * @todo if ns is present, it should work as replace, walk through the tree and
 * update QName values and attributes
 */
WsXmlNsH
ws_xml_define_ns(WsXmlNodeH node, const char *nsUri, const char *nsPrefix,
		 int bDefault)
{
	WsXmlNsH ns = NULL;

	if (node && nsUri) {
		ns = ws_xml_find_ns(node, nsUri, NULL, 0);
		if (ns == NULL || !is_ns_prefix_ok(ns, nsPrefix, bDefault)) {
			char buf[12];
			if (!bDefault && nsPrefix == NULL) {
				ws_xml_make_default_prefix(node, nsUri,
							   buf,
							   sizeof(buf));
				nsPrefix = buf;
			}
			ns = xml_parser_ns_add(node, nsUri, nsPrefix);
		}
	}
	return ns;
}

/**
 * Add QName child
 * @param parent Parent XML node
 * @param nameNs Child Namespace
 * @param name Child Name
 * @param valueNs Namespace for value
 * @param value Child Value
 * @return Child XML node
 * @note if namespaces has been changed after this function is called, it is caller's
 * responsibility to update QName fields accordingly
 *
 */
WsXmlNodeH
ws_xml_add_qname_child(WsXmlNodeH parent,
		       const char *nameNs,
		       const char *name,
		       const char *valueNs, const char *value)
{
	WsXmlNodeH node = ws_xml_add_child(parent, nameNs, name, NULL);
	if (node == NULL) {
		ws_xml_set_node_qname_val(node, valueNs, value);
	}
	return node;
}


int ws_xml_get_node_attr_count(WsXmlNodeH node)
{
	int count = 0;
	if (node)
		count = xml_parser_get_count(node, XML_COUNT_ATTR, 0);

	return count;
}


WsXmlAttrH
ws_xml_add_node_attr(WsXmlNodeH node,
		     const char *nsUri,
		     const char *name, const char *value)
{
	WsXmlAttrH attr = NULL;
	if (node && name)
		attr = xml_parser_attr_add(node, nsUri, name, value);

	return (WsXmlAttrH) attr;
}


void ws_xml_remove_node_attr(WsXmlAttrH attr)
{
	if (attr)
		xml_parser_attr_remove(attr);
}


WsXmlAttrH ws_xml_get_node_attr(WsXmlNodeH node, int index)
{
	return xml_parser_attr_get(node, index);
}

WsXmlAttrH
ws_xml_find_node_attr(WsXmlNodeH node, const char *attrNs,
		      const char *attrName)
{
	WsXmlAttrH attr = NULL;
	if (node && attrName) {
		int i = 0;

		for (i = 0; (attr = ws_xml_get_node_attr(node, i)) != NULL;
		     i++) {
			char *curNsUri = ws_xml_get_attr_ns(attr);
			char *curName = ws_xml_get_attr_name(attr);

			if ((attrNs == curNsUri)
			    ||
			    (attrNs != NULL
			     &&
			     curNsUri != NULL
			     && !strcmp(curNsUri, attrNs))) {
				if (!strcmp(attrName, curName))
					break;
			}
		}
	}

	return attr;
}


unsigned long ws_xml_get_node_ulong(WsXmlNodeH node)
{
	unsigned long val = 0;
	char *text = ws_xml_get_node_text(node);

	if (text)
		val = atoi(text);
	return val;
}


int ws_xml_set_node_ulong(WsXmlNodeH node, unsigned long uVal)
{
	int retVal = -1;
	if (node) {
		char buf[12];
		int ret = snprintf(buf, sizeof(buf), "%lu", uVal);
		if (ret < 0 || ret >= sizeof(buf))
			return -1;
		retVal = ws_xml_set_node_text(node, buf);
	}
	return retVal;
}

int ws_xml_set_node_long(WsXmlNodeH node, long Val)
{
	int retVal = -1;
	if (node) {
		char buf[12];
		int ret = snprintf(buf, sizeof(buf), "%ld", Val);
		if (ret < 0 || ret >= sizeof(buf))
			return -1;
		retVal = ws_xml_set_node_text(node, buf);
	}
	return retVal;
}

int ws_xml_set_node_real(WsXmlNodeH node, double Val)
{
	int retVal = -1;
	if (node) {
                /* __builtin___sprintf_chk' output between 13 and 15 bytes */
		char buf[15];
		int ret = snprintf(buf, sizeof(buf), "%E", Val);
		if (ret < 0 || ret >= sizeof(buf))
			return -1;
		retVal = ws_xml_set_node_text(node, buf);
	}
	return retVal;
}

char *ws_xml_get_attr_name(WsXmlAttrH attr)
{
	char *name = NULL;
	if (attr)
		name = xml_parser_attr_query(attr, XML_LOCAL_NAME);
	return name;
}

char *ws_xml_get_attr_ns(WsXmlAttrH attr)
{
	char *nsUri = NULL;

	if (attr)
		nsUri = xml_parser_attr_query(attr, XML_NS_URI);

	return nsUri;
}

char *ws_xml_get_attr_ns_prefix(WsXmlAttrH attr)
{
	char *prefix = NULL;

	if (attr)
		prefix = xml_parser_attr_query(attr, XML_NS_PREFIX);

	return prefix;
}


char *ws_xml_get_attr_value(WsXmlAttrH attr)
{
	char *val = NULL;
	if (attr)
		val = xml_parser_attr_query(attr, XML_TEXT_VALUE);
	return val;
}


char *ws_xml_find_attr_value(WsXmlNodeH node, const char *ns,
			     const char *attrName)
{
	char *val = NULL;
	WsXmlAttrH attr = ws_xml_find_node_attr(node, ns, attrName);

	if (attr)
		val = ws_xml_get_attr_value(attr);

	return val;
}

int ws_xml_find_attr_bool(WsXmlNodeH node, const char *ns,
			  const char *attrName)
{
	int retVal = 0;
	char *val = ws_xml_find_attr_value(node, ns, attrName);

	if (val != NULL)
		retVal = is_xml_val_true(val);

	return retVal;
}


unsigned long ws_xml_find_attr_ulong(WsXmlNodeH node, const char *ns,
				     const char *attrName)
{
	unsigned long retVal = 0;
	char *val = ws_xml_find_attr_value(node, ns, attrName);

	if (val != NULL)
		retVal = atoi(val);

	return retVal;
}


// if ns is not defined at the node or at any of its parents, it will be defined at the root
// if namespaces has been changed after this function is called, itis caller's
// responsibility to update QName fields accordingly
int ws_xml_set_node_qname_val(WsXmlNodeH node, const char *valNsUri,
			      const char *valName)
{
	int retVal = -1;
	if (node && valName && valNsUri) {
		char *buf = make_qname(node, valNsUri, valName);

		if (buf != NULL) {
			retVal = ws_xml_set_node_text(node, buf);
			u_free(buf);
		}
	}
	return retVal;
}

WsXmlDocH ws_xml_get_node_doc(WsXmlNodeH node)
{
	WsXmlDocH doc = NULL;

	if (node != NULL)
		doc = xml_parser_get_doc(node);

	return doc;
}


int ws_xml_set_node_text(WsXmlNodeH node, const char *text)
{
	int retVal = -1;

	if (node)
		retVal = xml_parser_node_set(node, XML_TEXT_VALUE, text);

	return retVal;
}

void ws_xml_set_node_lang(WsXmlNodeH node, const char *lang)
{
	xml_parser_node_set_lang(node, lang);
}


void ws_xml_dump_node_tree(FILE * f, WsXmlNodeH node)
{
	WsXmlDocH doc = xml_parser_get_doc(node);
	if (doc) {
		xml_parser_doc_dump(f, doc);
	}
}

void ws_xml_dump_memory_node_tree(WsXmlNodeH node, char **buf,
				  int *ptrSize)
{
	WsXmlDocH doc = xml_parser_get_doc(node);
	if (doc) {
		xml_parser_doc_dump_memory(doc, buf, ptrSize);
	}
}

void ws_xml_dump_memory_node_tree_enc(WsXmlNodeH node, char **buf,
				  int *ptrSize, const char *encoding)
{
	WsXmlDocH doc = xml_parser_get_doc(node);
	if (doc) {
		xml_parser_doc_dump_memory_enc(doc, buf, ptrSize, encoding);
	}
}

void ws_xml_dump_doc(FILE * f, WsXmlDocH doc)
{
	xml_parser_doc_dump(f, doc);
	return;
}


WsXmlNsH
ws_xml_ns_add(WsXmlNodeH node, const char *uri, const char *prefix)
{
	return xml_parser_ns_add(node, uri, prefix);
}



int ws_xml_check_xpath(WsXmlDocH doc, const char *xpath_expr)
{
	return xml_parser_check_xpath(doc, xpath_expr);
}


char *ws_xml_get_xpath_value(WsXmlDocH doc, char *expression)
{
	return xml_parser_get_xpath_value(doc, expression);
}



WsXmlDocH ws_xml_create_doc_by_import(WsXmlNodeH node)
{
	WsXmlDocH wsDoc = (WsXmlDocH) u_zalloc(sizeof(*wsDoc));
	if (wsDoc) {
		xml_parser_create_doc_by_import(wsDoc, node);
	}
	return wsDoc;
}


void ws_xml_unlink_node(WsXmlNodeH node)
{
	xml_parser_unlink_node(node);
}

void ws_xml_set_ns(WsXmlNodeH r, const char* namespace, const char* prefix)
{
	WsXmlNsH ns = ws_xml_ns_add(r, namespace, prefix);
	xml_parser_set_ns(r, ns, prefix);
}

int check_envelope_size(WsXmlDocH doc, unsigned int size, const char *charset)
{
	char *buf;
	int len;
	if(size == 0) return 0; 
	ws_xml_dump_memory_enc(doc, &buf, &len, charset);
	ws_xml_free_memory(buf);
	if(len > size) return 1;
	return 0;
}

/** @} */
