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

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

#include <stdio.h>
#include <stdlib.h>

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#include <string.h>

#include <errno.h>
#include <assert.h>

#include "u/libu.h"
#include "wsmand-daemon.h"
#include "wsman-server-api.h"

#ifdef PACKAGE_SUBSCRIPTION_DIR
#define DEFAULT_SUBSCRIPTION_REPOSITORY PACKAGE_SUBSCRIPTION_DIR
#else
#define DEFAULT_SUBSCRIPTION_REPOSITORY "/var/lib/openwsman/subscriptions"
#endif
#ifdef __APPLE__
#define DEFAULT_BASIC_AUTH  "libwsman_file_auth.dylib"
#else
#define DEFAULT_BASIC_AUTH  "libwsman_file_auth.so"
#endif

//int facility = LOG_DAEMON;

static const char **wsmand_argv = NULL;


static int server_port = -1;
static int server_ssl_port = -1;
static int use_ipv4 = 1;
#ifdef ENABLE_IPV6
static int use_ipv6 = 0;
#endif
static int use_digest = 0;
static char *ssl_key_file = NULL;
static char *service_path = DEFAULT_SERVICE_PATH;
static char *ssl_cert_file = NULL;
static char *ssl_disabled_protocols = NULL;
static char *ssl_cipher_list = NULL;
static char *pid_file = DEFAULT_PID_PATH;
static char *uri_subscription_repository = DEFAULT_SUBSCRIPTION_REPOSITORY;
static int daemon_flag = 0;
static int no_plugin_flag = 0;
static int use_ssl = 0;
static int debug_level = -1;
static int foreground_debug = 0;
static int syslog_level = -1;
static char *log_location = NULL;
static char *digest_password_file = NULL;
static char *basic_password_file = NULL;
static char *custom_anon_identify_file = NULL;
static char *custom_identify_file = NULL;
static char *basic_authenticator_arg = NULL;
static char *basic_authenticator = DEFAULT_BASIC_AUTH;
static int max_threads = 1;
static unsigned long enumIdleTimeout = 100;
static char *thread_stack_size="0";
static int max_connections_per_thread=20;

static char *config_file = NULL;



int wsmand_parse_options(int argc, char **argv)
{
	char retval;
	u_option_context_t *opt_ctx;
	u_error_t *error = NULL;
	char *version = NULL;

	u_option_entry_t options[] = {
#if 0
		{"no-plugins", 'n', U_OPTION_ARG_NONE, &no_plugin_flag,
		 "Do not load any plugins", NULL},
#endif
		{"ssl", 'S', U_OPTION_ARG_NONE, &use_ssl,
		 "Use SSL port", NULL},
		{"version", 'q', U_OPTION_ARG_NONE, &version,
		 "Display application version", NULL},
		{"debug", 'd', U_OPTION_ARG_NONE, &foreground_debug,
		 "Start daemon in foreground and turn on debugging", NULL},
		{"syslog", 's', U_OPTION_ARG_INT, &syslog_level,
		 "Set the verbosity of syslog output.", "0-6"},
		{"enum-idle-timeout", 'e', U_OPTION_ARG_INT,
		 &enumIdleTimeout,
		 "Enumeration Idle timeout in secs", "default 100"},
		{"config-file", 'c', U_OPTION_ARG_STRING, &config_file,
		 "Alternate configuration file", "<file>"},
		{"pid-file", 'p', U_OPTION_ARG_STRING, &pid_file,
		 "PID file", "<file>"},
		{"subscription-repository-location", 'r',  U_OPTION_ARG_STRING, &uri_subscription_repository,
		"Subscription Repository Location", "<uri>"},
		{NULL}
	};

	wsmand_argv = (const char **) argv;
	opt_ctx = u_option_context_new("WS-Management Server");
	u_option_context_set_ignore_unknown_options(opt_ctx, FALSE);
	u_option_context_add_main_entries(opt_ctx, options, "wsman");
	retval = u_option_context_parse(opt_ctx, &argc, &argv, &error);
	if (error) {
		if (error->message)
			printf("%s\n", error->message);
		retval = 0;
	}
	if (version) {
		fprintf(stdout, PACKAGE_NAME " " PACKAGE_VERSION "\n\n");
		exit(0);
	}
	
	u_error_free(error);
	u_option_context_free(opt_ctx);
	return retval;
}

const char **wsmand_options_get_argv(void)
{
	return wsmand_argv;
}

