/*******************************************************************************
 * 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 Vadim Revyakin
 * @author Liang Hou
 */

#define _GNU_SOURCE
#ifdef HAVE_CONFIG_H
#include "wsman_config.h"
#endif

#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <sys/stat.h>
#include <assert.h>

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

#ifndef WIN32
#include <dlfcn.h>
#endif

#include "u/libu.h"
#include "wsman-xml-api.h"
#include "wsman-soap.h"
#include "wsman-soap-envelope.h"

#include "wsman-xml.h"
#include "wsman-xml-serializer.h"
#include "wsman-dispatcher.h"


#include "shttpd.h"
#include "adapter.h"

#include "wsman-plugins.h"
#include "wsmand-listener.h"
#include "wsmand-daemon.h"
#include "wsman-server.h"
#include "wsman-server-api.h"
#include "wsman-plugins.h"
#ifdef ENABLE_EVENTING_SUPPORT
#include "wsman-cimindication-processor.h"
#endif


#ifdef HAVE_PTHREAD_H
#include <pthread.h>
#endif
#include <sys/socket.h>


static pthread_mutex_t shttpd_mutex;
static pthread_cond_t shttpd_cond;
int continue_working = 1;
static int (*basic_callback) (char *, char *) = NULL;

struct thread {
    struct thread       *next;
    struct shttpd_ctx   *ctx;
};

static struct thread    *threads;   /* List of worker threads */

typedef struct {
	char *response;
	int length;
	int ind;
} ShttpMessage;

#ifdef SHTTPD_GSS
char * gss_decrypt(struct shttpd_arg *arg, char *data, int len);
int gss_encrypt(struct shttpd_arg *arg, char *input, int inlen, char **output, int *outlen);
#endif

/* Check HTTP headers */
static
int check_request_content_type(struct shttpd_arg *arg) {
	const char *content_type;
	int status = WSMAN_STATUS_OK;

	content_type = shttpd_get_header(arg, "Content-Type");
	if (content_type && strncmp(content_type,
				    SOAP_CONTENT_TYPE,
				    strlen(SOAP_CONTENT_TYPE)) != 0) {
		status = WSMAN_STATUS_UNSUPPORTED_MEDIA_TYPE;
	}
	return status;
}

static
char *get_request_encoding(struct shttpd_arg *arg) {
	const char *content_type;
	char *p;
	char *encoding = "UTF-8";

	content_type = shttpd_get_header(arg, "Content-Type");
	if(content_type ) {
		if(( p = strstr(content_type, "charset")) != NULL ) {
			p += strlen("charset");
			p++;
			encoding = p;
		}
	}
	return encoding;
}

