/*******************************************************************************
 * 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 Liang Hou
 */

#ifdef HAVE_CONFIG_H
#include <wsman_config.h>
#endif

#define _GNU_SOURCE
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>

#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-serializer.h"

#include "wsman-faults.h"
#include "wsman-soap-envelope.h"
#include "wsman-epr.h"


/**
 * Change Endpoint Reference from request to response format
 * @param dstHeader Destination header
 * @param epr The Endpoint Reference
 */
static void
wsman_epr_from_request_to_response(WsXmlNodeH dstHeader, WsXmlNodeH epr)
{
	int i;
	WsXmlNodeH child;
	WsXmlNodeH node = !epr ? NULL : ws_xml_get_child(epr, 0,
							 XML_NS_ADDRESSING,
							 WSA_ADDRESS);
	ws_xml_add_child(dstHeader, XML_NS_ADDRESSING, WSA_TO,
			 !node ? WSA_TO_ANONYMOUS :
			 ws_xml_get_node_text(node));

	if (!epr)
		goto cleanup;

	if ((node = ws_xml_get_child(epr, 0, XML_NS_ADDRESSING,
			      WSA_REFERENCE_PROPERTIES))) {
		for (i = 0; (child = ws_xml_get_child(node, i, NULL, NULL)) != NULL; i++) {
			ws_xml_duplicate_tree(dstHeader, child);
		}
	}
	if ((node = ws_xml_get_child(epr, 0, XML_NS_ADDRESSING,
			      WSA_REFERENCE_PARAMETERS))) {
		for (i = 0; (child = ws_xml_get_child(node, i, NULL, NULL)) != NULL; i++) {
			ws_xml_duplicate_tree(dstHeader, child);
		}
	}

cleanup:
	return;
}

/**
 * Create a response SOAP envelope
 * @param rqstDoc The XML document of the request
 * @param action the Response action
 * @return Response envelope
 */
WsXmlDocH
wsman_create_response_envelope(WsXmlDocH rqstDoc, const char *action)
{

	WsXmlDocH doc = ws_xml_create_envelope();
	WsXmlNodeH dstHeader, srcHeader, srcNode;
	if (wsman_is_identify_request(rqstDoc))
		return doc;
	if (!doc)
		return NULL;

	dstHeader = ws_xml_get_soap_header(doc);
	srcHeader = ws_xml_get_soap_header(rqstDoc);

	srcNode = ws_xml_get_child(srcHeader, 0, XML_NS_ADDRESSING,
			     WSA_REPLY_TO);
	wsman_epr_from_request_to_response(dstHeader, srcNode);

	if (action != NULL) {
		ws_xml_add_child(dstHeader, XML_NS_ADDRESSING, WSA_ACTION,
				 action);
	} else {
		if ((srcNode = ws_xml_get_child(srcHeader, 0, XML_NS_ADDRESSING,
				      WSA_ACTION)) != NULL) {
			if ((action = ws_xml_get_node_text(srcNode)) != NULL) {
				size_t len = strlen(action) + sizeof(WSFW_RESPONSE_STR) + 2;
				char *tmp = (char *) u_malloc(sizeof(char) * len);
				if (tmp && action) {
					sprintf(tmp, "%s%s", action, WSFW_RESPONSE_STR);
					ws_xml_add_child(dstHeader, XML_NS_ADDRESSING,
							 WSA_ACTION, tmp);
					u_free(tmp);
				}
			}
		}
	}

	if ((srcNode = ws_xml_get_child(srcHeader, 0, XML_NS_ADDRESSING,
					WSA_MESSAGE_ID)) != NULL) {
		ws_xml_add_child(dstHeader, XML_NS_ADDRESSING, WSA_RELATES_TO,
				 ws_xml_get_node_text(srcNode));
	}
	return doc;
}

/**
 * Check Identify Request
 * @param buf Message buffer
 * @return 1 if true, 0 if not
 */
int wsman_check_identify(WsmanMessage * msg)
{
	int ret = 0;
	WsXmlDocH doc = ws_xml_read_memory( u_buf_ptr(msg->request),
					   u_buf_len(msg->request), msg->charset,  0);

	if (doc == NULL) {
		return 0;
	}
	if (wsman_is_identify_request(doc)) {
		ret = 1;
	}
	ws_xml_destroy_doc(doc);
	return ret;
}

/**
 * Buid Inbound Envelope
 * @param buf Message buffer
 * @return XML document with Envelope
 */
WsXmlDocH wsman_build_inbound_envelope(WsmanMessage * msg)
{
	WsXmlDocH doc = ws_xml_read_memory( u_buf_ptr(msg->request),
					   u_buf_len(msg->request), msg->charset,  0);

	if (doc == NULL) {
		wsman_set_fault(msg, WSA_INVALID_MESSAGE_INFORMATION_HEADER, 0, NULL);
		return NULL;
	}
	if (wsman_is_identify_request(doc)) {
		wsman_set_message_flags(msg, FLAG_IDENTIFY_REQUEST);
	}
	wsman_is_valid_envelope(msg, doc);
	return doc;
}

/**
 * Get SOAP header value
 * @param fw SOAP Framework handle
 * @param doc XML document
 * @param nsUri Namespace URI
 * @param name Header element name
 * @return Header value
 */
char *wsman_get_soap_header_value( WsXmlDocH doc, const char *nsUri, const char *name)
{
	char *retVal = NULL;
	WsXmlNodeH node = wsman_get_soap_header_element( doc, nsUri, name);

	if (node != NULL)
		retVal = u_str_clone(ws_xml_get_node_text(node));

	return retVal;
}


/**
 * Get SOAP Header
 * @param doc XML document
 * @param nsUri Namespace URI
 * @param name Header element name
 * @return XML node
 */
