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

#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-dispatcher.h"
#include "wsman-xml-serialize.h"
#include "wsman-faults.h"
#include "wsman-soap-envelope.h"


/**
 * @defgroup Dispatcher Dispatcher
 * @brief SOAP Dispatcher
 *
 * @{
 */

struct __MuHeaderInfo {
	char *ns;
	char *name;
};

static int is_mu_header(WsXmlNodeH header)
{
	int i;
	char *name, *ns;
	static struct __MuHeaderInfo s_Info[] = {
		{XML_NS_ADDRESSING, WSA_TO},
		{XML_NS_ADDRESSING, WSA_MESSAGE_ID},
		{XML_NS_ADDRESSING, WSA_RELATES_TO},
		{XML_NS_ADDRESSING, WSA_ACTION},
		{XML_NS_ADDRESSING, WSA_REPLY_TO},
		{XML_NS_ADDRESSING, WSA_FROM},
		{XML_NS_WS_MAN, WSM_RESOURCE_URI},
		{XML_NS_WS_MAN, WSM_SELECTOR_SET},
		{XML_NS_WS_MAN, WSM_MAX_ENVELOPE_SIZE},
		{XML_NS_WS_MAN, WSM_OPERATION_TIMEOUT},
		{XML_NS_WS_MAN, WSM_FRAGMENT_TRANSFER},
		{XML_NS_TRUST, WST_ISSUEDTOKENS},
		{NULL, NULL}
	};

	name = ws_xml_get_node_local_name(header);
	ns = ws_xml_get_node_name_ns(header);

	for (i = 0; s_Info[i].name != NULL; i++) {
		if ((ns == NULL && s_Info[i].ns == NULL) ||
		    (ns != NULL && s_Info[i].ns != NULL &&
		     !strcmp(ns, s_Info[i].ns))) {
			if (!strcmp(name, s_Info[i].name))
				return 1;
		}
	}
	debug("mustUnderstand: %s:%s", !ns ? "null" : ns, name ? name : "NULL");
	return 0;
}



static void
generate_op_fault(op_t * op,
			WsmanFaultCodeType faultCode,
			WsmanFaultDetailType faultDetail)
{
	if (op->out_doc) {
		ws_xml_destroy_doc(op->out_doc);
		op->out_doc = NULL;
	}
	if (op->in_doc == NULL) {
		return;
	}
	op->out_doc = wsman_generate_fault(op->in_doc, faultCode, faultDetail, NULL);
	return;
}

static void
generate_notunderstood_fault(op_t * op,
				   WsXmlNodeH notUnderstoodHeader)
{
	WsXmlNodeH child;
	WsXmlNodeH header;

	if (op->in_doc == NULL)
		return;
	generate_op_fault(op, SOAP_FAULT_MUSTUNDERSTAND, 0);

	if (op->out_doc != NULL) {
		header = ws_xml_get_soap_header(op->out_doc);
		if (header) {
			child = ws_xml_add_child(header, XML_NS_SOAP_1_2,
					     "NotUnderstood", NULL);
			ws_xml_add_qname_attr(child, NULL, "qname",
					      ws_xml_get_node_name_ns
					      (notUnderstoodHeader),
					      ws_xml_get_node_local_name
					      (notUnderstoodHeader));
		}
	} else {
		error("cant generate fault");
	}
	return;
}


static int check_for_duplicate_selectors(op_t * op)
{
	WsXmlNodeH header, node, selector;
	int retval = 0, index = 0;
	hash_t *h;

	header = wsman_get_soap_header_element( op->in_doc, NULL, NULL);
	if ((node = ws_xml_get_child(header, 0, XML_NS_WS_MAN,
			      WSM_SELECTOR_SET)) == NULL) {
		// No selectors
		return 0;
	}
	h = hash_create(HASHCOUNT_T_MAX, 0, 0);
	if (h == NULL) {
		generate_op_fault(op, WSMAN_INTERNAL_ERROR,
					OWSMAN_NO_DETAILS);
		error("could not create hash");
		return 1;
	}

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

		if (hash_lookup(h, attrVal)) {
			generate_op_fault(op, WSMAN_INVALID_SELECTORS,
						WSMAN_DETAIL_DUPLICATE_SELECTORS);
			debug("Selector %s duplicated", attrVal);
			retval = 1;
			break;
		}

		if (!hash_alloc_insert(h, attrVal,
				       ws_xml_get_node_text(selector))) {
			generate_op_fault(op, WSMAN_INTERNAL_ERROR,
						OWSMAN_NO_DETAILS);
			retval = 1;
			error("hash_alloc_insert failed");
			break;
		}
	}
	hash_free(h);
	return retval;
}