static
void server_callback(struct shttpd_arg *arg)
{
	char *encoding = "UTF-8";
	const char  *s;
	SoapH soap;
	int k;
	int status = WSMAN_STATUS_OK;
	char *request_uri;

	char *fault_reason = NULL;
	struct state {
        	size_t  cl;     /* Content-Length   */
	        size_t  nread;      /* Number of bytes read */
	 	u_buf_t *request;
	 	char    *response;
		size_t  len;
		int     index;
		int     type;
	} *state;


	/* If the connection was broken prematurely, cleanup */
	if ( (arg->flags & SHTTPD_CONNECTION_ERROR ) && arg->state) {
        	free(arg->state);
		return;
	} else if ((s = shttpd_get_header(arg, "Content-Length")) == NULL) {
        	shttpd_printf(arg, "HTTP/1.0 411 Length Required\n\n");
	        arg->flags |= SHTTPD_END_OF_OUTPUT;
		return;
	} else if (arg->state == NULL) {
        	/* New request. Allocate a state structure */
        	arg->state = state = calloc(1, sizeof(*state));
	        state->cl = strtoul(s, NULL, 10);
		u_buf_create(&(state->request));
	}

	state = arg->state;
	if ( state->response ) {
		goto CONTINUE;
	}

	if (state->nread>0 )
		u_buf_append(state->request, arg->in.buf, arg->in.len);
	else
		u_buf_set(state->request, arg->in.buf, arg->in.len);

	state->nread += arg->in.len;
	arg->in.num_bytes = arg->in.len;
	if (state->nread >= state->cl) {
		debug("Done reading request");
	} else {
		return;
	}
#ifdef SHTTPD_GSS
	const char *ct = shttpd_get_header(arg, "Content-Type");
	char *payload = 0; // used for gss encrypt

	if (ct && !memcmp(ct, "multipart/encrypted", 19)) {
	        // we have a encrypted payload. decrypt it 
        	payload = gss_decrypt(arg, u_buf_ptr(state->request), u_buf_len(state->request));
	}
#endif
	request_uri = (char *)shttpd_get_env(arg, "REQUEST_URI");
	if (strcmp(request_uri, "/wsman") == 0 ) {

		/* Here we must handle the initial request */
		WsmanMessage *wsman_msg = wsman_soap_message_new();
#ifdef SHTTPD_GSS
	        if(payload == 0) {
#endif
			if ( (status = check_request_content_type(arg) ) != WSMAN_STATUS_OK ) {
				wsman_soap_message_destroy(wsman_msg);
				goto DONE;
			}
			encoding = get_request_encoding(arg);

			u_buf_set(wsman_msg->request, u_buf_ptr(state->request), u_buf_len(state->request));
#ifdef SHTTPD_GSS
	        }
		else {
			u_buf_set(wsman_msg->request, payload, strlen(payload));
		}
#endif
	        wsman_msg->charset = u_strdup(encoding);
		soap = (SoapH) arg->user_data;
		wsman_msg->status.fault_code = WSMAN_RC_OK;

		/*
		 * some plugins can use credentials for their own authentication
		 * works only with basic authentication
		 */
		shttpd_get_credentials(arg, &wsman_msg->auth_data.username,
				&wsman_msg->auth_data.password);

		/* Call dispatcher. Real request handling */
		if (status == WSMAN_STATUS_OK) {
			/* dispatch if we didn't find out any error */
			char *idfile = wsmand_options_get_identify_file();
			if (idfile && wsman_check_identify(wsman_msg) == 1) {
				if (u_buf_load(wsman_msg->response, idfile)) {
					dispatch_inbound_call(soap, wsman_msg, NULL);
					status = wsman_msg->http_code;
				}
			} else {
				dispatch_inbound_call(soap, wsman_msg, NULL);
				status = wsman_msg->http_code;
			}
		}
		if (wsman_msg->request) {
#ifdef SHTTPD_GSS
			if (payload) {
				free(payload);
				/* note that payload is stiil set - this is used as a flag later */
			}
			else {
#endif
				u_buf_free(wsman_msg->request);
#ifdef SHTTPD_GSS
			}
#endif
			wsman_msg->request = NULL;
		}

		state->len =  u_buf_len(wsman_msg->response);;
		state->response = u_buf_steal(wsman_msg->response);
		state->index = 0;
		state->type = 0;

		wsman_soap_message_destroy(wsman_msg);
#ifdef ENABLE_EVENTING_SUPPORT
	} else if (strncmp(request_uri, DEFAULT_CIMINDICATION_PATH, strlen(DEFAULT_CIMINDICATION_PATH)) == 0 ) {
		status = CIMXML_STATUS_OK;
		int cim_error_code = 0;
		char *cim_error = NULL;
		char *fault_reason = NULL;
		char *uuid = NULL, *tmp, *end;
		cimxml_context *cntx = NULL;
		SoapH soap = NULL;
		CimxmlMessage *cimxml_msg = cimxml_message_new();
		tmp = (char *)shttpd_get_env(arg, "REQUEST_URI");
		if (tmp && ( end = strrchr(tmp, '/')) != NULL ) {
			uuid = &end[1];
		}
	        encoding = get_request_encoding(arg);
		cimxml_msg->charset = u_strdup(encoding);
		const char *cimexport = shttpd_get_header(arg, "CIMExport");
		const char *cimexportmethod = shttpd_get_header(arg, "CIMExportMethod");
		if ( cimexportmethod && cimexport ) {
			if(strncmp(cimexport, "MethodRequest", strlen("MethodRequest")) ||
					strncmp(cimexportmethod, "ExportIndication", strlen("ExportIndication"))) {
			}
		} else {
			status = WSMAN_STATUS_FORBIDDEN;
			cim_error_code = CIMXML_STATUS_UNSUPPORTED_OPERATION;
			cim_error = "unsupported-operation";
			goto DONE;
		}
		soap = (SoapH) arg->user_data;
		u_buf_set(cimxml_msg->request, u_buf_ptr(state->request), u_buf_len(state->request));
		cntx = u_malloc(sizeof(cimxml_context));
		cntx->soap = soap;
		cntx->uuid = uuid;
		CIM_Indication_call(cntx, cimxml_msg, NULL);
		status = cimxml_msg->http_code;
		cim_error_code = cimxml_msg->status.code;
		cim_error = cimxml_msg->status.fault_msg;
		if (cim_error) {
			shttpd_printf(arg, "HTTP/1.1 %d %s\r\n", status, fault_reason);
			shttpd_printf(arg, "CIMError: %s\r\n", cim_error);
			cimxml_message_destroy(cimxml_msg);
			goto CONTINUE;
		}
		state->len =  u_buf_len(cimxml_msg->response);;
		state->response = u_buf_steal(cimxml_msg->response);
		state->index = 0;
		state->type = 1;
		cimxml_message_destroy(cimxml_msg);
#endif

	} else if (strcmp(request_uri, ANON_IDENTIFY_PATH) == 0 ) {
		char *idfile = wsmand_options_get_anon_identify_file();
		u_buf_t *id;
		u_buf_create(&id);
		if (idfile && u_buf_load(id, idfile) == 0 ) {
			state->len =  u_buf_len(id);;
			state->response = u_buf_steal(id);
			state->index = 0;
			u_buf_free(id);
		} else {
			shttpd_printf(arg, "HTTP/1.0 404 Not foundn\n");
			arg->flags |= SHTTPD_END_OF_OUTPUT;
			u_buf_free(id);
			return;
		}
	} else {
		shttpd_printf(arg, "HTTP/1.0 404 Not foundn\n");
		arg->flags |= SHTTPD_END_OF_OUTPUT;
		return;
	}

DONE:

	if (fault_reason == NULL) {
		fault_reason = shttpd_reason_phrase(status);
	}
	debug("Response status=%d (%s)", status, fault_reason);

	/*
	 * Here we begin to create the http response.
	 * Create the headers at first.
	 */

	shttpd_printf(arg, "HTTP/1.1 %d %s\r\n", status, fault_reason);
	shttpd_printf(arg, "Server: %s/%s\r\n", PACKAGE, PACKAGE_VERSION);
#ifdef SHTTPD_GSS
	if(payload) {
		// we had an encrypted message so now we have to encypt the reply
		char *enc;
		int enclen;
		gss_encrypt(arg, state->response, state->len, &enc, &enclen);
		u_free(state->response);
		state->response = enc;
		state->len = enclen;
		payload = 0; // and reset the indicator so that if we send in packates we dont do this again
		shttpd_printf(arg, "Content-Type: multipart/encrypted;protocol=\"application/HTTP-Kerberos-session-encrypted\";boundary=\"Encrypted Boundary\"\r\n");
		shttpd_printf(arg, "Content-Length: %d\r\n", state->len);
	}
	else {
#endif
		if (state->type == 1) { /* eventing */
			shttpd_printf(arg, "Content-Type: application/xml; charset=\"utf-8\"\r\n");
			shttpd_printf(arg, "CIMExport: MethodResponse\r\n");
		} else {
			shttpd_printf(arg, "Content-Type: application/soap+xml;charset=%s\r\n", encoding);
		}
    		shttpd_printf(arg, "Content-Length: %d\r\n", state->len);
#ifdef SHTTPD_GSS
	}
#endif
	shttpd_printf(arg,"Connection: Close\r\n");
  
        /* separate header from message-body */
	shttpd_printf(arg, "\r\n");

	/* add response body to output buffer */
CONTINUE:


	k = arg->out.len - arg->out.num_bytes;
	if (k <= state->len - state->index) {
		 memcpy(arg->out.buf + arg->out.num_bytes, state->response + state->index, k );
		 state->index += k ;
		 arg->out.num_bytes += k;
		 return;
	}
	else {
	         int l = state->len - state->index;
		 memcpy(arg->out.buf + arg->out.num_bytes, state->response + state->index, l);
		 state->index += l ;
		 arg->out.num_bytes += l;
	}

	u_buf_free(state->request);
	u_free(state->response);
	u_free(state);
	arg->flags |= SHTTPD_END_OF_OUTPUT;
	return;
}