WsXmlNodeH
wsman_get_soap_header_element(WsXmlDocH doc, const char *nsUri, const char *name)
{
	WsXmlNodeH node = ws_xml_get_soap_header(doc);
	if (node && name) {
		node = ws_xml_find_in_tree(node, nsUri, name, 1);
	}
	return node;
}


/**
 * Build SOAP Fault
 * @param soapNsUri SOAP Namespace URI
 * @param faultNsUri Fault Namespace URI
 * @param code Fault code
 * @param subCode Fault Subcode
 * @param reason Fault Reson
 * @param detail Fault Details
 * @return Fault XML document
 */
WsXmlDocH
wsman_build_soap_fault(const char *soapNsUri, const char *faultNsUri,
		       const char *code, const char *subCode, const char *reason,
		       const char *detail)
{
	WsXmlDocH doc;

	if (faultNsUri == NULL)
		faultNsUri = soapNsUri;

	if ((doc = ws_xml_create_doc( soapNsUri, SOAP_ENVELOPE)) != NULL) {
		WsXmlNodeH node, root, fault, body;
		root = ws_xml_get_doc_root(doc);
		body = ws_xml_add_child(root, soapNsUri, SOAP_BODY, NULL);

		ws_xml_define_ns(root, soapNsUri, NULL, 0);
		ws_xml_define_ns(root, XML_NS_ADDRESSING, NULL, 0);
		ws_xml_define_ns(root, XML_NS_XML_NAMESPACES, NULL, 0);
		if (strcmp(soapNsUri, faultNsUri) != 0)
			ws_xml_define_ns(root, faultNsUri, NULL, 0);
		if (body
		    && (fault = ws_xml_add_child(body, soapNsUri, SOAP_FAULT,
					 NULL))) {
			if (code != NULL
			    && (node = ws_xml_add_child(fault, soapNsUri,
						 SOAP_CODE,
						 NULL)) != NULL) {
				ws_xml_add_qname_child(node, soapNsUri,
						       SOAP_VALUE,
						       soapNsUri, code);

				if (subCode != NULL
				    &&
				    (node = ws_xml_add_child(node, soapNsUri,
						      SOAP_SUBCODE,
						      NULL)) != NULL) {
					ws_xml_add_qname_child(node,
							       soapNsUri,
							       SOAP_VALUE,
							       faultNsUri,
							       subCode);
				}
			}
			if (reason && (node = ws_xml_add_child(fault, soapNsUri,
						 SOAP_REASON, NULL))) {
				node = ws_xml_add_child(node, soapNsUri,
						     SOAP_TEXT, reason);
				ws_xml_add_node_attr(node,
						     XML_NS_XML_NAMESPACES,
						     SOAP_LANG, "en");
			}
			if (detail) {
				ws_xml_add_child(fault, soapNsUri, SOAP_DETAIL, detail);
			}
		}
	}
	return doc;
}




/**
 * Check if Envelope is valid
 * @param  msg Message data
 * @param doc XML document
 * @return 1 if envelope is valid, 0 if not
 */
int wsman_is_valid_envelope(WsmanMessage * msg, WsXmlDocH doc)
{
	int retval = 1;
	char *soapNsUri;
	WsXmlNodeH header;
	WsXmlNodeH root = ws_xml_get_doc_root(doc);

	if (strcmp(SOAP_ENVELOPE, ws_xml_get_node_local_name(root)) != 0) {
		wsman_set_fault(msg,
				WSA_INVALID_MESSAGE_INFORMATION_HEADER, 0,
				"No Envelope");
		retval = 0;
		debug("no envelope");
		goto cleanup;
	}
	soapNsUri = ws_xml_get_node_name_ns(root);
	if (strcmp(soapNsUri, XML_NS_SOAP_1_2) != 0) {
		wsman_set_fault(msg, SOAP_FAULT_VERSION_MISMATCH, 0, NULL);
		retval = 0;
		debug("version mismatch");
		goto cleanup;
	}
	if (ws_xml_get_soap_body(doc) == NULL) {
		wsman_set_fault(msg,
				WSA_INVALID_MESSAGE_INFORMATION_HEADER, 0,
				"No Body");
		retval = 0;
		debug("no body");
		goto cleanup;
	}
	header = ws_xml_get_soap_header(doc);
	if (!header) {
		wsman_set_fault(msg,
				WSA_INVALID_MESSAGE_INFORMATION_HEADER, 0,
				"No Header");
		retval = 0;
		debug("no header");
		goto cleanup;
	} else {
		if (!wsman_is_identify_request(doc) && !wsman_is_event_related_request(doc)) {
			WsXmlNodeH resource_uri =
			    ws_xml_get_child(header, 0,
					     XML_NS_WS_MAN,
					     WSM_RESOURCE_URI);
			WsXmlNodeH action = ws_xml_get_child(header, 0,
							     XML_NS_ADDRESSING,
							     WSA_ACTION);
			WsXmlNodeH reply = ws_xml_get_child(header, 0,
							    XML_NS_ADDRESSING,
							    WSA_REPLY_TO);
			WsXmlNodeH to = ws_xml_get_child(header, 0,
							 XML_NS_ADDRESSING,
							 WSA_TO);
			if (!resource_uri) {
				wsman_set_fault(msg,
						WSA_DESTINATION_UNREACHABLE,
						WSMAN_DETAIL_INVALID_RESOURCEURI,
						NULL);
				retval = 0;
				debug("no wsman:ResourceURI");
				goto cleanup;
			}
			if (!action) {
				wsman_set_fault(msg,
						WSA_ACTION_NOT_SUPPORTED,
						0, NULL);
				retval = 0;
				debug("no wsa:Action");
				goto cleanup;
			}
			if (!reply) {
				wsman_set_fault(msg,
						WSA_MESSAGE_INFORMATION_HEADER_REQUIRED,
						0, NULL);
				retval = 0;
				debug("no wsa:ReplyTo");
				goto cleanup;
			}
			if (!to) {
				wsman_set_fault(msg,
						WSA_DESTINATION_UNREACHABLE,
						0, NULL);
				retval = 0;
				debug("no wsa:To");
				goto cleanup;
			}
		}
	}
      cleanup:
	return retval;
}