static int validate_control_headers(op_t * op)
{
	unsigned long size = 0;
	time_t duration;
	WsXmlNodeH header, child, maxsize;
	char *mu = NULL;

	header = wsman_get_soap_header_element( op->in_doc,  NULL, NULL);
	maxsize = ws_xml_get_child(header, 0, XML_NS_WS_MAN,
			     WSM_MAX_ENVELOPE_SIZE);
        /* DSP0226, v1.2
         * R13.1-3: A service should not send a SOAP Envelope with more than 32,767 octets unless the
         * client has specified a wsman:MaxEnvelopeSize header that overrides this limit
         */
        if (maxsize == NULL) { /* no wsman:MaxEnvelopeSize specified */
          op->maxsize = WSMAN_MAX_ENVELOPE_SIZE;
        }
        else {
          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);
                /* wsman:MaxEnvelopeSize too small ? */
		if (size < WSMAN_MINIMAL_ENVELOPE_SIZE_REQUEST) {
			generate_op_fault(op, WSMAN_ENCODING_LIMIT,
						WSMAN_DETAIL_MINIMUM_ENVELOPE_LIMIT);
			return 0;
		}
		op->maxsize = size;
	}
	child = ws_xml_get_child(header, 0,
				 XML_NS_WS_MAN, WSM_OPERATION_TIMEOUT);
	if (child != NULL) {
		char *text = ws_xml_get_node_text(child);
		char *nsUri = ws_xml_get_node_name_ns(header);
		if (text == NULL ||
		    ws_deserialize_duration(text, &duration)) {
			generate_op_fault(op,
						WSA_INVALID_MESSAGE_INFORMATION_HEADER,
						WSMAN_DETAIL_OPERATION_TIMEOUT);
			return 0;
		}
		if (duration <= 0) {
			generate_op_fault(op, WSMAN_TIMED_OUT, 0);
			return 0;
		}
		op->expires = duration;
		// Not supported now
		if (ws_xml_find_attr_bool
		    (child, nsUri, SOAP_MUST_UNDERSTAND)) {
			generate_op_fault(op,
						WSMAN_UNSUPPORTED_FEATURE,
						WSMAN_DETAIL_OPERATION_TIMEOUT);
			return 0;
		}
	}
	return 1;
}


static WsXmlNodeH
validate_mustunderstand_headers(op_t * op)
{
	WsXmlNodeH child = NULL, header = NULL;
	int i;
	char *nsUri;

	header = wsman_get_soap_header_element(op->in_doc, NULL, NULL);
	nsUri = ws_xml_get_node_name_ns(header);

	for (i = 0;(child = ws_xml_get_child(header, i, NULL, NULL)) != NULL; i++) {
		if (ws_xml_find_attr_bool(child, nsUri, SOAP_MUST_UNDERSTAND)) {
			if (!is_mu_header(child)) {
				break;
			}
		}
	}

	if (child != NULL) {
		debug("Mustunderstand Fault: %s", ws_xml_get_node_text(child));
	}
	return child;
}

static int
check_supported_dialect(const char *dialect)
{
	if (strcmp(dialect, WSM_ASSOCIATION_FILTER_DIALECT) == 0)
		return 0;
	else if (strcmp(dialect, WSM_XPATH_FILTER_DIALECT) == 0)
		return 0;
	else if (strcmp(dialect, WSM_WQL_FILTER_DIALECT) == 0)
		return 0;
	else if (strcmp(dialect, WSM_CQL_FILTER_DIALECT) == 0)
		return 0;
	else if (strcmp(dialect, WSM_SELECTOR_FILTER_DIALECT) == 0)
		return 0;
	return 1;
}


/**
 * Check for duplicate Message ID
 * @param op operation
 * @return status
 */