static void listener_shutdown_handler(void *p)
{
	int *a = (int *) p;
	debug("listener_shutdown_handler started");
	*a = 0;
}

static void protect_uri(struct shttpd_ctx *ctx, char *uri)
{
	if (wsmand_options_get_digest_password_file()) {
		shttpd_protect_uri(ctx, uri,
                   wsmand_options_get_digest_password_file(),NULL, 1);
		debug("Using Digest Authorization for %s:", uri);
	}
	if (basic_callback) {
		shttpd_protect_uri(ctx, uri, wsmand_options_get_basic_password_file(),
						basic_callback, 0);
		debug("Using Basic Authorization %s for %s",
		      wsmand_option_get_basic_authenticator()?
		      wsmand_option_get_basic_authenticator() :
		      wsmand_default_basic_authenticator(), uri);
	}
}

static struct shttpd_ctx *create_shttpd_context(SoapH soap)
{
	struct shttpd_ctx *ctx;
	if (wsmand_options_get_use_ssl()) {
		message("ssl certificate: %s", wsmand_options_get_ssl_cert_file());
		message("Using SSL");
		ctx = shttpd_init(NULL,
				  "ssl_certificate",
				  wsmand_options_get_ssl_cert_file(),
				  "auth_realm",
				  AUTHENTICATION_REALM,
				  NULL);
	} else {
		ctx = shttpd_init(NULL,
				  "auth_realm", AUTHENTICATION_REALM,
				   NULL);
	}
	if (ctx == NULL) {
		return NULL;
	}
	shttpd_register_uri(ctx, wsmand_options_get_service_path(),
			    server_callback, (void *) soap);
	shttpd_register_uri(ctx, ANON_IDENTIFY_PATH,
			    server_callback, (void *) soap);

#ifdef ENABLE_EVENTING_SUPPORT
	message("Registered CIM Indication Listener: %s", DEFAULT_CIMINDICATION_PATH "/*");
	shttpd_register_uri(ctx, DEFAULT_CIMINDICATION_PATH "/*", server_callback,(void *)soap);
	protect_uri( ctx, DEFAULT_CIMINDICATION_PATH );
#endif