/**
 * Check if Envelope is valid
 * @param  msg Message data
 * @param doc XML document
 * @return 1 if envelope is valid, 0 if not
 */
int wsman_is_valid_xml_envelope(WsXmlDocH doc)
{
	int retval = 1;
	char *soapNsUri;
	WsXmlNodeH root = ws_xml_get_doc_root(doc);

	if (strcmp(SOAP_ENVELOPE, ws_xml_get_node_local_name(root)) != 0) {
		retval = 0;
		goto cleanup;
	}
	soapNsUri = ws_xml_get_node_name_ns(root);
	if (strcmp(soapNsUri, XML_NS_SOAP_1_2) != 0) {
		retval = 0;
		goto cleanup;
	}
	if (ws_xml_get_soap_body(doc) == NULL) {
		retval = 0;
		goto cleanup;
	}
      cleanup:
	return retval;
}


/**
 * Create a Fault
 * @param rqstDoc Request document (Envelope)
 * @param code Fault code
 * @param subCodeNs Namespace of sub code
 * @param subCode Sub code
 * @param lang Language for Reason section
 * @param reason Fault Reason
 * @param addDetailProc Callback for details
 * @param addDetailProcData Pointer to callback data
 * @return XML document of the fault
 */
WsXmlDocH
wsman_create_fault_envelope(WsXmlDocH rqstDoc,
			    const char *code,
			    const char *subCodeNs,
			    const char *subCode,
			    const char *fault_action,
			    const char *lang, const char *reason, const char *faultDetail)
{
	WsXmlDocH doc = NULL;
	WsXmlNodeH header, body, fault, codeNode, node;

	char uuidBuf[50];
	char *soapNs;

	if (rqstDoc) {
		doc = wsman_create_response_envelope(rqstDoc, fault_action);
	} else {
		/* FIXME */
		doc = ws_xml_create_envelope();
	}

	if (doc == NULL) {
		return NULL;
	}
	header = ws_xml_get_soap_header(doc);
	body = ws_xml_get_soap_body(doc);
	soapNs = ws_xml_get_node_name_ns(body);
	fault = ws_xml_add_child(body, soapNs, SOAP_FAULT, NULL);
	codeNode = ws_xml_add_child(fault, soapNs, SOAP_CODE, NULL);
	node = ws_xml_add_child(codeNode, soapNs, SOAP_VALUE, NULL);

	ws_xml_set_node_qname_val(node, soapNs, code);

	if (subCode && subCode[0] != 0 ) {
		node =
		    ws_xml_add_child(codeNode, soapNs, SOAP_SUBCODE, NULL);
		node = ws_xml_add_child(node, soapNs, SOAP_VALUE, NULL);
		if (subCodeNs)
			ws_xml_set_node_qname_val(node, subCodeNs,
						  subCode);
		else
			ws_xml_set_node_text(node, subCode);
	}
	if (reason) {
		node = ws_xml_add_child(fault, soapNs, SOAP_REASON, NULL);
		node = ws_xml_add_child(node, soapNs, SOAP_TEXT, NULL);
		ws_xml_set_node_text(node, reason);
		ws_xml_set_node_lang(node, !lang ? "en" : lang);
	}
	if (faultDetail) {
		WsXmlNodeH d =
		    ws_xml_add_child(fault, soapNs, SOAP_DETAIL, NULL);
		node =
		    ws_xml_add_child_format(d, XML_NS_WS_MAN,
					    SOAP_FAULT_DETAIL, "%s/%s",
					    XML_NS_WSMAN_FAULT_DETAIL,
					    faultDetail);
	}
	generate_uuid(uuidBuf, sizeof(uuidBuf), 0);
	ws_xml_add_child(header, XML_NS_ADDRESSING, WSA_MESSAGE_ID,
			 uuidBuf);

	return doc;
}

static int interpretxpath(char **xpath)
{
	return 1;
}

