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

#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
#ifdef HAVE_PTHREAD_H
#include <pthread.h>
#endif
#ifndef WIN32
#include <dlfcn.h>
#endif
#include "u/libu.h"
#if 0
#include "wsman-faults.h"
#include "wsman-xml.h"
#include "wsman-plugins.h"
#include "wsman-server.h"
#include "wsman-dispatcher.h"
#endif
#include "wsman-soap.h"
#include "wsman-soap-envelope.h"
#include "wsman-server.h"
#include "wsman-xml.h"
#include "wsman-dispatcher.h"
#include "wsman-event-pool.h"
#include "wsman-subscription-repository.h"


WsManListenerH *wsman_dispatch_list_new()
{
	WsManListenerH *list =
	    (WsManListenerH *) u_malloc(sizeof(WsManListenerH));
	return list;
}


static int wsman_server_verify_plugin(WsDispatchInterfaceInfo *ifcinfo)
{
	debug("Plugin '%s', version: %s", (ifcinfo->displayName), (ifcinfo->version) );
	if (strcmp (OPENWSMAN_PLUGIN_API_VERSION, ifcinfo->version) == 0) {
		return 1;
	}
	return 0;
}


WsContextH wsman_init_plugins(WsManListenerH * listener)
{
	list_t *list = list_create(LISTCOUNT_T_MAX);
	lnode_t *node;
	WsContextH cntx = NULL;
	WsDispatchInterfaceInfo *ifcinfo = NULL;
	wsman_plugins_load(listener);
	node = list_first(listener->plugins);

	while (node) {
		WsManPlugin *p = (WsManPlugin *) node->list_data;
	        if (p->init == NULL
		    || p->init(p->p_handle, &(p->data)) == 0 ) {
		    error ("Plugin %s fails init()", p->p_name);
		    error("invalid plugin");
		    goto next_plugin;
		}
	      
                p->ifc = (WsDispatchInterfaceInfo *)
                          malloc(sizeof(WsDispatchInterfaceInfo));
		ifcinfo = p->ifc;
	        ifcinfo->extraData = p->data;
		p->set_config = dlsym(p->p_handle, "set_config");

		if (listener->config && p->set_config) {
			p->set_config(p->p_handle, listener->config);
		} else {
			debug("no configuration available for plugin: %s", p->p_name);
		}

		if (p->get_endpoints)
			p->get_endpoints(p->p_handle, p->ifc);

		if (p->ifc && wsman_server_verify_plugin(ifcinfo)) {
			lnode_t *i = lnode_create(p->ifc);
			list_append(list, i);
		} else {
			error ("Plugin '%s' is not compatible with version of the software or plugin is invalid", p->p_name);
			error("invalid plugin");
		}
next_plugin:
		node = list_next(listener->plugins, node);
	}
	cntx = ws_create_runtime(list);
	return cntx;
}

#ifdef ENABLE_EVENTING_SUPPORT
SubsRepositoryOpSetH
wsman_init_subscription_repository(WsContextH cntx, char *uri)
{
	SoapH soap = ws_context_get_runtime(cntx);
	if(soap) {
		soap->subscriptionOpSet = wsman_get_subsrepos_opset();
		if(uri) {
			soap->uri_subsRepository = u_strdup(uri);
			soap->subscriptionOpSet->init_subscription(uri, NULL);
		}
	}
	return soap->subscriptionOpSet;
}

EventPoolOpSetH 
wsman_init_event_pool(WsContextH cntx, void*data)
{
	SoapH soap = ws_context_get_runtime(cntx);
	if(soap) {
		soap->eventpoolOpSet = wsman_get_eventpool_opset();
		soap->eventpoolOpSet->init(NULL);
	}
	return soap->eventpoolOpSet;
}

