/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2004-2007  Marcel Holtmann <marcel@holtmann.org>
 *
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

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

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

#include <glib.h>

#include <dbus/dbus.h>

#include "logging.h"

#include "dbus-helper.h"

struct generic_data {
	void *user_data;
	DBusObjectPathUnregisterFunction unregister_function;
	GSList *interfaces;
	char *introspect;
};

struct interface_data {
	char *name;
	DBusMethodVTable *methods;
	DBusSignalVTable *signals;
	DBusPropertyVTable *properties;
};

DBusHandlerResult dbus_connection_send_and_unref(DBusConnection *connection,
							DBusMessage *message)
{
	if (message) {
		dbus_connection_send(connection, message, NULL);
		dbus_message_unref(message);
	}

	return DBUS_HANDLER_RESULT_HANDLED;
}

static void print_arguments(GString *gstr, const char *sig, const char *direction)
{
	int i;

	for (i = 0; sig[i]; i++) {
		char type[32];
		int len, struct_level, dict_level;
		gboolean complete;

		complete = FALSE;
		struct_level = dict_level = 0;
		memset(type, 0, sizeof(type));

		/* Gather enough data to have a single complete type */
		for (len = 0; len < (sizeof(type) - 1) && sig[i]; len++, i++) {
			switch (sig[i]){
			case '(':
				struct_level++;
				break;
			case ')':
				struct_level--;
				if (struct_level <= 0 && dict_level <= 0)
					complete = TRUE;
				break;
			case '{':
				dict_level++;
				break;
			case '}':
				dict_level--;
				if (struct_level <= 0 && dict_level <= 0)
					complete = TRUE;
				break;
			case 'a':
				break;
			default:
				if (struct_level <= 0 && dict_level <= 0)
					complete = TRUE;
				break;
			}

			type[len] = sig[i];

			if (complete)
				break;
		}


		if (direction)
			g_string_append_printf(gstr,
					"\t\t\t<arg type=\"%s\" direction=\"%s\"/>\n",
					type, direction);
		else
			g_string_append_printf(gstr,
					"\t\t\t<arg type=\"%s\"/>\n",
					type);
	}
}

static void generate_introspection_xml(DBusConnection *conn,
					struct generic_data *data,
					const char *path)
{
	GSList *list;
	GString *gstr;
	char **children;
	int i;

	g_free(data->introspect);

	gstr = g_string_new(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE);

	g_string_append_printf(gstr, "<node name=\"%s\">\n", path);

	for (list = data->interfaces; list; list = list->next) {
		struct interface_data *iface = list->data;
		DBusMethodVTable *method;
		DBusSignalVTable *signal;
		DBusPropertyVTable *property;

		g_string_append_printf(gstr, "\t<interface name=\"%s\">\n", iface->name);

		for (method = iface->methods; method && method->name; method++) {
			debug("%s: adding method %s.%s",
					path, iface->name, method->name);
			if (!strlen(method->signature) && !strlen(method->reply))
				g_string_append_printf(gstr, "\t\t<method name=\"%s\"/>\n",
							method->name);
			else {
				g_string_append_printf(gstr, "\t\t<method name=\"%s\">\n",
							method->name);
				print_arguments(gstr, method->signature, "in");
				print_arguments(gstr, method->reply, "out");
				g_string_append_printf(gstr, "\t\t</method>\n");
			}
		}

		for (signal = iface->signals; signal && signal->name; signal++) {
			debug("%s: adding signal %s.%s",
					path, iface->name, signal->name);
			if (!strlen(signal->signature))
				g_string_append_printf(gstr, "\t\t<signal name=\"%s\"/>\n",
							signal->name);
			else {
				g_string_append_printf(gstr, "\t\t<signal name=\"%s\">\n",
							signal->name);
				print_arguments(gstr, signal->signature, NULL);
				g_string_append_printf(gstr, "\t\t</signal>\n");
			}
		}

		for (property = iface->properties; property && property->name; property++) {
			debug("%s: adding property %s.%s",
					path, iface->name, property->name);
		}

		g_string_append_printf(gstr, "\t</interface>\n");
	}

	if (!dbus_connection_list_registered(conn, path, &children))
		goto done;

	for (i = 0; children[i]; i++)
		g_string_append_printf(gstr, "\t<node name=\"%s\"/>\n", children[i]);

	dbus_free_string_array(children);

done:
	g_string_append_printf(gstr, "</node>\n");

	data->introspect = g_string_free(gstr, FALSE);
}