int wsman_parse_enum_request(WsContextH cntx,
		WsEnumerateInfo * enumInfo)
{
	filter_t *filter = NULL;
	WsXmlNodeH node;
	WsXmlDocH doc = cntx->indoc;
	if (!doc)
		return 0;

	node = ws_xml_get_soap_body(doc);
	if (node && (node = ws_xml_get_child(node, 0,
					XML_NS_ENUMERATION,
					WSENUM_ENUMERATE))) {

		WsXmlNodeH opt = ws_xml_get_child(node, 0, XML_NS_WS_MAN,
				WSM_ENUM_MODE);
		/* Enumeration mode */
		if (opt) {
			char *text = ws_xml_get_node_text(opt);
			if (text != NULL) {
				if (strcmp(text, WSM_ENUM_EPR) == 0)
					enumInfo->flags |= WSMAN_ENUMINFO_EPR;
				else if (strcmp(text, WSM_ENUM_OBJ_AND_EPR) == 0)
					enumInfo->flags |= WSMAN_ENUMINFO_OBJEPR;
			}
		}

		/* Polymorphism */
		opt = ws_xml_get_child(node, 0, XML_NS_CIM_BINDING,
				WSMB_POLYMORPHISM_MODE);
		if (opt) {
			char *mode = ws_xml_get_node_text(opt);
			if (strcmp(mode, WSMB_EXCLUDE_SUBCLASS_PROP) == 0) {
				enumInfo->flags |= WSMAN_ENUMINFO_POLY_EXCLUDE;
			} else if (strcmp(mode, WSMB_INCLUDE_SUBCLASS_PROP) == 0) {
				enumInfo->flags |= WSMAN_ENUMINFO_POLY_INCLUDE;
			} else if (strcmp(mode, WSMB_NONE) == 0) {
				enumInfo->flags |= WSMAN_ENUMINFO_POLY_NONE;
			}
		} else {
			enumInfo->flags |= WSMAN_ENUMINFO_POLY_INCLUDE;
		}

		/* Enum Optimization ?
		 *  wsen:Enum/wsman:Optimize
		 *  wsen:Enum/wsman:MaxElements <optional>
		 */
		opt = ws_xml_get_child(node, 0, XML_NS_WS_MAN,
				WSM_OPTIMIZE_ENUM);
		if (opt) {
			WsXmlNodeH max = ws_xml_get_child(node, 0,
					XML_NS_WS_MAN,
					WSM_MAX_ELEMENTS);
			enumInfo->flags |= WSMAN_ENUMINFO_OPT;
			if (max) {
				char *text = ws_xml_get_node_text(max);
				if (text != NULL) {
					enumInfo->maxItems = atoi(text);
				}
			} else {
				enumInfo->maxItems = 1;
			}
		}

		/* Filter */
		filter = filter_deserialize(node, XML_NS_WS_MAN);
		enumInfo->filter = filter;
		if(filter) {
			if(strcmp(filter->dialect, WSM_ASSOCIATION_FILTER_DIALECT) == 0) {
				if(filter->assocType == 0)
					enumInfo->flags |= WSMAN_ENUMINFO_ASSOC;
				else
					enumInfo->flags |= WSMAN_ENUMINFO_REF;
			}
			else if(strcmp(filter->dialect, WSM_CQL_FILTER_DIALECT) ==0)
				enumInfo->flags |= WSMAN_ENUMINFO_CQL;
			else if(strcmp(filter->dialect, WSM_WQL_FILTER_DIALECT) == 0)
				enumInfo->flags |= WSMAN_ENUMINFO_WQL;
			else if(strcmp(filter->dialect, WSM_SELECTOR_FILTER_DIALECT) == 0)
				enumInfo->flags |= WSMAN_ENUMINFO_SELECTOR;
			else {
				if(interpretxpath(&filter->query))
					enumInfo->flags |= WSMAN_ENUMINFO_WQL;
				else
					return 0;

			}
		}
	}

	return 1;
}

static int is_existing_filter_epr(WsXmlNodeH node, filter_t **f)
{
	char *uri;
	WsXmlNodeH xmlnode = ws_xml_get_child(node, 0, XML_NS_WS_MAN, WSM_RESOURCE_URI);
	if(xmlnode == NULL)
		return -1;
	uri = ws_xml_get_node_text(xmlnode);
	if(strcmp(uri, CIM_ALL_AVAILABLE_CLASSES) == 0)
		return -1;
	xmlnode = ws_xml_get_child(node, 0, XML_NS_WS_MAN, WSM_SELECTOR_SET);
	if(xmlnode == NULL)
		return -1;
	*f = u_zalloc(sizeof(filter_t));
	return 0;
}

int wsman_parse_credentials(WsXmlDocH doc, WsSubscribeInfo * subsInfo,
		WsmanFaultCodeType *faultcode,
		WsmanFaultDetailType *detailcode)
{
	int i = 0;
	WsXmlNodeH tnode = NULL, snode = NULL, node = NULL, temp = NULL;
	char *value = NULL;
	snode = ws_xml_get_soap_header(doc);
	snode = ws_xml_get_child(snode, 0, XML_NS_TRUST, WST_ISSUEDTOKENS);
	if(snode == NULL) return 0;
	tnode = ws_xml_get_child(snode, i, XML_NS_TRUST, WST_REQUESTSECURITYTOKENRESPONSE);
	while(tnode)
	{
		i++;
		node = ws_xml_get_child(tnode, 0, XML_NS_POLICY, WSP_APPLIESTO);
		if(node) {
			node = ws_xml_get_child(node, 0, XML_NS_ADDRESSING, WSA_EPR);
			if(node) {
				node = ws_xml_get_child(node, 0, XML_NS_ADDRESSING, WSA_ADDRESS);
				if(node)
					if(strcmp(ws_xml_get_node_text(node), subsInfo->epr_notifyto)) {
						*faultcode = WSMAN_INVALID_PARAMETER;
						*detailcode = WSMAN_DETAIL_INVALID_ADDRESS;
						return -1;
					}
			}
		}
		node = ws_xml_get_child(tnode, 0, XML_NS_TRUST, WST_TOKENTYPE);
		value = ws_xml_get_node_text(node);
		if(strcmp(value, WST_USERNAMETOKEN) == 0) {
			node = ws_xml_get_child(tnode, 0, XML_NS_TRUST, WST_REQUESTEDSECURITYTOKEN);
			if(node) {
				node = ws_xml_get_child(node, 0, XML_NS_SE, WSSE_USERNAMETOKEN);
				if(node) {
					temp = ws_xml_get_child(node, 0, XML_NS_SE, WSSE_USERNAME);
					if(temp)
						subsInfo->username = u_strdup(ws_xml_get_node_text(temp));
					temp = ws_xml_get_child(node, 0, XML_NS_SE, WSSE_PASSWORD);
					if(temp)
						subsInfo->password = u_strdup(ws_xml_get_node_text(temp));
				}
			}
			debug("subsInfo->username = %s, subsInfo->password = %s", subsInfo->username, \
				subsInfo->password);
		}
		else if(strcmp(value, WST_CERTIFICATETHUMBPRINT) == 0) {
			node = ws_xml_get_child(tnode, 0, XML_NS_TRUST, WST_REQUESTEDSECURITYTOKEN);
			if(node) {
				node = ws_xml_get_child(node, 0, XML_NS_WS_MAN, WSM_CERTIFICATETHUMBPRINT);
				if(node)
					subsInfo->certificate_thumbprint = u_strdup(ws_xml_get_node_text(node));
			}
		}
		else {
			*faultcode = WSMAN_INVALID_OPTIONS;
			*detailcode = WST_DETAIL_UNSUPPORTED_TOKENTYPE;
			return -1;
		}
		tnode = ws_xml_get_child(snode, i, XML_NS_TRUST, WST_REQUESTSECURITYTOKENRESPONSE);
	}
	return 0;
}