static int
check_unsupported_features(op_t * op)
{
	WsXmlNodeH enumurate;
	WsXmlNodeH subscribe;
	WsXmlNodeH header = wsman_get_soap_header_element( op->in_doc, NULL, NULL);
	WsXmlNodeH body = ws_xml_get_soap_body(op->in_doc);
	int retVal = 0;
	WsXmlNodeH n, m, k;
	char *resource_uri = NULL, *mu = NULL;
	WsXmlAttrH attr = NULL;


	n = ws_xml_get_child(header, 0, XML_NS_ADDRESSING, WSA_FAULT_TO);
	if (n != NULL) {
		debug("wsa:FaultTo is not supported");
		retVal = 1;
		generate_op_fault(op, WSMAN_UNSUPPORTED_FEATURE,
					WSMAN_DETAIL_ADDRESSING_MODE);
		goto DONE;
	}
	n = ws_xml_get_child(header, 0, XML_NS_WS_MAN, WSM_LOCALE);
	if (n != NULL) {
		debug("Locale header found");
		mu = ws_xml_find_attr_value(n, XML_NS_SOAP_1_2,
					    SOAP_MUST_UNDERSTAND);
		if (mu != NULL && strcmp(mu, "true") == 0) {
			retVal = 1;
			generate_op_fault(op,
						WSMAN_UNSUPPORTED_FEATURE,
						WSMAN_DETAIL_LOCALE);
			goto DONE;
		}
	}
#if 0
	n = ws_xml_get_child(header, 0, XML_NS_WS_MAN,
			     WSM_FRAGMENT_TRANSFER);
	if (n != NULL) {
		debug("FragmentTransfer header found");
		mu = ws_xml_find_attr_value(n, XML_NS_SOAP_1_2,
					    SOAP_MUST_UNDERSTAND);
		if (mu != NULL && strcmp(mu, "true") == 0) {
			retVal = 1;
			generate_op_fault(op,
						WSMAN_UNSUPPORTED_FEATURE,
						WSMAN_DETAIL_FRAGMENT_LEVEL_ACCESS);
			goto DONE;
		}
	}
#endif
	enumurate = ws_xml_get_child(body, 0, XML_NS_ENUMERATION,
			     WSENUM_ENUMERATE);
	if (enumurate) {

	n = ws_xml_get_child(enumurate, 0, XML_NS_ENUMERATION,
			     WSENUM_END_TO);
	if (n != NULL) {
		retVal = 1;
		generate_op_fault(op, WSMAN_UNSUPPORTED_FEATURE,
					WSMAN_DETAIL_ADDRESSING_MODE);
	}
	n = ws_xml_get_child(enumurate, 0, XML_NS_ENUMERATION,
			     WSENUM_FILTER);
	m = ws_xml_get_child(enumurate, 0, XML_NS_WS_MAN, WSM_FILTER);
	if (n != NULL && m != NULL) {
		retVal = 1;
		generate_op_fault(op, WSEN_CANNOT_PROCESS_FILTER, 0);
		goto DONE;
	} else if (n || m) {
		char *dia = NULL;
		if (n) {
			dia = ws_xml_find_attr_value(n, NULL, WSM_DIALECT);
		} else if (m) {
			dia = ws_xml_find_attr_value(m, NULL, WSM_DIALECT);
		}
		if (dia)
			retVal = check_supported_dialect(dia);
		else
			retVal = check_supported_dialect (WSM_XPATH_FILTER_DIALECT);

		if (retVal) {
			retVal = 1;
			generate_op_fault(op, WSEN_FILTER_DIALECT_REQUESTED_UNAVAILABLE,
						0);
			goto DONE;
			}
	}
	k = ws_xml_get_child(header, 0, XML_NS_WS_MAN, WSM_RESOURCE_URI);
	if (k)
		resource_uri = ws_xml_get_node_text(k);
	if (resource_uri &&
	    (strcmp(resource_uri, CIM_ALL_AVAILABLE_CLASSES) == 0)) {
		if (!n && !m) {
			retVal = 1;
			generate_op_fault(op, WSMAN_UNSUPPORTED_FEATURE,
						WSMAN_DETAIL_FILTERING_REQUIRED);
			goto DONE;
		}

	}
	}
	subscribe = ws_xml_get_child(body, 0, XML_NS_EVENTING, WSEVENT_SUBSCRIBE);
	if(subscribe) {
	/*	n = ws_xml_get_child(subscribe, 0, XML_NS_EVENTING, WSEVENT_ENDTO);
		if(n) {
			retVal = 1;
			generate_op_fault(op, WSMAN_UNSUPPORTED_FEATURE,
					WSMAN_DETAIL_ADDRESSING_MODE);
			goto DONE;
		}
	*/	n = ws_xml_get_child(subscribe, 0, XML_NS_EVENTING, WSEVENT_DELIVERY);
		if(n == NULL) {
			retVal = 1;
			generate_op_fault(op, WSE_INVALID_MESSAGE, 0);
			goto DONE;
		}
		attr = ws_xml_find_node_attr(n, NULL,WSEVENT_DELIVERY_MODE);
		if(attr) {
			mu = ws_xml_get_attr_value(attr);
			if (strcasecmp(mu, WSEVENT_DELIVERY_MODE_PUSH) &&
				strcasecmp(mu, WSEVENT_DELIVERY_MODE_PUSHWITHACK) &&
				strcasecmp(mu, WSEVENT_DELIVERY_MODE_EVENTS) &&
				strcasecmp(mu, WSEVENT_DELIVERY_MODE_PULL)) {
				debug("Unsupported delivery mode : %s",ws_xml_get_attr_value(attr));
				retVal = 1;
				generate_op_fault(op, WSE_DELIVERY_MODE_REQUESTED_UNAVAILABLE, 0);
				goto DONE;
			}
		}
		m = ws_xml_get_child(n, 0, XML_NS_WS_MAN, WSM_CONNECTIONRETRY);
		if(m) {
			retVal = 1;
			generate_op_fault(op, WSMAN_UNSUPPORTED_FEATURE, WSMAN_DETAIL_DELIVERY_RETRIES);
			goto DONE;
		}
	}
DONE:
	return retVal;
}