static DBusHandlerResult introspect(DBusConnection *connection,
				DBusMessage *message, struct generic_data *data)
{
	DBusMessage *reply;

	if (!dbus_message_has_signature(message, DBUS_TYPE_INVALID_AS_STRING)) {
		error("Unexpected signature to introspect call");
		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
	}

	if (!data->introspect)
		generate_introspection_xml(connection, data,
						dbus_message_get_path(message));

	reply = dbus_message_new_method_return(message);
	if (!reply)
		return DBUS_HANDLER_RESULT_NEED_MEMORY;

	dbus_message_append_args(reply, DBUS_TYPE_STRING, &data->introspect,
					DBUS_TYPE_INVALID);

	return dbus_connection_send_and_unref(connection, reply);
}

static void generic_unregister(DBusConnection *connection, void *user_data)
{
	struct generic_data *data = user_data;

	if (data->unregister_function)
		data->unregister_function(connection, data->user_data);

	g_free(data->introspect);
	g_free(data);
}

static struct interface_data *find_interface(GSList *interfaces,
						const char *name)
{
	GSList *list;

	for (list = interfaces; list; list = list->next) {
		struct interface_data *iface = list->data;
		if (!strcmp(name, iface->name))
			return iface;
	}

	return NULL;
}

static DBusHandlerResult generic_message(DBusConnection *connection,
					DBusMessage *message, void *user_data)
{
	struct generic_data *data = user_data;
	struct interface_data *iface;
	DBusMethodVTable *current;
	const char *interface;

	if (dbus_message_is_method_call(message,
					DBUS_INTERFACE_INTROSPECTABLE,
					"Introspect"))
		return introspect(connection, message, data);

	interface = dbus_message_get_interface(message);

	iface = find_interface(data->interfaces, interface);
	if (!iface)
		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;

	for (current = iface->methods;
			current->name && current->message_function; current++) {
		if (!dbus_message_is_method_call(message, iface->name,
							current->name))
			continue;

		if (dbus_message_has_signature(message, current->signature)) {
			debug("%s: %s.%s()", dbus_message_get_path(message),
					iface->name, current->name);
			return current->message_function(connection,
						message, data->user_data);
		}
	}

	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}

static DBusObjectPathVTable generic_table = {
	.unregister_function	= generic_unregister,
	.message_function	= generic_message,
};

static void update_parent_data(DBusConnection *conn, const char *child_path)
{
	struct generic_data *data;
	char *parent_path, *slash;

	parent_path = g_strdup(child_path);
	slash = strrchr(parent_path, '/');
	if (!slash)
		goto done;

	*slash = '\0';
	if (!strlen(parent_path))
		goto done;

	if (!dbus_connection_get_object_path_data(conn, parent_path,
							(void *) &data))
		goto done;

	if (!data)
		goto done;

	g_free(data->introspect);
	data->introspect = NULL;

done:
	g_free(parent_path);
}

dbus_bool_t dbus_connection_create_object_path(DBusConnection *connection,
					const char *path, void *user_data,
					DBusObjectPathUnregisterFunction function)
{
	struct generic_data *data;

	data = g_new0(struct generic_data, 1);

	data->user_data = user_data;
	data->unregister_function = function;

	data->introspect = g_strdup(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE "<node></node>");

	if (!dbus_connection_register_object_path(connection, path,
						&generic_table, data)) {
		g_free(data);
		return FALSE;
	}

	update_parent_data(connection, path);

	return TRUE;
}

dbus_bool_t dbus_connection_destroy_object_path(DBusConnection *connection,
							const char *path)
{
	if (!dbus_connection_unregister_object_path(connection, path))
		return FALSE;

	update_parent_data(connection, path);

	return TRUE;
}

dbus_bool_t dbus_connection_get_object_user_data(DBusConnection *connection,
							const char *path,
							void **data_p)
{
	struct generic_data *data;

	if (!dbus_connection_get_object_path_data(connection, path,
							(void *) &data))
		return FALSE;

	*data_p = data->user_data;

	return TRUE;
}