	protect_uri( ctx, wsmand_options_get_service_path());

	return ctx;
}


static int initialize_basic_authenticator(void)
{
	char *auth;
	char *arg;
	void *hnd;
	int (*init) (char *);
	char *name;
	int should_return = 0;
	int res = 0;

	if (wsmand_options_get_basic_password_file() != NULL) {
		if ((wsmand_option_get_basic_authenticator() &&
		     (strcmp(wsmand_default_basic_authenticator(),
			     wsmand_option_get_basic_authenticator()))) ||
		    wsmand_option_get_basic_authenticator_arg()) {
			fprintf(stderr,
				"basic authentication is ambigious in config file\n");
			return 1;
		}
		auth = wsmand_default_basic_authenticator();
		arg = wsmand_options_get_basic_password_file();
	} else {
		auth = wsmand_option_get_basic_authenticator();
		arg = wsmand_option_get_basic_authenticator_arg();
	}

	if (auth == NULL) {
		/* No basic authenticationame */
		return 0;
	}

	if (auth[0] == '/') {
		name = auth;
	} else {
		name = u_strdup_printf("%s/%s", PACKAGE_AUTH_DIR, auth);
		should_return = 1;
	}

	hnd = dlopen(name, RTLD_LAZY | RTLD_GLOBAL);
	if (hnd == NULL) {
		fprintf(stderr, "Could not dlopen %s\n", name);
		res = 1;
		goto DONE;
	}
	basic_callback = dlsym(hnd, "authorize");
	if (basic_callback == NULL) {
		fprintf(stderr, "Could not resolve authorize() in %s\n",
			name);
		res = 1;
		goto DONE;
	}

	init = dlsym(hnd, "initialize");
	if (init != NULL) {
		res = init(arg);
	}
      DONE:
	if (should_return) {
		u_free(name);
	}
	return res;
}


