#include <string.h>
#include <stdlib.h>

#include <stdio.h>

#include "plugin.h"
#include "log.h"
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#ifdef HAVE_VALGRIND_VALGRIND_H
#include <valgrind/valgrind.h>
#endif

#ifndef __WIN32
#include <dlfcn.h>
#endif
/*
 *
 * if you change this enum to add a new callback, be sure
 * - that PLUGIN_FUNC_SIZEOF is the last entry
 * - that you add PLUGIN_TO_SLOT twice:
 *   1. as callback-dispatcher
 *   2. in plugins_call_init()
 *
 */

typedef struct {
	PLUGIN_DATA;
} plugin_data;

typedef enum {
	PLUGIN_FUNC_UNSET,
		PLUGIN_FUNC_HANDLE_URI_CLEAN,
		PLUGIN_FUNC_HANDLE_URI_RAW,
		PLUGIN_FUNC_HANDLE_REQUEST_DONE,
		PLUGIN_FUNC_HANDLE_CONNECTION_CLOSE,
		PLUGIN_FUNC_HANDLE_TRIGGER,
		PLUGIN_FUNC_HANDLE_SIGHUP,
		PLUGIN_FUNC_HANDLE_SUBREQUEST,
		PLUGIN_FUNC_HANDLE_SUBREQUEST_START,
		PLUGIN_FUNC_HANDLE_JOBLIST,
		PLUGIN_FUNC_HANDLE_DOCROOT,
		PLUGIN_FUNC_HANDLE_PHYSICAL,
		PLUGIN_FUNC_CONNECTION_RESET,
		PLUGIN_FUNC_INIT,
		PLUGIN_FUNC_CLEANUP,
		PLUGIN_FUNC_SET_DEFAULTS,

		PLUGIN_FUNC_SIZEOF
} plugin_t;

static plugin *plugin_init(void) {
	plugin *p;

	p = calloc(1, sizeof(*p));

	return p;
}

static void plugin_free(plugin *p) {
	int use_dlclose = 1;
	if (p->name) buffer_free(p->name);
#ifdef HAVE_VALGRIND_VALGRIND_H
	/*if (RUNNING_ON_VALGRIND) use_dlclose = 0;*/
#endif

#ifndef LIGHTTPD_STATIC
	if (use_dlclose && p->lib) {
#ifdef __WIN32
		FreeLibrary(p->lib);
#else
		dlclose(p->lib);
#endif
	}
#endif

	free(p);
}

static int plugins_register(server *srv, plugin *p) {
	plugin **ps;
	if (0 == srv->plugins.size) {
		srv->plugins.size = 4;
		srv->plugins.ptr  = malloc(srv->plugins.size * sizeof(*ps));
		srv->plugins.used = 0;
	} else if (srv->plugins.used == srv->plugins.size) {
		srv->plugins.size += 4;
		srv->plugins.ptr   = realloc(srv->plugins.ptr, srv->plugins.size * sizeof(*ps));
	}

	ps = srv->plugins.ptr;
	ps[srv->plugins.used++] = p;

	return 0;
}

/**
 *
 *
 *
 */