int
wsman_parse_event_request(WsXmlDocH doc, WsSubscribeInfo * subsInfo,
		WsmanFaultCodeType *faultcode,
		WsmanFaultDetailType *detailcode)
{
	WsXmlNodeH node;
        filter_t *wsman_f = NULL;
	filter_t *wse_f = NULL;
	if (!doc)
		return 0;

	node = ws_xml_get_soap_body(doc);
	if (node && (node = ws_xml_get_child(node, 0,
					XML_NS_EVENTING,
					WSEVENT_SUBSCRIBE))) {
	        /* See DSP0226 (WS-Management), Section 10.2.2 Filtering
		 * WS-Management defines wsman:Filter as the filter element to wse:Subscribe
		 * but also allows wse:Filter to be compatible with WS-Eventing implementations
		 * R10.2.2-50, R10.2.2-51 to DSP0226 */

		wsman_f = filter_deserialize(node, XML_NS_WS_MAN);
		wse_f = filter_deserialize(node, XML_NS_EVENTING);
	        if (wsman_f && wse_f) {
	                /* return wse:InvalidMessage if wsman:Filter and wse:Filter are given
			 * see R10.2.2-52 of DSP0226 */
		        *faultcode = WSE_INVALID_MESSAGE;
		        return -1;
		}
	        /* use the wse:Filter variant if wsman:Filter not given */
	        if (!wsman_f)
	                wsman_f = wse_f;
	  
	        subsInfo->filter = wsman_f;      
		if (wsman_f) {
			if (strcmp(wsman_f->dialect, WSM_CQL_FILTER_DIALECT) == 0)
				subsInfo->flags |= WSMAN_SUBSCRIPTION_CQL;
			else if (strcmp(wsman_f->dialect, WSM_WQL_FILTER_DIALECT) == 0)
				subsInfo->flags |= WSMAN_SUBSCRIPTION_WQL;
			else {
				*faultcode = WSE_FILTERING_NOT_SUPPORTED;
			        return -1;
			}
		} else {
			if (is_existing_filter_epr(ws_xml_get_soap_header(doc), &wsman_f)) {
				*faultcode = WSE_FILTERING_NOT_SUPPORTED;
				return -1;
			} else {
				subsInfo->flags |= WSMAN_SUBSCRIPTION_SELECTORSET;
			}
		}
	}

	return 0;
}

/*
 * get option value
 * 
 * !! caller must u_free returned string
 * 
 */

char *
wsman_get_option_set(WsContextH cntx, WsXmlDocH doc,
		const char *op)
{
	char *optval = NULL;
	int index = 0;
	WsXmlNodeH node, option;
	if (doc == NULL) {
		doc = cntx->indoc;
		if (!doc)
			return NULL;
	}

	node = ws_xml_get_soap_header(doc);
	if (node && (node = ws_xml_get_child(node, 0,
					XML_NS_WS_MAN, WSM_OPTION_SET))) {
		while ((option = ws_xml_get_child(node, index++, XML_NS_WS_MAN,
						WSM_OPTION))) {
			char *attrVal = ws_xml_find_attr_value(option, NULL,
					WSM_NAME);
			if (attrVal && strcmp(attrVal, op ) == 0 ) {
				optval = ws_xml_get_node_text(option);
				if (optval[0] == 0)
					optval = "true";
				optval = u_strdup(optval);
				debug("Option: %s=%s", attrVal, optval);
				break;
			}
		}
	}
	return optval;
}


/*
 * Get wsen:Pull/wsen:MaxElements value
 */

int wsman_get_max_elements(WsContextH cntx, WsXmlDocH doc)
{
	int max_elements = 1;
	if (doc == NULL)
		doc = cntx->indoc;

	if (doc) {
		WsXmlNodeH node = ws_xml_get_soap_body(doc);

		if (node && (node = ws_xml_get_child(node, 0, XML_NS_ENUMERATION,
					 WSENUM_PULL))) {
			node = ws_xml_get_child(node, 0, XML_NS_WS_MAN,
					     WSENUM_MAX_ELEMENTS);
			if (node) {
				char *text = ws_xml_get_node_text(node);
				if (text != NULL)
					max_elements = atoi(text);
			}
		}
	} else {
		return 0;
	}
	return max_elements;

}

unsigned long wsman_get_max_envelope_size(WsContextH cntx, WsXmlDocH doc)
{
	unsigned long size = 0;
	WsXmlNodeH header, maxsize;
	char *mu = NULL;
	if (doc == NULL)
		doc = cntx->indoc;
	header = ws_xml_get_soap_header(doc);
	maxsize = ws_xml_get_child(header, 0, XML_NS_WS_MAN,
			     WSM_MAX_ENVELOPE_SIZE);
	mu = ws_xml_find_attr_value(maxsize, XML_NS_SOAP_1_2,
				    SOAP_MUST_UNDERSTAND);
	if (mu != NULL && strcmp(mu, "true") == 0) {
		size = ws_deserialize_uint32(NULL, header,
					     0, XML_NS_WS_MAN,
					     WSM_MAX_ENVELOPE_SIZE);
	}
	return size;
}