/**
 * Check for duplicate Message ID
 * @param op operation
 * @return status
 */
static int wsman_is_duplicate_message_id(op_t * op)
{
	WsXmlNodeH header = wsman_get_soap_header_element(op->in_doc, NULL, NULL);
	int retVal = 0;
	SoapH soap;
	WsXmlNodeH msgIdNode;
	soap = op->dispatch->soap;

	msgIdNode = ws_xml_get_child(header, 0, XML_NS_ADDRESSING, WSA_MESSAGE_ID);
	if (msgIdNode != NULL) {
		lnode_t *node;
		char *msgId;
		msgId = ws_xml_get_node_text(msgIdNode);
		if (msgId[0] == 0 ) {
			generate_op_fault(op, WSA_INVALID_MESSAGE_INFORMATION_HEADER, 0 );
			debug("MessageId missing");
			return 1;
		}
		debug("Checking Message ID: %s", msgId);
		u_lock(soap);

		if (soap->processedMsgIdList == NULL) {
			soap->processedMsgIdList = list_create(LISTCOUNT_T_MAX);
		}
#ifndef IGNORE_DUPLICATE_ID
		node = list_first(soap->processedMsgIdList);
		while (node != NULL) {
			if (!strcmp(msgId, (char *) node->list_data)) {
				debug("Duplicate Message ID: %s", msgId);
				retVal = 1;
				generate_op_fault(op, WSA_INVALID_MESSAGE_INFORMATION_HEADER,
							WSA_DETAIL_DUPLICATE_MESSAGE_ID);
				break;
			}
			node = list_next(soap->processedMsgIdList, node);
		}
#endif


		if (!retVal) {
			while (list_count(soap->processedMsgIdList) >= PROCESSED_MSG_ID_MAX_SIZE) {
				node = list_del_first(soap->processedMsgIdList);
				u_free(node->list_data);
				u_free(node);
			}

			node = lnode_create(NULL);
			if (node) {
				node->list_data = u_str_clone(msgId);
				if (node->list_data == NULL) {
					u_free(node);
				} else {
					list_append(soap->processedMsgIdList, node);
				}
			}
		}
		u_unlock(soap);
	} else if (!wsman_is_identify_request(op->in_doc)) {
		generate_op_fault(op, WSA_MESSAGE_INFORMATION_HEADER_REQUIRED, 0);
		debug("No MessageId Header found");
		return 1;
	}

	return retVal;
}

int
soap_add_filter(SoapH soap,
		SoapServiceCallback callbackProc,
		void *callbackData, int inbound)
{
	callback_t *entry = NULL;

	if (soap) {
		if (!inbound) {
			if (!soap->outboundFilterList)
				soap->outboundFilterList = list_create(LISTCOUNT_T_MAX);
			entry = make_callback_entry(callbackProc, callbackData, soap->outboundFilterList);
		} else {
			if (!soap->inboundFilterList)
				soap->inboundFilterList = list_create(LISTCOUNT_T_MAX);
			entry = make_callback_entry(callbackProc, callbackData, soap->inboundFilterList);
		}
	}
	if (entry == NULL)
		return 0;
	else
		return 1;
}


int
outbound_control_header_filter(SoapOpH opHandle,
			       void *data, void *opaqueData)
{
	op_t *op = (op_t *)opHandle;
	WsmanMessage *msg = wsman_get_msg_from_op(opHandle);
	if(check_envelope_size(op->out_doc, op->maxsize, msg->charset)) {
		debug("****should not go here");
		generate_op_fault(op, WSMAN_ENCODING_LIMIT,
						WSMAN_DETAIL_SERVICE_ENVELOPE_LIMIT);
	}
	return 0;
}