#ifdef LIGHTTPD_STATIC
int plugins_load(server *srv) {
	plugin *p;
#define PLUGIN_INIT(x)\
	p = plugin_init(); \
	if (x ## _plugin_init(p)) { \
		log_error_write(srv, __FILE__, __LINE__, "ss", #x, "plugin init failed" ); \
		plugin_free(p); \
		return -1;\
	}\
	plugins_register(srv, p);

#include "plugin-static.h"

	return 0;
}
#else
int plugins_load(server *srv) {
	plugin *p;
	int (*init)(plugin *pl);
	const char *error;
	size_t i;

	for (i = 0; i < srv->srvconf.modules->used; i++) {
		data_string *d = (data_string *)srv->srvconf.modules->data[i];
		char *modules = d->value->ptr;

		buffer_copy_string_buffer(srv->tmp_buf, srv->srvconf.modules_dir);

		buffer_append_string(srv->tmp_buf, "/");
		buffer_append_string(srv->tmp_buf, modules);
#if defined(__WIN32) || defined(__CYGWIN__)
		buffer_append_string(srv->tmp_buf, ".dll");
#else
		buffer_append_string(srv->tmp_buf, ".so");
#endif

		p = plugin_init();
#ifdef __WIN32
		if (NULL == (p->lib = LoadLibrary(srv->tmp_buf->ptr))) {
			LPVOID lpMsgBuf;
			FormatMessage(
		        	FORMAT_MESSAGE_ALLOCATE_BUFFER |
		       		FORMAT_MESSAGE_FROM_SYSTEM,
		        	NULL,
		        	GetLastError(),
		        	MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
		        	(LPTSTR) &lpMsgBuf,
		        	0, NULL );

			log_error_write(srv, __FILE__, __LINE__, "ssb", "LoadLibrary() failed",
					lpMsgBuf, srv->tmp_buf);

			plugin_free(p);

			return -1;

		}
#else
		if (NULL == (p->lib = dlopen(srv->tmp_buf->ptr, RTLD_NOW|RTLD_GLOBAL))) {
			log_error_write(srv, __FILE__, __LINE__, "sbs", "dlopen() failed for:",
					srv->tmp_buf, dlerror());

			plugin_free(p);

			return -1;
		}

#endif
		buffer_reset(srv->tmp_buf);
		buffer_copy_string(srv->tmp_buf, modules);
		buffer_append_string(srv->tmp_buf, "_plugin_init");

#ifdef __WIN32
		init = GetProcAddress(p->lib, srv->tmp_buf->ptr);

		if (init == NULL)  {
			LPVOID lpMsgBuf;
			FormatMessage(
		        	FORMAT_MESSAGE_ALLOCATE_BUFFER |
		       		FORMAT_MESSAGE_FROM_SYSTEM,
		        	NULL,
		        	GetLastError(),
		        	MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
		        	(LPTSTR) &lpMsgBuf,
		        	0, NULL );

			log_error_write(srv, __FILE__, __LINE__, "sbs", "getprocaddress failed:", srv->tmp_buf, lpMsgBuf);

			plugin_free(p);
			return -1;
		}

#else
#if 1
		init = (int (*)(plugin *))dlsym(p->lib, srv->tmp_buf->ptr);
#else
		*(void **)(&init) = dlsym(p->lib, srv->tmp_buf->ptr);
#endif
		if ((error = dlerror()) != NULL)  {
			log_error_write(srv, __FILE__, __LINE__, "s", error);

			plugin_free(p);
			return -1;
		}

#endif
		if ((*init)(p)) {
			log_error_write(srv, __FILE__, __LINE__, "ss", modules, "plugin init failed" );

			plugin_free(p);
			return -1;
		}
#if 0
		log_error_write(srv, __FILE__, __LINE__, "ss", modules, "plugin loaded" );
#endif
		plugins_register(srv, p);
	}

	return 0;
}
#endif

#define PLUGIN_TO_SLOT(x, y) \
	handler_t plugins_call_##y(server *srv, connection *con) {\
		plugin **slot;\
		size_t j;\
                if (!srv->plugin_slots) return HANDLER_GO_ON;\
                slot = ((plugin ***)(srv->plugin_slots))[x];\
		if (!slot) return HANDLER_GO_ON;\
		for (j = 0; j < srv->plugins.used && slot[j]; j++) { \
			plugin *p = slot[j];\
			handler_t r;\
			switch(r = p->y(srv, con, p->data)) {\
			case HANDLER_GO_ON:\
				break;\
			case HANDLER_FINISHED:\
			case HANDLER_COMEBACK:\
			case HANDLER_WAIT_FOR_EVENT:\
			case HANDLER_WAIT_FOR_FD:\
			case HANDLER_ERROR:\
				return r;\
			default:\
				log_error_write(srv, __FILE__, __LINE__, "sbs", #x, p->name, "unknown state");\
				return HANDLER_ERROR;\
			}\
		}\
		return HANDLER_GO_ON;\
	}

/**
 * plugins that use
 *
 * - server *srv
 * - connection *con
 * - void *p_d (plugin_data *)
 */

PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_URI_CLEAN, handle_uri_clean)
PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_URI_RAW, handle_uri_raw)
PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_REQUEST_DONE, handle_request_done)
PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_CONNECTION_CLOSE, handle_connection_close)
PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_SUBREQUEST, handle_subrequest)
PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_SUBREQUEST_START, handle_subrequest_start)
PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_JOBLIST, handle_joblist)
PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_DOCROOT, handle_docroot)
PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_PHYSICAL, handle_physical)
PLUGIN_TO_SLOT(PLUGIN_FUNC_CONNECTION_RESET, connection_reset)

#undef PLUGIN_TO_SLOT

#define PLUGIN_TO_SLOT(x, y) \
	handler_t plugins_call_##y(server *srv) {\
		plugin **slot;\
		size_t j;\
                if (!srv->plugin_slots) return HANDLER_GO_ON;\
                slot = ((plugin ***)(srv->plugin_slots))[x];\
		if (!slot) return HANDLER_GO_ON;\
		for (j = 0; j < srv->plugins.used && slot[j]; j++) { \
			plugin *p = slot[j];\
			handler_t r;\
			switch(r = p->y(srv, p->data)) {\
			case HANDLER_GO_ON:\
				break;\
			case HANDLER_FINISHED:\
			case HANDLER_COMEBACK:\
			case HANDLER_WAIT_FOR_EVENT:\
			case HANDLER_WAIT_FOR_FD:\
			case HANDLER_ERROR:\
				return r;\
			default:\
				log_error_write(srv, __FILE__, __LINE__, "sbsd", #x, p->name, "unknown state:", r);\
				return HANDLER_ERROR;\
			}\
		}\
		return HANDLER_GO_ON;\
	}