char * wsman_get_fragment_string(WsContextH cntx, WsXmlDocH doc)
{
	WsXmlNodeH header, n;
	char *mu = NULL;
	if(doc == NULL)
		doc = cntx->indoc;
	header = ws_xml_get_soap_header(doc);
	n = ws_xml_get_child(header, 0, XML_NS_WS_MAN,
			     WSM_FRAGMENT_TRANSFER);
	if (n != NULL) {
		mu = ws_xml_find_attr_value(n, XML_NS_SOAP_1_2,
					    SOAP_MUST_UNDERSTAND);
		if (mu != NULL && strcmp(mu, "true") == 0) {
			return ws_xml_get_node_text(n);
		}
	}
	return NULL;
}


void wsman_get_fragment_type(char *fragstr, int *fragment_flag, char **element,
	int *index)
{
	char *p, *p1, *p2, *dupstr;
	*fragment_flag = 0;
	*element = NULL;
	*index = 0;
	if(fragstr == NULL) return;
	dupstr = u_strdup(fragstr);
	p = strstr(dupstr, "/text()");
	if(p) {
		*p = '\0';
		*fragment_flag = 2;
		*element = u_strdup(dupstr);
	}
	else {
		if((p1 = strstr(dupstr, "[")) && (p2 = strstr(dupstr, "]"))) {
			*element = u_strndup(dupstr, p1 - dupstr);
			*p2 = '\0';
			*index = atoi(p1+1);
			*fragment_flag = 3;
		}
		else {
			*element = u_strdup(dupstr);
			*fragment_flag = 1;
		}
	}
	u_free(dupstr);
}


char *wsman_get_method_name(WsContextH cntx)
{
	char *m, *method = NULL;
	char *tmp = NULL;
	m = wsman_get_action(cntx, NULL);
	if (m != NULL && m[0] != 0) {
		tmp = strrchr(m, '/');
		if(tmp)
			method = u_strdup(tmp + 1);
		debug("method or action: %s", method);
	}
	return method;
}



char *wsman_get_class_name(WsContextH cntx)
{
	char *className = NULL;
	char *resource_uri = wsman_get_resource_uri(cntx, NULL);
	char *tmp = NULL;
	if(resource_uri) {
		tmp = strrchr(resource_uri, '/');
		if(tmp)
			className = u_strdup(tmp + 1);
	}
	return className;
}




char *
wsman_get_resource_uri(WsContextH cntx, WsXmlDocH doc)
{
	char *val = NULL;
	WsXmlNodeH header, node;

	if (doc == NULL) {
		doc = cntx->indoc;
		if (!doc)
			return NULL;
	}

	header = ws_xml_get_soap_header(doc);
	node = ws_xml_get_child(header, 0, XML_NS_WS_MAN,
				WSM_RESOURCE_URI);
	val = (!node) ? NULL : ws_xml_get_node_text(node);
	return val;
}


/*
 * free list of method arguments
 */

static void
wsman_free_method_list(list_t *list) 
{
	lnode_t *node = list_first(list);

	debug("wsman_free_method_list:");
	while (node) {
		methodarglist_t *node_val = (methodarglist_t *)node->list_data;
		selector_entry *sentry = (selector_entry *)node_val->data;
		debug("freeing list entry key: %s", node_val->key);
		switch (sentry->type) {
			case 0: u_free(sentry->entry.text); break;
			case 1: u_free(sentry->entry.eprp); break;
		}
		u_free(sentry);
		u_free(node_val->key);
		u_free(node_val);
		node->list_data = NULL; // needed to prevent double free
		node = list_next(list, node);
	}
	list_destroy_nodes(list);
	list_destroy(list);
}


/*
 * free hash node with method arguments
 *   called from hash_set_allocator(), hence the dummy argument
 */

static void
wsman_free_method_hnode(hnode_t * n, void *dummy)
{
	if (strcmp(METHOD_ARGS_KEY, (char *)hnode_getkey(n)) == 0) {
		wsman_free_method_list((list_t *)hnode_get(n));
	}
	u_free(n);
}


/*
 * convert xml method args to hash_t
 *
 */

hash_t *
wsman_get_method_args(WsContextH cntx, const char *resource_uri)
{
	char *input = NULL;
	WsXmlDocH doc = cntx->indoc;
	hash_t *h = hash_create(HASHCOUNT_T_MAX, 0, 0);
	hash_set_allocator(h, NULL, wsman_free_method_hnode, NULL);
	if (doc) {
		WsXmlNodeH in_node;
		WsXmlNodeH body = ws_xml_get_soap_body(doc);
		char *mn = wsman_get_method_name(cntx);
		input = u_strdup_printf("%s_INPUT", mn);
		in_node = ws_xml_get_child(body, 0, resource_uri, input);
		if (!in_node) {
			char *xsd = u_strdup_printf("%s.xsd", resource_uri);
			in_node = ws_xml_get_child(body, 0, xsd, input);
			u_free(xsd);
		}
		if (in_node) {
			WsXmlNodeH arg, epr;
			int index = 0;
			list_t *arglist = list_create(LISTCOUNT_T_MAX);
			lnode_t *argnode;
			while ((arg = ws_xml_get_child(in_node, index++, NULL, NULL))) {
				char *key = ws_xml_get_node_local_name(arg);
				selector_entry *sentry = u_malloc(sizeof(*sentry));
				methodarglist_t *nodeval = u_malloc(sizeof(methodarglist_t));
				epr = ws_xml_get_child(arg, 0, XML_NS_ADDRESSING,
					WSA_REFERENCE_PARAMETERS);
				nodeval->key = u_strdup(key);
				nodeval->arraycount = 0;
				argnode = lnode_create(nodeval);
				if (epr) {
					debug("epr: %s", key);
					sentry->type = 1;
					sentry->entry.eprp = epr_deserialize(arg, NULL, NULL, 1); 
					//wsman_get_epr(cntx, arg, key, XML_NS_CIM_CLASS);
				} else {
					debug("text: %s", key);
					sentry->type = 0;
					sentry->entry.text = u_strdup(ws_xml_get_node_text(arg));
				}
				nodeval->data = sentry;
				list_append(arglist, argnode);
			}
			if (!hash_alloc_insert(h, METHOD_ARGS_KEY, arglist)) {
				error("hash_alloc_insert failed");
				wsman_free_method_list(arglist);
			}
		}
		u_free(mn);
		u_free(input);
	} else {
		error("error: xml document is NULL");
	}
	if (!hash_isempty(h))
		return h;

	hash_destroy(h);
	return NULL;
}