int wsmand_read_config(dictionary * ini)
{
	if (!iniparser_find_entry(ini, "server")) {
		return 0;
	}

	server_port = iniparser_getint(ini, "server:port", 5985);
	server_ssl_port = iniparser_getint(ini, "server:ssl_port", 5986);
	debug_level = iniparser_getint(ini, "server:debug_level", 0);
	enumIdleTimeout =
	    (unsigned long) iniparser_getint(ini,
					     "server:enum_idle_timeout",
					     100);
	service_path =
	    iniparser_getstring(ini, "server:service_path", "/wsman");
	ssl_key_file = iniparser_getstr(ini, "server:ssl_key_file");
	ssl_cert_file = iniparser_getstr(ini, "server:ssl_cert_file");
        ssl_disabled_protocols = iniparser_getstr(ini, "server:ssl_disabled_protocols");
        ssl_cipher_list = iniparser_getstr(ini, "server:ssl_cipher_list");
	use_ipv4 = iniparser_getboolean(ini, "server:ipv4", 1);
#ifdef ENABLE_IPV6
        use_ipv6 = iniparser_getboolean(ini, "server:ipv6", 1);
        if (! (use_ipv4 || use_ipv6)) {
		fprintf(stderr, "Neither ipv4 nor ipv6 is enabled in openwsman.conf !\n");
		exit(1);
	}
#endif
	use_digest = iniparser_getboolean(ini, "server:use_digest", 0);
	digest_password_file = iniparser_getstr(ini,
						"server:digest_password_file");
	basic_password_file =
	    iniparser_getstr(ini, "server:basic_password_file");
	custom_identify_file =
	    iniparser_getstr(ini, "server:identify_file");
	custom_anon_identify_file =
	    iniparser_getstr(ini, "server:anon_identify_file");
	basic_authenticator =
	    iniparser_getstr(ini, "server:basic_authenticator");
	basic_authenticator_arg =
	    iniparser_getstr(ini, "server:basic_authenticator_arg");
	log_location = iniparser_getstr(ini, "server:log_location");
	max_threads = iniparser_getint(ini, "server:max_threads", 0);
	uri_subscription_repository = iniparser_getstring(ini, "server:subs_repository", DEFAULT_SUBSCRIPTION_REPOSITORY);
        max_connections_per_thread = iniparser_getint(ini, "server:max_connections_per_thread", iniparser_getint(ini, "server:max_connextions_per_thread", 20));
        thread_stack_size = iniparser_getstring(ini, "server:thread_stack_size", "0");
#ifdef ENABLE_EVENTING_SUPPORT
	wsman_server_set_subscription_repos(uri_subscription_repository);
#endif
	return 1;
}

int wsmand_options_get_max_connections_per_thread(void)
{
        return max_connections_per_thread;
}

unsigned int wsmand_options_get_thread_stack_size(void)
{
        errno=0;
        unsigned int stack_size = strtoul(thread_stack_size,NULL,10);
        if(errno){
                debug("failed to convert string to unsigned int : %s", strerror(errno));
                return 0;
        }
        return stack_size;
}

const char *wsmand_options_get_config_file(void)
{
	char *p;
	if (config_file == NULL) {
		config_file = DEFAULT_CONFIG_FILE;
	}
	if (config_file != NULL && !u_path_is_absolute(config_file)) {
		char cwd[PATH_MAX];
		if ((p = getcwd(cwd, PATH_MAX)) != NULL)
			config_file =
			    u_strdup_printf("%s/%s", cwd, config_file);
	}
	return config_file;
}

char *wsmand_options_get_digest_password_file(void)
{
	return digest_password_file;
}

char *wsmand_options_get_basic_password_file(void)
{
	return basic_password_file;
}

char *wsmand_options_get_identify_file(void)
{
	return custom_identify_file;
}
char *wsmand_options_get_anon_identify_file(void)
{
	return custom_anon_identify_file;
}

char *wsmand_options_get_service_path(void)
{
	return service_path;
}

int wsmand_options_get_daemon_flag(void)
{
	return daemon_flag;
}

int wsmand_options_get_no_plugins_flag(void)
{
	return no_plugin_flag;
}

int wsmand_options_get_use_ssl(void)
{
	return use_ssl;
}

int wsmand_options_get_use_ipv4(void)
{
	return use_ipv4;
}

#ifdef ENABLE_IPV6
int wsmand_options_get_use_ipv6(void)
{
	return use_ipv6;
}

/* called when opening an ipv6 socket failed */
void wsmand_options_disable_use_ipv6(void)
{
	use_ipv6 = 0;
}
#endif

int wsmand_options_get_foreground_debug(void)
{
	if (foreground_debug)
		return 6;
	else
		return -1;
}



int wsmand_options_get_debug_level(void)
{
	return debug_level;
}


int wsmand_options_get_syslog_level(void)
{
	return syslog_level;
}