int
outbound_addressing_filter(SoapOpH opHandle, void *data, void *opaqueData)
{
	WsXmlDocH in_doc = soap_get_op_doc(opHandle, 1);
	WsXmlDocH out_doc = soap_get_op_doc(opHandle, 0);

	WsXmlNodeH outHeaders = wsman_get_soap_header_element(out_doc, NULL, NULL);

	if (!outHeaders) {
		return 0;
	}
	if (ws_xml_get_child(outHeaders, 0, XML_NS_ADDRESSING,  WSA_MESSAGE_ID) == NULL &&
	    !wsman_is_identify_request(in_doc)) {
		char uuidBuf[100];
		generate_uuid(uuidBuf, sizeof(uuidBuf), 0);
		ws_xml_add_child(outHeaders, XML_NS_ADDRESSING,	 WSA_MESSAGE_ID, uuidBuf);
		debug("Adding message id: %s", uuidBuf);
	}
	if (in_doc != NULL) {
		WsXmlNodeH inMsgIdNode;
		inMsgIdNode = wsman_get_soap_header_element(in_doc,XML_NS_ADDRESSING,
							    WSA_MESSAGE_ID);
		if (inMsgIdNode != NULL &&
		    !ws_xml_get_child(outHeaders, 0, XML_NS_ADDRESSING, WSA_RELATES_TO)) {
			ws_xml_add_child(outHeaders, XML_NS_ADDRESSING, WSA_RELATES_TO,
					 ws_xml_get_node_text(inMsgIdNode));
		}
	}

	return 0;
}



static int
process_filter_chain(op_t *op, list_t *list, void *opaqueData)
{
	int retVal = 0;
	callback_t *filter = NULL;
	if (list != NULL) {
		filter = (callback_t *) list_first(list);
		while (!retVal && filter != NULL) {
			retVal = filter->proc((SoapOpH) op, filter->node.list_data,
					 opaqueData);
			filter = (callback_t *) list_next(list, &filter->node);
		}
	}
	return retVal;
}

/**
 * Process Filters
 * @param op SOAP operation
 * @param inbound Direction of message, 0 for outbound  and 1 for inbound.
 * @return 0 on success, 1 on error.
 **/
static int process_filters(op_t * op, int inbound, void *opaqueData)
{
	int retVal = 0;
	list_t *list;

	debug("Processing Filters: %s", (!inbound) ? "outbound" : "inbound");
	if (!(op->dispatch->flags & SOAP_SKIP_DEF_FILTERS)) {
		list = inbound ? op->dispatch->soap->inboundFilterList :
		    op->dispatch->soap->outboundFilterList;
		retVal = process_filter_chain(op, list, opaqueData);
	}
	if (retVal) {
		debug("process_filter_chain returned 1 for DEF FILTERS");
		return 1;
	}
	list = inbound ? op->dispatch->inboundFilterList :
	    op->dispatch->outboundFilterList;
	retVal = process_filter_chain(op, list, opaqueData);

	if (retVal) {
		debug("process_filter_chain returned 1");
		return 1;
	}

	if (inbound) {
		WsXmlNodeH notUnderstoodHeader;
		if (wsman_is_duplicate_message_id(op)) {
			debug("wsman_is_duplicate_message_id");
			return 1;
		}
		if (check_unsupported_features(op)) {
			debug("check_unsupported_features");
			return 1;
		}
		if ((notUnderstoodHeader =
		     validate_mustunderstand_headers(op)) != 0) {
			generate_notunderstood_fault(op, notUnderstoodHeader);
			debug("validate_mustunderstand_headers");
			return 1;
		}
		if (!validate_control_headers(op)) {
			debug("validate_control_headers");
			return 1;
		}
		if (check_for_duplicate_selectors(op)) {
			debug("check_for_duplicate_selectors");
			return 1;
		}
	}
	return 0;
}



static void
dispatcher_create_fault(SoapH soap, WsmanMessage * msg, WsXmlDocH in_doc)
{
	char *buf = NULL;
	int len;
	if (!soap)
		return;

	if (wsman_fault_occured(msg)) {
		wsman_generate_fault_buffer(in_doc,
					    msg->charset,
					    msg->status.fault_code,
					    msg->status.fault_detail_code,
					    msg->status.fault_msg,
					    &buf, &len);
		u_buf_set(msg->response, buf, len);
		u_free(buf);
		msg->http_code = wsman_find_httpcode_for_fault_code(
						msg->status.
					    fault_code);
	}
	return;
}