hash_t *
wsman_get_selectors_from_epr(WsContextH cntx, WsXmlNodeH epr_node)
{
	WsXmlNodeH selector, node, epr;
	selector_entry *sentry;
	int index = 0;
	hash_t *h = hash_create2(HASHCOUNT_T_MAX, 0, 0);

	node = ws_xml_get_child(epr_node, 0, XML_NS_WS_MAN,
			WSM_SELECTOR_SET);
	if (!node) {
		debug("no SelectorSet defined");
		hash_destroy(h);
		return NULL;
	}
	while ((selector =
		ws_xml_get_child(node, index++, XML_NS_WS_MAN,  WSM_SELECTOR))) {
		char *attrVal =
		    ws_xml_find_attr_value(selector, XML_NS_WS_MAN,
					   WSM_NAME);
		if (attrVal == NULL)
			attrVal = ws_xml_find_attr_value(selector, NULL,
						   WSM_NAME);

		if (attrVal && !hash_lookup(h, attrVal)) {
			sentry = u_malloc(sizeof(*sentry));
			epr = ws_xml_get_child(selector, 0, XML_NS_ADDRESSING,
					WSA_EPR);
			if (epr) {
				debug("epr: %s", attrVal);
				sentry->type = 1;
				sentry->entry.eprp = epr_deserialize(selector, XML_NS_ADDRESSING,
					WSA_EPR, 1);
				if (!hash_alloc_insert(h, attrVal, sentry)) {
					error("hash_alloc_insert failed");
				}
			} else {
				debug("text: %s", attrVal);
				sentry->type = 0;
				sentry->entry.text = ws_xml_get_node_text(selector);
				if (!hash_alloc_insert(h, attrVal,
						sentry)) {
					error("hash_alloc_insert failed");
				}
			}
		}
	}

	if (!hash_isempty(h))
		return h;

	hash_destroy(h);
	return NULL;
}

hash_t *
wsman_get_selector_list(WsContextH cntx, WsXmlDocH doc)
{
	WsXmlNodeH header;
	hash_t *h = NULL;

	if (doc == NULL) {
		doc = cntx->indoc;
		if (!doc)
			return NULL;
	}
	header = ws_xml_get_soap_header(doc);
	if (header) {
		h = wsman_get_selectors_from_epr(cntx, header);
	}
	return h;
}

hash_t *
wsman_get_selector_list_from_filter(WsContextH cntx, WsXmlDocH doc)
{
	WsXmlNodeH body;
	WsXmlNodeH node, assInst, object;

	if (doc == NULL) {
		doc = cntx->indoc;
		if (!doc)
			return NULL;
	}

	body = ws_xml_get_soap_body(doc);
	node = ws_xml_get_child(body, 0, XML_NS_ENUMERATION, WSENUM_ENUMERATE);
	if(!node) {
		debug("no SelectorSet defined. Missing Enumerate");
		return NULL;
	}
	node = ws_xml_get_child(node, 0, XML_NS_WS_MAN, WSENUM_FILTER);
	if(!node) {
		debug("no SelectorSet defined. Missing Filter");
		return NULL;
	}

	assInst = ws_xml_get_child(node, 0, XML_NS_CIM_BINDING, WSMB_ASSOCIATION_INSTANCES);
	if(!assInst) {
		assInst = ws_xml_get_child(node, 0, XML_NS_CIM_BINDING, WSMB_ASSOCIATED_INSTANCES);
		if(!assInst) {
			debug("no SelectorSet defined. Missing AssociationInstances / AssociatedInstances");
			return NULL;
		}
	}

	object = ws_xml_get_child(assInst, 0, XML_NS_CIM_BINDING, WSMB_OBJECT);
	if(!node) {
		debug("no SelectorSet defined. Missing Object");
		return NULL;
	}

	node = ws_xml_get_child(object, 0, XML_NS_ADDRESSING, WSA_REFERENCE_PARAMETERS);
	if(!node) {
		debug("no SelectorSet defined. Missing ReferenceParameters");
		return NULL;
	}

	return  wsman_get_selectors_from_epr(cntx, node);
}


char *
wsman_get_selector(WsContextH cntx,
			 WsXmlDocH doc, const char *name, int index)
{
	char *val = NULL;
	if (doc == NULL)
		doc = cntx->indoc;
	if (doc) {
		WsXmlNodeH header = ws_xml_get_soap_header(doc);
		WsXmlNodeH node = ws_xml_get_child(header, index, XML_NS_WS_MAN,
				     WSM_SELECTOR_SET);

		if (node) {
			WsXmlNodeH selector;
			int index = 0;

			while ((selector = ws_xml_get_child(node, index++,
						 XML_NS_WS_MAN, WSM_SELECTOR))) {
				char *attrVal = ws_xml_find_attr_value(selector,
							   XML_NS_WS_MAN,
							   WSM_NAME);
				if (attrVal == NULL)
					attrVal = ws_xml_find_attr_value(selector, NULL, WSM_NAME);

				if (attrVal && !strcmp(attrVal, name)) {
					val = ws_xml_get_node_text(selector);
					break;
				}
			}
		}
	}
	debug("Selector value for %s: %s", name, val);
	return val;
}