static int get_server_auth(void) {
	if (initialize_basic_authenticator()) {
		return 0;
	}

	if (wsmand_options_get_digest_password_file()) {
		message("Using Digest Authorization");
	}
	if (basic_callback) {
		message("Using Basic Authorization %s",
			wsmand_option_get_basic_authenticator()?
			wsmand_option_get_basic_authenticator() :
			wsmand_default_basic_authenticator());
	}

	if ((wsmand_options_get_digest_password_file() == NULL) &&
		    (basic_callback == NULL)) {
		error("Server does not work without authentication");
		return 0;
	}
	return 1;
}

static int get_server_port(void) {
	int port = 0;
	int use_ssl = wsmand_options_get_use_ssl();
	if (use_ssl) {
		message("Using SSL");
		if (wsmand_options_get_ssl_cert_file() &&
		    wsmand_options_get_ssl_key_file() &&
		    (wsmand_options_get_server_ssl_port() > 0)) {
			port = wsmand_options_get_server_ssl_port();
		} else {
			error("Not enough data to use SSL port");
			return 0;
		}
	} else {
		port = wsmand_options_get_server_port();
	}
	return port;
}


static int wsman_setup_thread(pthread_attr_t *pattrs) {
	int r;
	int ret = 0;
	if ((r = pthread_cond_init(&shttpd_cond, NULL)) != 0) {
		debug("pthread_cond_init failed = %d", r);
		return ret;
	}
	if ((r = pthread_mutex_init(&shttpd_mutex, NULL)) != 0) {
		debug("pthread_mutex_init failed = %d", r);
		return ret;
	}

	if ((r = pthread_attr_init(pattrs)) != 0) {
		debug("pthread_attr_init failed = %d", r);
		return ret;
	}

	if ((r = pthread_attr_setdetachstate(pattrs, PTHREAD_CREATE_DETACHED)) != 0) {
		debug("pthread_attr_setdetachstate = %d", r);
		return ret;
	}
	return 1;
        size_t thread_stack_size = wsmand_options_get_thread_stack_size();
        if(thread_stack_size){
                if(( r = pthread_attr_setstacksize(pattrs, thread_stack_size)) !=0) {
                        debug("pthread_attr_setstacksize failed = %d", r);
                        return ret;
                }
        }
}

static void *thread_function(void *param)
{
    struct thread *thread = param;

    for (;;)
        shttpd_poll(thread->ctx, 1000);

    return NULL;
}