int wsman_clean_subsrepository(SoapH soap, SubsRepositoryEntryH entry)
{
	int retVal = 0;
	WsXmlDocH doc = ws_xml_read_memory( (char *)entry->strdoc, entry->len, "UTF-8", 0);
	unsigned long expire;
	WsmanFaultCodeType fault_code;
	if(doc) {
		WsXmlNodeH node = ws_xml_get_soap_body(doc);
		if(node) {
			node = ws_xml_get_child(node, 0, XML_NS_EVENTING, WSEVENT_SUBSCRIBE);
			node = ws_xml_get_child(node, 0, XML_NS_EVENTING, WSEVENT_EXPIRES);
			if(node == NULL) { //No specified expiration, delete it
				debug("subscription %s deleted from the repository", entry->uuid);
				soap->subscriptionOpSet->delete_subscription(soap->uri_subsRepository, entry->uuid+5);
				retVal = 1;
			}
			else {
				wsman_set_expiretime(node, &expire, &fault_code);
				if(fault_code == WSMAN_RC_OK) {
					if(time_expired(expire)) {
						debug("subscription %s deleted from the repository", entry->uuid);
						soap->subscriptionOpSet->delete_subscription(soap->uri_subsRepository, entry->uuid+5);
						retVal = 1;
					}
				}
			}
		}
		ws_xml_destroy_doc(doc);
	}
	return retVal;
}

void wsman_repos_notification_dispatcher(WsContextH cntx, SubsRepositoryEntryH entry, int subsNum)
{
	WsmanMessage *wsman_msg = wsman_soap_message_new();
	if(wsman_msg == NULL) return;
	unsigned char *strdoc = entry->strdoc;
	u_buf_construct(wsman_msg->request, strdoc, entry->len, entry->len);
	dispatch_inbound_call(cntx->soap, wsman_msg, NULL);
	wsman_soap_message_destroy(wsman_msg);
	if(list_count(cntx->subscriptionMemList) > subsNum) {
		lnode_t *node = list_last(cntx->subscriptionMemList);
		WsSubscribeInfo *subs = (WsSubscribeInfo *)node->list_data;
		//Update UUID in the memory
		strncpy(subs->subsId, entry->uuid+5, EUIDLEN);
	}
}

void *wsman_notification_manager(void *arg)
{
	WsContextH cntx = (WsContextH) arg;
	int r;
	pthread_mutex_t mutex;
	pthread_cond_t cond;
	struct timespec timespec;
	struct timeval tv;

	if ((r = pthread_cond_init(&cond, NULL)) != 0) {
		error("pthread_cond_init failed = %d", r);
		return NULL;
	}
	if ((r = pthread_mutex_init(&mutex, NULL)) != 0) {
		error("pthread_mutex_init failed = %d", r);
		return NULL;
	}

	while (continue_working) {
		pthread_mutex_lock(&mutex);
		gettimeofday(&tv, NULL);
		timespec.tv_sec = tv.tv_sec + 1;
		timespec.tv_nsec = tv.tv_usec * 1000;
		pthread_cond_timedwait(&cond, &mutex, &timespec);
		pthread_mutex_unlock(&mutex);
		wse_notification_manager(cntx);
	}
	return NULL;	
}
#endif
void *wsman_server_auxiliary_loop_thread(void *arg)
{
	WsContextH cntx = (WsContextH) arg;
	int r;
	pthread_mutex_t mutex;
	pthread_cond_t cond;
	struct timespec timespec;
	struct timeval tv;

	if ((r = pthread_cond_init(&cond, NULL)) != 0) {
		error("pthread_cond_init failed = %d", r);
		return NULL;
	}
	if ((r = pthread_mutex_init(&mutex, NULL)) != 0) {
		error("pthread_mutex_init failed = %d", r);
		return NULL;
	}

	while (continue_working) {
		pthread_mutex_lock(&mutex);
		gettimeofday(&tv, NULL);
		timespec.tv_sec = tv.tv_sec + 1;
		timespec.tv_nsec = tv.tv_usec * 1000;
		pthread_cond_timedwait(&cond, &mutex, &timespec);
		pthread_mutex_unlock(&mutex);

		wsman_timeouts_manager(cntx, NULL);
#ifdef ENABLE_EVENTING_SUPPORT
		wsman_heartbeat_generator(cntx, NULL);
#endif
	}
	return NULL;
}