static int
process_inbound_operation(op_t * op, WsmanMessage * msg, void *opaqueData)
{
	int retVal = 1;
	char *buf = NULL;
	int len;

	msg->http_code = WSMAN_STATUS_OK;
	op->out_doc = NULL;
	if (op->dispatch->serviceCallback == NULL) {
		wsman_set_fault(msg, WSA_ACTION_NOT_SUPPORTED,
				OWSMAN_NO_DETAILS, NULL);
		debug("op service callback is null");
		goto GENERATE_FAULT;
	}

	if (process_filters(op, 1, opaqueData)) {
		if (op->out_doc == NULL) {
			error("doc is null");
			wsman_set_fault(msg, WSMAN_INTERNAL_ERROR,
					OWSMAN_NO_DETAILS, NULL);
			goto GENERATE_FAULT;
		}
		if (wsman_is_fault_envelope(op->out_doc)) {
			msg->http_code =
			    wsman_find_httpcode_for_value(op->out_doc);
		} else {
			error("not fault envelope");
		}

		ws_xml_dump_memory_enc(op->out_doc, &buf, &len, msg->charset);
		u_buf_set(msg->response, buf, len);
		ws_xml_destroy_doc(op->out_doc);
		op->out_doc = NULL;
		u_free(buf);
		return 1;
	}


	retVal = op->dispatch->serviceCallback((SoapOpH) op,
					  op->dispatch->serviceData,
					  opaqueData);
	if (op->out_doc == NULL) {
		// XXX (correct fault?)
		wsman_set_fault(msg, WSA_DESTINATION_UNREACHABLE,
				WSMAN_DETAIL_INVALID_RESOURCEURI, NULL);
		error("output doc is null");
		goto GENERATE_FAULT;
	}

	process_filters(op, 0, opaqueData);
	if (op->out_doc == NULL) {
		error("doc is null");
		wsman_set_fault(msg, WSMAN_INTERNAL_ERROR,
				OWSMAN_NO_DETAILS, NULL);
		goto GENERATE_FAULT;
	}
	if (wsman_is_fault_envelope(op->out_doc)) {
		msg->http_code =
		    wsman_find_httpcode_for_value(op->out_doc);
	}
	else {
		wsman_add_fragement_for_header(op->in_doc, op->out_doc);
	}
	ws_xml_dump_memory_enc(op->out_doc, &buf, &len, msg->charset);
	u_buf_set(msg->response, buf, len);
	ws_xml_destroy_doc(op->out_doc);
	op->out_doc = NULL;
	u_free(buf);
	return 0;

      GENERATE_FAULT:
	return retVal;
}


static SoapDispatchH get_dispatch_entry(SoapH soap, WsXmlDocH doc)
{
	SoapDispatchH dispatch = NULL;
	if (soap->dispatcherProc) {
		dispatch = soap->dispatcherProc(soap->cntx,
						soap->dispatcherData, doc);
	}
	if (dispatch == NULL) {
		error("Dispatcher Error");
	} else {
		dispatch->usageCount++;
	}
	return dispatch;
}

void
dispatch_inbound_call(SoapH soap, WsmanMessage * msg, void *opaqueData)
{
	op_t *op = NULL;
	WsXmlDocH in_doc = wsman_build_inbound_envelope( msg);
	SoapDispatchH dispatch = NULL;
	debug("Inbound call...");
#if 0
        /* debug incoming message */
        int size;
        char *buf;
        ws_xml_dump_memory_node_tree_enc( ws_xml_get_soap_body(in_doc), &buf, &size, "UTF-8" );  
	debug(buf);
#endif
	if (wsman_fault_occured(msg)) {
		error("document is null");
		goto DONE;
	}
	dispatch = get_dispatch_entry(soap, in_doc);

	if (dispatch == NULL) {
		wsman_set_fault(msg, WSA_DESTINATION_UNREACHABLE,
				WSMAN_DETAIL_INVALID_RESOURCEURI, NULL);
		debug("dispatch == NULL");
		goto DONE;
	}
	op = create_op_entry(soap, dispatch, msg);
	if (op == NULL) {
		wsman_set_fault(msg, WSA_DESTINATION_UNREACHABLE,
				WSMAN_DETAIL_INVALID_RESOURCEURI, NULL);
		destroy_dispatch_entry(dispatch);
		debug("op entry == NULL");
		goto DONE;
	}
	op->in_doc = in_doc;
	process_inbound_operation(op, msg, opaqueData);
DONE:
	dispatcher_create_fault(soap, msg, in_doc);
	destroy_op_entry(op);
	ws_xml_destroy_doc(in_doc);
	debug("Inbound call completed");
	return;
}


static char *wsman_dispatcher_match_ns(WsDispatchInterfaceInfo * r,
		char *uri)
{
	char *ns = NULL;
	lnode_t *node = NULL;
	if (r->namespaces == NULL) {
		return NULL;
	}
	if (!uri)
		return NULL;

	node = list_first(r->namespaces);
	while (node) {
		WsSupportedNamespaces *sns =
		    (WsSupportedNamespaces *) node->list_data;
		debug("namespace: %s", sns->ns);
		if (sns->ns != NULL && strstr(uri, sns->ns)) {
			ns = u_strdup(sns->ns);
			break;
		}
		node = list_next(r->namespaces, node);
	}
	return ns;
}