static struct thread *
spawn_new_thread(pthread_attr_t pattrs, SoapH soap)
{
    struct shttpd_ctx   *ctx;
    struct thread       *thread;
    pthread_t           tid;
	debug("spawning new thread");

    thread  = malloc(sizeof(*thread));
    ctx = create_shttpd_context(soap);

    assert(ctx != NULL);
    assert(thread != NULL);

    thread->ctx = ctx;
    thread->next    = threads;
    threads     = thread;

	pthread_create(&tid, &pattrs, thread_function, thread);

    return (thread);
}


static struct thread *
find_not_busy_thread(int *num_threads, int max_connections_per_thread)
{
    struct thread   *thread;

    for (thread = threads, *num_threads=0; thread != NULL; thread = thread->next) {
	debug("Active sockets: %d, Thread Number: %d", shttpd_active(thread->ctx), *num_threads );
        (*num_threads)++;
        if (shttpd_active(thread->ctx) < max_connections_per_thread)
            return (thread);
	}

    return (NULL);
}


WsManListenerH *wsmand_start_server(dictionary * ini)
{
	int lsn, port, sock;
	struct thread       *thread;
	pthread_t tid;
#ifdef ENABLE_EVENTING_SUPPORT
	pthread_t notificationManager_id;
#endif
	pthread_attr_t pattrs;
	int use_ssl = wsmand_options_get_use_ssl();
	struct shttpd_ctx   *httpd_ctx;

	WsManListenerH *listener = wsman_dispatch_list_new();
	listener->config = ini;
	WsContextH cntx = wsman_init_plugins(listener);
        int num_threads=0;
        int max_threads=wsmand_options_get_max_threads();
        int max_connections_per_thread = wsmand_options_get_max_connections_per_thread();
        if(max_threads && !max_connections_per_thread){
                error("max_threads: %d and max_connections_per_thread : %d", max_threads, max_connections_per_thread);
                return listener;
        }

#ifdef ENABLE_EVENTING_SUPPORT
	wsman_event_init(cntx->soap);
#endif

	if (cntx == NULL) {
		return listener;
	}
#ifndef HAVE_SSL
	if (use_ssl) {
		error("Server configured without SSL support");
		return listener;
	}
#endif
	SoapH soap = ws_context_get_runtime(cntx);
	ws_set_context_enumIdleTimeout(cntx,wsmand_options_get_enumIdleTimeout());


	if ((port = get_server_port()) == 0  )
		return listener;
#ifdef ENABLE_IPV6
	if (wsmand_options_get_use_ipv6()) {
		message("     Working on IPv6 port %d", port);
	}
	else {
#endif
		message("     Working on IPv4 port %d", port);
#ifdef ENABLE_IPV6
	}
#endif
	if (!get_server_auth())
		return listener;

	wsmand_shutdown_add_handler(listener_shutdown_handler,
				    &continue_working);

	httpd_ctx = create_shttpd_context(soap);

	lsn = shttpd_listen(httpd_ctx, port, use_ssl);

	if (wsman_setup_thread(&pattrs) == 0 )
		return listener;
	pthread_create(&tid, &pattrs, wsman_server_auxiliary_loop_thread, cntx);

#ifdef ENABLE_EVENTING_SUPPORT
	pthread_create(&notificationManager_id, &pattrs, wsman_notification_manager, cntx);
#endif

	while (continue_working) {
		if ((sock = shttpd_accept(lsn, 1000)) == -1) {
			continue;
		}
		debug("Sock %d accepted", sock);
                if ((thread = find_not_busy_thread(&num_threads, max_connections_per_thread)) == NULL){
                        if(max_threads){
                                if(num_threads < max_threads){
                                        thread = spawn_new_thread(pattrs, soap);
                                }
                                else{
                                        continue;
                                }
                        }
                        else{
                                thread = spawn_new_thread(pattrs, soap);
                        }
		}
                shttpd_add_socket(thread->ctx, sock, use_ssl);
        }
        return listener;
}