int wsmand_options_get_server_port(void)
{
	return server_port;
}


int wsmand_options_get_server_ssl_port(void)
{
	return server_ssl_port;
}



char *wsmand_options_get_ssl_key_file(void)
{
	return ssl_key_file;
}

char *wsmand_options_get_ssl_cert_file(void)
{
	return ssl_cert_file;
}

char *wsmand_options_get_ssl_disabled_protocols(void)
{
	return ssl_disabled_protocols;
}

char *wsmand_options_get_ssl_cipher_list(void)
{
	return ssl_cipher_list;
}

int wsmand_options_get_digest(void)
{
	return use_digest;
}


char *wsmand_options_get_pid_file(void)
{
	return pid_file;
}


int wsmand_options_get_max_threads(void)
{
//XXX: we might wish to return a constant 1 till the
//MT issues on unix are solved. See compat_unix.h for
//details on the issue.
	return max_threads;
}


char *wsmand_default_basic_authenticator()
{
	return DEFAULT_BASIC_AUTH;
}

char *wsmand_option_get_basic_authenticator()
{
	return basic_authenticator;
}

char *wsmand_option_get_basic_authenticator_arg()
{
	return basic_authenticator_arg;
}

unsigned long wsmand_options_get_enumIdleTimeout()
{
	return enumIdleTimeout;
}

typedef struct _ShutdownHandler ShutdownHandler;
struct _ShutdownHandler {
	WsmandShutdownFn fn;
	void *user_data;
};

static list_t *shutdown_handlers = NULL;
static int shutdown_counter = 0;
static int shutdown_pending = 0;
static int shutting_down = 0;

void wsmand_shutdown_add_handler(WsmandShutdownFn fn, void *user_data)
{
	ShutdownHandler *handler;
	lnode_t *n;

	if (fn == NULL)
		return;

	handler = u_zalloc(sizeof(ShutdownHandler));
	handler->fn = fn;
	handler->user_data = user_data;

	n = lnode_create(handler);

	if (!shutdown_handlers)
		shutdown_handlers = list_create(LISTCOUNT_T_MAX);

	list_prepend(shutdown_handlers, n);
}

void wsmand_shutdown_block(void)
{
	if (shutdown_counter < 0)
		return;

	if (shutting_down) {
		debug
		    ("Attempting to block shut-down while shut-down is already in progress!");
	}
	++shutdown_counter;
}

void wsmand_shutdown_allow(void)
{
	if (shutdown_counter <= 0)
		return;
	--shutdown_counter;

	if (shutdown_counter == 0 && shutdown_pending) {
		wsmand_shutdown();
	}
}

static int shutdown_idle_cb(void *user_data)
{
	// int restart = (int )user_data;
	lnode_t *n;
	if (shutdown_handlers == NULL) {
		goto NULL_SHUTDOWN_HANDLERS;
	}

	if (list_isempty(shutdown_handlers)) {
		goto EMPTY_LIST;
	}

	n = list_first(shutdown_handlers);

	debug("shutdown_idle_cb started");

	while (n) {
		ShutdownHandler *handler = n->list_data;

		if (handler && handler->fn)
			handler->fn(handler->user_data);

		u_free(handler);
		n = list_next(shutdown_handlers, n);
	}

	// list_destroy_nodes (shutdown_handlers);
      EMPTY_LIST:
	// list_destroy (shutdown_handlers);
      NULL_SHUTDOWN_HANDLERS:

	if (user_data == NULL) {
		/* We should be quitting the main loop (which will cause us to
		   exit) in a handler.  If not, we'll throw in an exit just to be
		   sure. */
		exit(0);
	} else {
		const char **argv = wsmand_options_get_argv();

		errno = 0;
		if ((execv(argv[0], (char **) argv)) < 0) {
			debug("Can not restart wsmand: %s",
			      strerror(errno));
			exit(EXIT_FAILURE);
		}
	}

	/* We should never reach here... */
	assert(1 == 1);
	return 0;
}

static void do_shutdown(int restart)
{
	if (shutdown_counter > 0) {
		debug("Shutting down pended");
		shutdown_pending = TRUE;
		return;
	}
	debug("Shutting down daemon...");

	if (shutting_down) {
		debug
		    ("Shut-down request received while shut-down is already in progress!");
		return;
	}

	shutting_down = TRUE;
	if (restart) {
		shutdown_idle_cb((void *) 1);
	} else {
		shutdown_idle_cb(NULL);
	}

}

void wsmand_shutdown(void)
{
	do_shutdown(FALSE);
}

void wsmand_restart(void)
{
	do_shutdown(TRUE);
}