WsEndPointRelease
wsman_get_release_endpoint(WsContextH cntx, WsXmlDocH doc)
{
	WsManDispatcherInfo *dispInfo =
	    (WsManDispatcherInfo *) cntx->soap->dispatcherData;
	lnode_t *node = NULL;
	WsDispatchInterfaceInfo *r = NULL;
	WsDispatchEndPointInfo *ep = NULL;
	char *ptr = ENUM_ACTION_RELEASE, *ns = NULL, *uri = NULL;
	int i;

	if (dispInfo->interfaces) {
		node = list_first((list_t *) dispInfo->interfaces);
	}
	uri = wsman_get_resource_uri(cntx, doc);

	while (node != NULL) {
		WsDispatchInterfaceInfo *ifc =
		    (WsDispatchInterfaceInfo *) node->list_data;
		if (ifc->wsmanResourceUri == NULL &&
		    (ns = wsman_dispatcher_match_ns(ifc, uri))) {
			r = ifc;
			break;
		}
		if (ifc->wsmanResourceUri &&
		    !strcmp(uri, ifc->wsmanResourceUri)) {
			r = ifc;
			break;
		}
		node = list_next((list_t *) dispInfo->interfaces, node);
	}
	if (r == NULL) {
		u_free(ns);
		return NULL;
	}
	/*
	 * See if the action is part of the namespace which means that
	 * we are dealing with a custom action
	 */
	if (ns != NULL) {
		size_t len = strlen(ns);
		if (!strncmp(ptr, ns, len) && ptr[len] == '/') {
			ptr += len + 1;
		}
	}
	for (i = 0; r->endPoints[i].serviceEndPoint != NULL; i++) {
		if (r->endPoints[i].inAction != NULL &&
		    !strcmp(ptr, r->endPoints[i].inAction)) {
			ep = &r->endPoints[i];
			break;
		}
	}
	u_free(ns);

	if (ep == NULL) {
		debug("no ep");
		return NULL;
	}
	debug("Release endpoint: %p", ep->serviceEndPoint);
	return (WsEndPointRelease) ep->serviceEndPoint;
}

SoapDispatchH wsman_dispatcher(WsContextH cntx, void *data, WsXmlDocH doc)
{
	SoapDispatchH disp = NULL;
	char *uri = NULL, *action;
	WsManDispatcherInfo *dispInfo = (WsManDispatcherInfo *) data;
	WsDispatchEndPointInfo *ep = NULL;
	WsDispatchEndPointInfo *ep_custom = NULL;

	WsXmlDocH notdoc = NULL;

#ifdef ENABLE_EVENTING_SUPPORT
	WsXmlNodeH nodedoc = NULL;
#endif
	int i;
	char *ns = NULL;

	WsDispatchInterfaceInfo *r = NULL;
	lnode_t *node = list_first((list_t *) dispInfo->interfaces);

	if (doc == NULL) {
		error("doc is null");
		u_free(data);
		goto cleanup;
	}
	uri = wsman_get_resource_uri(cntx, doc);
	action = wsman_get_action(cntx, doc);
#ifdef ENABLE_EVENTING_SUPPORT
	if(wsman_is_event_related_request(doc)) {
		WsXmlNodeH temp = ws_xml_get_child( ws_xml_get_soap_header(doc), 0,
			XML_NS_EVENTING, WSEVENT_IDENTIFIER);
		char *uuid = ws_xml_get_node_text(temp);
		debug("Request uuid: %s", uuid ? uuid : "NULL");
		if(uuid) {
			lnode_t *t = list_first(cntx->subscriptionMemList);
			while(t != NULL) {
				WsSubscribeInfo *subsInfo = (WsSubscribeInfo *)t->list_data;
				if(!strcmp(uuid+5, subsInfo->subsId)) {
					uri = subsInfo->uri;
					break;
				}
				else
					t = list_next(cntx->subscriptionMemList, t);
			}
			if(t == NULL) {
				unsigned char *buf = NULL;
				int len;
				if(cntx->soap->subscriptionOpSet->get_subscription(cntx->soap->uri_subsRepository,
					uuid+5, &buf, &len) == 0) {
					notdoc = ws_xml_read_memory( (char *)buf, len, "UTF-8", 0);
					if(notdoc) {
						nodedoc = ws_xml_get_soap_header(notdoc);
						if(nodedoc) {
							nodedoc = ws_xml_get_child(nodedoc, 0, XML_NS_WS_MAN, WSM_RESOURCE_URI);
							if(nodedoc) {
								uri = ws_xml_get_node_text(nodedoc);
							}
						}
					}
					u_free(buf);
				}
			}
		}
	}
#endif
	debug("uri: %s, action: %s", uri ? uri : "NULL", action ? action : "NULL");
	if ((!uri || !action) && !wsman_is_identify_request(doc)) {
		goto cleanup;
	}
	while (node != NULL) {

		WsDispatchInterfaceInfo *ifc = (WsDispatchInterfaceInfo *) node->list_data;
		if (wsman_is_identify_request(doc)) {
			if ((ns = wsman_dispatcher_match_ns(ifc,
						       XML_NS_WSMAN_ID))) {
				r = ifc;
				break;
			}
			debug("ns did not match");
		}
		/*
		 * If Resource URI is null then most likely we are dealing
		 * with  a generic plugin supporting a namespace with
		 * multiple Resource URIs (e.g. CIM)
		 **/
		else if (ifc->wsmanResourceUri == NULL &&
			 (ns = wsman_dispatcher_match_ns(ifc, uri))) {
			r = ifc;
			break;
		} else if (ifc->wsmanResourceUri &&
			   !strcmp(uri, ifc->wsmanResourceUri)) {
			r = ifc;
			break;
		}
		node = list_next((list_t *) dispInfo->interfaces, node);
	}


	if (wsman_is_identify_request(doc) && r != NULL) {
		ep = &r->endPoints[0];
	} else if (r != NULL) {
		char *ptr = action;
		/*
		 * See if the action is part of the namespace which means that
		 * we are dealing with a custom action
		 */
		if (ns != NULL) {
			size_t len = strlen(ns);
			if (!strncmp(action, ns, len) &&
			    action[len] == '/')
				ptr = &action[len + 1];
		}
		for (i = 0; r->endPoints[i].serviceEndPoint != NULL; i++) {
			if (r->endPoints[i].inAction != NULL &&
			    !strcmp(ptr, r->endPoints[i].inAction)) {
				ep = &r->endPoints[i];
				break;
			} else if (r->endPoints[i].inAction == NULL) {
				/*
				 * Just store it for later
				 * in case no match is found for above condition
				 */
				ep_custom = &r->endPoints[i];
			}
		}
	}
	ws_remove_context_val(cntx, WSM_RESOURCE_URI);

	if (ep != NULL) {
		for (i = 0; i < dispInfo->mapCount; i++) {
			if (dispInfo->map[i].ep == ep) {
				disp = dispInfo->map[i].disp;
				break;
			}
		}
	} else if (ep_custom != NULL) {
		for (i = 0; i < dispInfo->mapCount; i++) {
			if (dispInfo->map[i].ep == ep_custom) {
				disp = dispInfo->map[i].disp;
				break;
			}
		}
	}

cleanup:
	if(notdoc)
		ws_xml_destroy_doc(notdoc);
	if (ns)
		u_free(ns);
	return disp;
}


