/*******************************************************************************
 * 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;
}

/*
 * Interpret query as XPath
 * 
 */

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

/*
 * Parse enumeration request
 * @return: 0 for error, set WsmanStatus accordingly
 * 
 */
int wsman_parse_enum_request(WsContextH cntx,
		WsEnumerateInfo * enumInfo, WsmanStatus *status)
{
	filter_t *filter = NULL;
	WsXmlNodeH node;
	WsXmlDocH doc = cntx->indoc;
	if (!doc) {
                status->fault_code = WSMAN_INVALID_PARAMETER;
                status->fault_detail_code = WSMAN_DETAIL_INVALID_VALUE;
		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_XPATH;
				else {
                                        status->fault_code = WSEN_CANNOT_PROCESS_FILTER;
                                        status->fault_detail_code = WSMAN_DETAIL_NOT_SUPPORTED;
					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_ENUMERATION,
					     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);
}