/**
 * plugins that use
 *
 * - server *srv
 * - void *p_d (plugin_data *)
 */

PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_TRIGGER, handle_trigger)
PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_SIGHUP, handle_sighup)
PLUGIN_TO_SLOT(PLUGIN_FUNC_CLEANUP, cleanup)
PLUGIN_TO_SLOT(PLUGIN_FUNC_SET_DEFAULTS, set_defaults)

#undef PLUGIN_TO_SLOT

#if 0
/**
 *
 * special handler
 *
 */
handler_t plugins_call_handle_fdevent(server *srv, const fd_conn *fdc) {
	size_t i;
	plugin **ps;

	ps = srv->plugins.ptr;

	for (i = 0; i < srv->plugins.used; i++) {
		plugin *p = ps[i];
		if (p->handle_fdevent) {
			handler_t r;
			switch(r = p->handle_fdevent(srv, fdc, p->data)) {
			case HANDLER_GO_ON:
				break;
			case HANDLER_FINISHED:
			case HANDLER_COMEBACK:
			case HANDLER_WAIT_FOR_EVENT:
			case HANDLER_ERROR:
				return r;
			default:
				log_error_write(srv, __FILE__, __LINE__, "d", r);
				break;
			}
		}
	}

	return HANDLER_GO_ON;
}
#endif
/**
 *
 * - call init function of all plugins to init the plugin-internals
 * - added each plugin that supports has callback to the corresponding slot
 *
 * - is only called once.
 */

handler_t plugins_call_init(server *srv) {
	size_t i;
	plugin **ps;

	ps = srv->plugins.ptr;

	/* fill slots */

	srv->plugin_slots = calloc(PLUGIN_FUNC_SIZEOF, sizeof(ps));

	for (i = 0; i < srv->plugins.used; i++) {
		size_t j;
		/* check which calls are supported */

		plugin *p = ps[i];

#define PLUGIN_TO_SLOT(x, y) \
	if (p->y) { \
		plugin **slot = ((plugin ***)(srv->plugin_slots))[x]; \
		if (!slot) { \
			slot = calloc(srv->plugins.used, sizeof(*slot));\
			((plugin ***)(srv->plugin_slots))[x] = slot; \
		} \
		for (j = 0; j < srv->plugins.used; j++) { \
			if (slot[j]) continue;\
			slot[j] = p;\
			break;\
		}\
	}


		PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_URI_CLEAN, handle_uri_clean);
		PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_URI_RAW, handle_uri_raw);
		PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_REQUEST_DONE, handle_request_done);
		PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_CONNECTION_CLOSE, handle_connection_close);
		PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_TRIGGER, handle_trigger);
		PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_SIGHUP, handle_sighup);
		PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_SUBREQUEST, handle_subrequest);
		PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_SUBREQUEST_START, handle_subrequest_start);
		PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_JOBLIST, handle_joblist);
		PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_DOCROOT, handle_docroot);
		PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_PHYSICAL, handle_physical);
		PLUGIN_TO_SLOT(PLUGIN_FUNC_CONNECTION_RESET, connection_reset);
		PLUGIN_TO_SLOT(PLUGIN_FUNC_CLEANUP, cleanup);
		PLUGIN_TO_SLOT(PLUGIN_FUNC_SET_DEFAULTS, set_defaults);
#undef PLUGIN_TO_SLOT

		if (p->init) {
			if (NULL == (p->data = p->init())) {
				log_error_write(srv, __FILE__, __LINE__, "sb",
						"plugin-init failed for module", p->name);
				return HANDLER_ERROR;
			}

			/* used for con->mode, DIRECT == 0, plugins above that */
			((plugin_data *)(p->data))->id = i + 1;

			if (p->version != LIGHTTPD_VERSION_ID) {
				log_error_write(srv, __FILE__, __LINE__, "sb",
						"plugin-version doesn't match lighttpd-version for", p->name);
				return HANDLER_ERROR;
			}
		} else {
			p->data = NULL;
		}
	}

	return HANDLER_GO_ON;
}

void plugins_free(server *srv) {
	size_t i;
	plugins_call_cleanup(srv);

	for (i = 0; i < srv->plugins.used; i++) {
		plugin *p = ((plugin **)srv->plugins.ptr)[i];

		plugin_free(p);
	}

	for (i = 0; srv->plugin_slots && i < PLUGIN_FUNC_SIZEOF; i++) {
		plugin **slot = ((plugin ***)(srv->plugin_slots))[i];

		if (slot) free(slot);
	}

	free(srv->plugin_slots);
	srv->plugin_slots = NULL;

	free(srv->plugins.ptr);
	srv->plugins.ptr = NULL;
	srv->plugins.used = 0;
}