/*
 * Create dispatch Entry
 *
 * @param soap Soap Framework Handle
 * @param inboundAction Inbound Action
 * @param outboundAction Outbound Action
 * @param role Role
 * @param proc Call back processor
 * @param data Callback Data
 * @param flags Flags
 * @return Dispatch Entry
 */
static SoapDispatchH
create_dispatch_entry(SoapH soap,
		      char *inboundAction,
		      char *outboundAction,
		      char *role,
		      SoapServiceCallback proc,
		      void *data, unsigned long flags)
{

	SoapDispatchH entry = wsman_dispatch_entry_new();
	if (entry) {
		entry->soap = soap;
		entry->flags = flags;
		entry->inboundAction = u_str_clone(inboundAction);
		entry->outboundAction = u_str_clone(outboundAction);
		entry->serviceCallback = proc;
		entry->serviceData = data;
		entry->usageCount = 1;
	}
	return entry;
}



/*
 * Create Dispatch Entry
 * @param soap Soap handle
 * @param inboundAction Inbound Action
 * @param outboundAction Outbound Action (optional)
 * @param role Role (reserved, must be NULL)
 * @param callbackProc Callback processor
 * @param callbackData Callback data
 * @param flags Flags
 * @return Dispatch Handle
 */
SoapDispatchH wsman_dispatch_create(SoapH soap,
		char *inboundAction, char *outboundAction,	//optional
		char *role,	//reserved, must be NULL
		SoapServiceCallback callbackProc,
		void *callbackData,
		unsigned long flags)
{

	SoapDispatchH disp = NULL;
	if (soap && role == NULL) {
		disp = create_dispatch_entry(soap, inboundAction,
					  outboundAction, role,
					  callbackProc, callbackData,
					  flags);
	}
	return disp;
}

/*
 * Start Dispatcher
 */
void wsman_dispatch_start(SoapDispatchH disp)
{
	list_t *displist = NULL;
	if (disp) {
		displist = disp->soap->dispatchList;
		if (displist != NULL || ( displist = list_create(LISTCOUNT_T_MAX) )) {
			list_append(displist, &(disp)->node);
		}
	}
}


SoapDispatchH wsman_dispatch_entry_new(void)
{
	return (SoapDispatchH) u_zalloc(sizeof(struct __dispatch_t));
}



/** @} */