dbus_bool_t dbus_connection_register_interface(DBusConnection *connection,
					const char *path, const char *name,
					DBusMethodVTable *methods,
					DBusSignalVTable *signals,
					DBusPropertyVTable *properties)
{
	struct generic_data *data;
	struct interface_data *iface;

	if (!dbus_connection_get_object_path_data(connection, path,
							(void *) &data))
		return FALSE;

	if (find_interface(data->interfaces, name))
		return FALSE;

	iface = g_new0(struct interface_data, 1);

	iface->name = g_strdup(name);
	iface->methods = methods;
	iface->signals = signals;
	iface->properties = properties;

	data->interfaces = g_slist_append(data->interfaces, iface);

	g_free(data->introspect);
	data->introspect = NULL;

	return TRUE;
}

dbus_bool_t dbus_connection_unregister_interface(DBusConnection *connection,
					const char *path, const char *name)
{
	struct generic_data *data;
	struct interface_data *iface;

	if (!dbus_connection_get_object_path_data(connection, path,
							(void *) &data))
		return FALSE;

	iface = find_interface(data->interfaces, name);
	if (!iface)
		return FALSE;

	data->interfaces = g_slist_remove(data->interfaces, iface);

	g_free(iface->name);
	g_free(iface);

	g_free(data->introspect);
	data->introspect = NULL;

	return TRUE;
}

void dbus_message_iter_append_dict_entry(DBusMessageIter *dict,
					const char *key, int type, void *val)
{
	DBusMessageIter entry;
	DBusMessageIter value;
	char *sig;

	dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY, NULL, &entry);

	dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);

	switch (type) {
	case DBUS_TYPE_STRING:
		sig = DBUS_TYPE_STRING_AS_STRING;
		break;
	case DBUS_TYPE_UINT32:
		sig = DBUS_TYPE_UINT32_AS_STRING;
		break;
	case DBUS_TYPE_BOOLEAN:
		sig = DBUS_TYPE_BOOLEAN_AS_STRING;
		break;
	default:
		sig = DBUS_TYPE_VARIANT_AS_STRING;
		break;
	}

	dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT, sig, &value);

	dbus_message_iter_append_basic(&value, type, val);

	dbus_message_iter_close_container(&entry, &value);

	dbus_message_iter_close_container(dict, &entry);
}

dbus_bool_t dbus_connection_emit_signal_valist(DBusConnection *conn,
						const char *path,
						const char *interface,
						const char *name,
						int first,
						va_list var_args)
{
	struct generic_data *data;
	struct interface_data *iface;
	DBusMessageIter iter;
	DBusSignalVTable *sig_data;
	DBusMessage *signal;
	int type;
	const char *args = NULL;

	if (!dbus_connection_get_object_path_data(conn, path, (void *) &data)) {
		error("dbus_connection_emit_signal: path %s isn't registered",
				path);
		return FALSE;
	}

	iface = find_interface(data->interfaces, interface);

	if (!iface) {
		error("dbus_connection_emit_signal: %s does not implement %s",
				path, interface);
		return FALSE;
	}

	for (sig_data = iface->signals; sig_data && sig_data->name; sig_data++) {
		if (!strcmp(sig_data->name, name)) {
			args = sig_data->signature;
			break;
		}
	}

	if (!args) {
		error("No signal named %s on interface %s", name, interface);
		return FALSE;
	}

	signal = dbus_message_new_signal(path, interface, name);
	if (!signal) {
		error("Unable to allocate new %s.%s signal", interface,  name);
		return FALSE;
	}

	dbus_message_iter_init_append(signal, &iter);

	for (type = first; type != DBUS_TYPE_INVALID;
			type = va_arg(var_args, int), args++) {
		void *value;

		if (type != *args) {
			error("%s.%s: expected arg type '%c' but got '%c'",
					interface, name, *args, type);
			dbus_message_unref(signal);
			return FALSE;
		}
		
		value = va_arg(var_args, void *);

		if (!dbus_message_iter_append_basic(&iter, type, value)) {
			error("%s.%s: appending argument of type '%c' failed",
					interface, name, type);
			dbus_message_unref(signal);
			return FALSE;
		}
	}

	dbus_connection_send(conn, signal, NULL);
	dbus_message_unref(signal);

	return TRUE;
}

dbus_bool_t dbus_connection_emit_signal(DBusConnection *conn, const char *path,
					const char *interface, const char *name,
					int first, ...)
{
	dbus_bool_t ret;
	va_list var_args;

	va_start(var_args, first);
	ret = dbus_connection_emit_signal_valist(conn, path, interface, name,
							first, var_args);
	va_end(var_args);

	return ret;
}

