/*******************************************************************************
* 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);
	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 && name) {
		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);

		if ((buf = u_malloc(len)) != NULL) {
			if (prefix != NULL && name != NULL)
				sprintf(buf, "%s:%s", prefix, name);
			else
				strcpy(buf, name);
		}
	}
	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 ((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];
		sprintf(buf, "%lu", uVal);
		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];
		sprintf(buf, "%ld", Val);
		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) {
		char buf[12];
		sprintf(buf, "%E", Val);
		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);
	xml_parser_doc_dump(f, doc);
	return;
}

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

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

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));
	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;
}

/** @} */