char *wsman_get_action(WsContextH cntx, WsXmlDocH doc)
{
	char *val = NULL;
	if (doc == NULL) {
		doc = cntx->indoc;
	}
	if (doc) {
		WsXmlNodeH header = ws_xml_get_soap_header(doc);
		WsXmlNodeH node = ws_xml_get_child(header, 0, XML_NS_ADDRESSING,
				     WSA_ACTION);
		val = (!node) ? NULL : ws_xml_get_node_text(node);
	}
	return val;
}




void wsman_add_selector(WsXmlNodeH baseNode, const char *name, const char *val)
{
	WsXmlNodeH selector = NULL;
	WsXmlDocH epr = NULL;
	WsXmlNodeH set = ws_xml_get_child(baseNode, 0, XML_NS_WS_MAN,
			WSM_SELECTOR_SET);

	if (val && strstr(val, WSA_EPR)) {
		epr = ws_xml_read_memory(val, strlen(val), NULL, 0);
	}

	if (set || (set = ws_xml_add_child(baseNode,
				XML_NS_WS_MAN, WSM_SELECTOR_SET, NULL))) {
		if (epr) {
			if ((selector = ws_xml_add_child(set, XML_NS_WS_MAN, WSM_SELECTOR,
							NULL))) {
				ws_xml_duplicate_tree(selector, ws_xml_get_doc_root(epr));
				ws_xml_add_node_attr(selector, NULL, WSM_NAME,
						name);
			}
		} else {
			if ((selector = ws_xml_add_child(set, XML_NS_WS_MAN, WSM_SELECTOR,
							val))) {
				ws_xml_add_node_attr(selector, NULL, WSM_NAME,
						name);
			}
		}
	}
	return;
}



void
wsman_set_estimated_total(WsXmlDocH in_doc,
			  WsXmlDocH out_doc, WsEnumerateInfo * enumInfo)
{
	WsXmlNodeH header = ws_xml_get_soap_header(in_doc);
	if (ws_xml_get_child(header, 0,
			     XML_NS_WS_MAN, WSM_REQUEST_TOTAL) != NULL) {
		if (out_doc) {
			WsXmlNodeH response_header =
			    ws_xml_get_soap_header(out_doc);
			if (enumInfo->totalItems >= 0)
				ws_xml_add_child_format(response_header,
							XML_NS_WS_MAN,
							WSM_TOTAL_ESTIMATE,
							"%d",
							enumInfo->
							totalItems);
		}
	}
	return;
}



void wsman_add_namespace_as_selector(WsXmlDocH doc, const char *_namespace)
{
	WsXmlNodeH header = ws_xml_get_soap_header(doc);
	wsman_add_selector(header, CIM_NAMESPACE_SELECTOR, _namespace);

	return;
}


void wsman_add_fragement_for_header(WsXmlDocH indoc, WsXmlDocH outdoc)
{
	WsXmlNodeH inheader, outheader;
	WsXmlNodeH fragmentnode;
	inheader = ws_xml_get_soap_header(indoc);
	fragmentnode = ws_xml_get_child(inheader, 0, XML_NS_WS_MAN, WSM_FRAGMENT_TRANSFER);
	if(fragmentnode == NULL)
		return;
	outheader = ws_xml_get_soap_header(outdoc);
	ws_xml_duplicate_tree(outheader, fragmentnode);
}


int wsman_is_identify_request(WsXmlDocH doc)
{
	WsXmlNodeH node = ws_xml_get_soap_body(doc);
	node = ws_xml_get_child(node, 0, XML_NS_WSMAN_ID, WSMID_IDENTIFY);
	if (node)
		return 1;
	else
		return 0;
}

int wsman_is_event_related_request(WsXmlDocH doc)
{
	WsXmlNodeH node = ws_xml_get_soap_header(doc);
	char *action = NULL;
	node = ws_xml_get_child(node, 0, XML_NS_ADDRESSING, WSA_ACTION);
	action = ws_xml_get_node_text(node);
	if (!action)
		return 0;

	if(strcmp(action, EVT_ACTION_UNSUBSCRIBE) ==0 || strcmp(action, EVT_ACTION_RENEW) ==0
		|| strcmp(action, EVT_ACTION_PULL) == 0)
		return 1;
	else
		return 0;
}

int time_expired(unsigned long lt)
{
	struct timeval tv;
	if(lt == 0) return 0; // 0 means it never expires
	gettimeofday(&tv, NULL);
	if(!(tv.tv_sec< lt))
		return 1;
	else
		return 0;
}

void
wsman_set_expiretime(WsXmlNodeH  node,
                    unsigned long * expire,
                    WsmanFaultCodeType *fault_code)
{
	struct timeval  tv;
	time_t timeout;
	char *text;
	XML_DATETIME tmx;
	gettimeofday(&tv, NULL);
	text = ws_xml_get_node_text(node);
	*fault_code = WSMAN_DETAIL_OK;
	if (text == NULL) {
		*fault_code = WSEN_INVALID_EXPIRATION_TIME;
		return;
	}
	debug("wsen:Expires = %s", text);
	if (text[0] == 'P') {
		//  xml duration
		if (ws_deserialize_duration(text, &timeout)) {
			*fault_code = WSEN_INVALID_EXPIRATION_TIME;
			goto DONE;
		}
		*expire = tv.tv_sec + timeout;
		goto DONE;
	}

	// timeout is XML datetime type
	if (ws_deserialize_datetime(text, &tmx)) {
		*fault_code = WSEN_UNSUPPORTED_EXPIRATION_TYPE;
		goto DONE;
	}
	timeout = mktime(&(tmx.tm)) + 60*tmx.tz_min;
	*expire = timeout;
DONE:
	return;
}

WsXmlDocH
wsman_create_doc(const char *rootname)
{
	return ws_xml_create_doc(NULL, (char *)rootname);
}

void
wsman_destroy_doc(WsXmlDocH doc)
{
	ws_xml_destroy_doc(doc);
}

