/*
 *
 *  D-Bus helper library
 *
 *  Copyright (C) 2004-2011  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 <glib.h>
#include <dbus/dbus.h>

#include "gdbus.h"

#define METHOD_CALL_TIMEOUT (300 * 1000)

struct GDBusClient {
	gint ref_count;
	DBusConnection *dbus_conn;
	char *service_name;
	char *unique_name;
	char *base_path;
	GPtrArray *match_rules;
	DBusPendingCall *pending_call;
	GDBusWatchFunction connect_func;
	void *connect_data;
	GDBusWatchFunction disconn_func;
	void *disconn_data;
	GDBusMessageFunction signal_func;
	void *signal_data;
	GDBusProxyFunction proxy_added;
	GDBusProxyFunction proxy_removed;
	GDBusPropertyFunction property_changed;
	void *user_data;
	GList *proxy_list;
};

struct GDBusProxy {
	gint ref_count;
	GDBusClient *client;
	char *obj_path;
	char *interface;
	GHashTable *prop_list;
	char *match_rule;
	GDBusPropertyFunction prop_func;
	void *prop_data;
};

struct prop_entry {
	char *name;
	int type;
	DBusMessage *msg;
};

static void modify_match_reply(DBusPendingCall *call, void *user_data)
{
	DBusMessage *reply = dbus_pending_call_steal_reply(call);
	DBusError error;

	dbus_error_init(&error);

	if (dbus_set_error_from_message(&error, reply) == TRUE)
		dbus_error_free(&error);

	dbus_message_unref(reply);
}

static gboolean modify_match(DBusConnection *conn, const char *member,
							const char *rule)
{
	DBusMessage *msg;
	DBusPendingCall *call;

	msg = dbus_message_new_method_call(DBUS_SERVICE_DBUS, DBUS_PATH_DBUS,
					DBUS_INTERFACE_DBUS, member);
	if (msg == NULL)
		return FALSE;

	dbus_message_append_args(msg, DBUS_TYPE_STRING, &rule,
						DBUS_TYPE_INVALID);

	if (dbus_connection_send_with_reply(conn, msg, &call, -1) == FALSE) {
		dbus_message_unref(msg);
		return FALSE;
	}

	dbus_pending_call_set_notify(call, modify_match_reply, NULL, NULL);
	dbus_pending_call_unref(call);

	dbus_message_unref(msg);

	return TRUE;
}

static void iter_append_iter(DBusMessageIter *base, DBusMessageIter *iter)
{
	int type;

	type = dbus_message_iter_get_arg_type(iter);

	if (dbus_type_is_basic(type)) {
		const void *value;

		dbus_message_iter_get_basic(iter, &value);
		dbus_message_iter_append_basic(base, type, &value);
	} else if (dbus_type_is_container(type)) {
		DBusMessageIter iter_sub, base_sub;
		char *sig;

		dbus_message_iter_recurse(iter, &iter_sub);

		switch (type) {
		case DBUS_TYPE_ARRAY:
		case DBUS_TYPE_VARIANT:
			sig = dbus_message_iter_get_signature(&iter_sub);
			break;
		default:
			sig = NULL;
			break;
		}

		dbus_message_iter_open_container(base, type, sig, &base_sub);

		if (sig != NULL)
			dbus_free(sig);

		while (dbus_message_iter_get_arg_type(&iter_sub) !=
							DBUS_TYPE_INVALID) {
			iter_append_iter(&base_sub, &iter_sub);
			dbus_message_iter_next(&iter_sub);
		}

		dbus_message_iter_close_container(base, &base_sub);
	}
}

static void prop_entry_update(struct prop_entry *prop, DBusMessageIter *iter)
{
	DBusMessage *msg;
	DBusMessageIter base;

	msg = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN);
	if (msg == NULL)
		return;

	dbus_message_iter_init_append(msg, &base);
	iter_append_iter(&base, iter);

	if (prop->msg != NULL)
		dbus_message_unref(prop->msg);

	prop->msg = dbus_message_copy(msg);
	dbus_message_unref(msg);
}

static struct prop_entry *prop_entry_new(const char *name,
						DBusMessageIter *iter)
{
	struct prop_entry *prop;

	prop = g_try_new0(struct prop_entry, 1);
	if (prop == NULL)
		return NULL;

	prop->name = g_strdup(name);
	prop->type = dbus_message_iter_get_arg_type(iter);

	prop_entry_update(prop, iter);

	return prop;
}

static void prop_entry_free(gpointer data)
{
	struct prop_entry *prop = data;

	if (prop->msg != NULL)
		dbus_message_unref(prop->msg);

	g_free(prop->name);

	g_free(prop);
}

static void add_property(GDBusProxy *proxy, const char *name,
						DBusMessageIter *iter)
{
	DBusMessageIter value;
	struct prop_entry *prop;

	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_VARIANT)
		return;

	dbus_message_iter_recurse(iter, &value);

	prop = g_hash_table_lookup(proxy->prop_list, name);
	if (prop != NULL) {
		GDBusClient *client = proxy->client;

		prop_entry_update(prop, &value);

		if (proxy->prop_func)
			proxy->prop_func(proxy, name, &value, proxy->prop_data);

		if (client == NULL)
			return;

		if (client->property_changed)
			client->property_changed(proxy, name, &value,
							client->user_data);
		return;
	}

	prop = prop_entry_new(name, &value);
	if (prop == NULL)
		return;

	g_hash_table_replace(proxy->prop_list, prop->name, prop);

	if (proxy->prop_func)
		proxy->prop_func(proxy, name, &value, proxy->prop_data);
}

static void update_properties(GDBusProxy *proxy, DBusMessageIter *iter)
{
	DBusMessageIter dict;

	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
		return;

	dbus_message_iter_recurse(iter, &dict);

	while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
		DBusMessageIter entry;
		const char *name;

		dbus_message_iter_recurse(&dict, &entry);

		if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
			break;

		dbus_message_iter_get_basic(&entry, &name);
		dbus_message_iter_next(&entry);

		add_property(proxy, name, &entry);

		dbus_message_iter_next(&dict);
	}
}

static void get_all_properties_reply(DBusPendingCall *call, void *user_data)
{
	GDBusProxy *proxy = user_data;
	GDBusClient *client = proxy->client;
	DBusMessage *reply = dbus_pending_call_steal_reply(call);
	DBusMessageIter iter;
	DBusError error;

	dbus_error_init(&error);

	if (dbus_set_error_from_message(&error, reply) == TRUE) {
		dbus_error_free(&error);
		goto done;
	}

	dbus_message_iter_init(reply, &iter);

	update_properties(proxy, &iter);

done:
	if (g_list_find(client->proxy_list, proxy) == NULL) {
		if (client->proxy_added)
			client->proxy_added(proxy, client->user_data);

		client->proxy_list = g_list_append(client->proxy_list, proxy);
	}

	dbus_message_unref(reply);

	g_dbus_client_unref(client);
}

static void get_all_properties(GDBusProxy *proxy)
{
	GDBusClient *client = proxy->client;
	const char *service_name = client->service_name;
	DBusMessage *msg;
	DBusPendingCall *call;

	msg = dbus_message_new_method_call(service_name, proxy->obj_path,
					DBUS_INTERFACE_PROPERTIES, "GetAll");
	if (msg == NULL)
		return;

	dbus_message_append_args(msg, DBUS_TYPE_STRING, &proxy->interface,
							DBUS_TYPE_INVALID);

	if (dbus_connection_send_with_reply(client->dbus_conn, msg,
							&call, -1) == FALSE) {
		dbus_message_unref(msg);
		return;
	}

	g_dbus_client_ref(client);

	dbus_pending_call_set_notify(call, get_all_properties_reply,
							proxy, NULL);
	dbus_pending_call_unref(call);

	dbus_message_unref(msg);
}

static GDBusProxy *proxy_lookup(GDBusClient *client, const char *path,
						const char *interface)
{
	GList *list;

	for (list = g_list_first(client->proxy_list); list;
						list = g_list_next(list)) {
		GDBusProxy *proxy = list->data;

		if (g_str_equal(proxy->interface, interface) == TRUE &&
				g_str_equal(proxy->obj_path, path) == TRUE)
			return proxy;
        }

	return NULL;
}

static GDBusProxy *proxy_new(GDBusClient *client, const char *path,
						const char *interface)
{
	GDBusProxy *proxy;

	proxy = g_try_new0(GDBusProxy, 1);
	if (proxy == NULL)
		return NULL;

	proxy->client = client;
	proxy->obj_path = g_strdup(path);
	proxy->interface = g_strdup(interface);

	proxy->prop_list = g_hash_table_new_full(g_str_hash, g_str_equal,
							NULL, prop_entry_free);

	proxy->match_rule = g_strdup_printf("type='signal',"
				"sender='%s',path='%s',interface='%s',"
				"member='PropertiesChanged',arg0='%s'",
				client->service_name, proxy->obj_path,
				DBUS_INTERFACE_PROPERTIES, proxy->interface);

	modify_match(client->dbus_conn, "AddMatch", proxy->match_rule);

	return g_dbus_proxy_ref(proxy);
}

static void proxy_free(gpointer data)
{
	GDBusProxy *proxy = data;

	if (proxy->client) {
		GDBusClient *client = proxy->client;

		if (client->proxy_removed)
			client->proxy_removed(proxy, client->user_data);

		modify_match(client->dbus_conn, "RemoveMatch",
							proxy->match_rule);

		g_free(proxy->match_rule);
		proxy->match_rule = NULL;

		g_hash_table_remove_all(proxy->prop_list);

		proxy->client = NULL;
	}

	g_dbus_proxy_unref(proxy);
}

static void proxy_remove(GDBusClient *client, const char *path,
						const char *interface)
{
	GList *list;

	for (list = g_list_first(client->proxy_list); list;
						list = g_list_next(list)) {
		GDBusProxy *proxy = list->data;

		if (g_str_equal(proxy->interface, interface) == TRUE &&
				g_str_equal(proxy->obj_path, path) == TRUE) {
			client->proxy_list =
				g_list_delete_link(client->proxy_list, list);
			proxy_free(proxy);
			break;
		}
	}
}

GDBusProxy *g_dbus_proxy_new(GDBusClient *client, const char *path,
							const char *interface)
{
	GDBusProxy *proxy;

	if (client == NULL)
		return NULL;

	proxy = proxy_lookup(client, path, interface);
	if (proxy)
		return g_dbus_proxy_ref(proxy);

	proxy = proxy_new(client, path, interface);
	if (proxy == NULL)
		return NULL;

	get_all_properties(proxy);

	return g_dbus_proxy_ref(proxy);
}

GDBusProxy *g_dbus_proxy_ref(GDBusProxy *proxy)
{
	if (proxy == NULL)
		return NULL;

	g_atomic_int_inc(&proxy->ref_count);

	return proxy;
}

void g_dbus_proxy_unref(GDBusProxy *proxy)
{
	if (proxy == NULL)
		return;

	if (g_atomic_int_dec_and_test(&proxy->ref_count) == FALSE)
		return;

	g_hash_table_destroy(proxy->prop_list);

	g_free(proxy->obj_path);
	g_free(proxy->interface);

	g_free(proxy);
}

const char *g_dbus_proxy_get_path(GDBusProxy *proxy)
{
	if (proxy == NULL)
		return NULL;

	return proxy->obj_path;
}

const char *g_dbus_proxy_get_interface(GDBusProxy *proxy)
{
	if (proxy == NULL)
		return NULL;

	return proxy->interface;
}

gboolean g_dbus_proxy_get_property(GDBusProxy *proxy, const char *name,
                                                        DBusMessageIter *iter)
{
	struct prop_entry *prop;

	if (proxy == NULL || name == NULL)
		return FALSE;

	prop = g_hash_table_lookup(proxy->prop_list, name);
	if (prop == NULL)
		return FALSE;

	if (prop->msg == NULL)
		return FALSE;

	if (dbus_message_iter_init(prop->msg, iter) == FALSE)
		return FALSE;

	return TRUE;
}

struct refresh_property_data {
	GDBusProxy *proxy;
	char *name;
};

static void refresh_property_free(gpointer user_data)
{
	struct refresh_property_data *data = user_data;

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

static void refresh_property_reply(DBusPendingCall *call, void *user_data)
{
	struct refresh_property_data *data = user_data;
	DBusMessage *reply = dbus_pending_call_steal_reply(call);
	DBusError error;

	dbus_error_init(&error);

	if (dbus_set_error_from_message(&error, reply) == FALSE) {
		DBusMessageIter iter;

		dbus_message_iter_init(reply, &iter);

		add_property(data->proxy, data->name, &iter);
	} else
		dbus_error_free(&error);

	dbus_message_unref(reply);
}

gboolean g_dbus_proxy_refresh_property(GDBusProxy *proxy, const char *name)
{
	struct refresh_property_data *data;
	GDBusClient *client;
	DBusMessage *msg;
	DBusMessageIter iter;
	DBusPendingCall *call;

	if (proxy == NULL || name == NULL)
		return FALSE;

	client = proxy->client;
	if (client == NULL)
		return FALSE;

	data = g_try_new0(struct refresh_property_data, 1);
	if (data == NULL)
		return FALSE;

	data->proxy = proxy;
	data->name = g_strdup(name);

	msg = dbus_message_new_method_call(client->service_name,
			proxy->obj_path, DBUS_INTERFACE_PROPERTIES, "Get");
	if (msg == NULL) {
		refresh_property_free(data);
		return FALSE;
	}

	dbus_message_iter_init_append(msg, &iter);
	dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING,
							&proxy->interface);
	dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &name);

	if (dbus_connection_send_with_reply(client->dbus_conn, msg,
							&call, -1) == FALSE) {
		dbus_message_unref(msg);
		refresh_property_free(data);
		return FALSE;
	}

	dbus_pending_call_set_notify(call, refresh_property_reply,
						data, refresh_property_free);
	dbus_pending_call_unref(call);

	dbus_message_unref(msg);

	return TRUE;
}

struct set_property_data {
	GDBusResultFunction function;
	void *user_data;
	GDBusDestroyFunction destroy;
};

static void set_property_reply(DBusPendingCall *call, void *user_data)
{
	struct set_property_data *data = user_data;
	DBusMessage *reply = dbus_pending_call_steal_reply(call);
	DBusError error;

	dbus_error_init(&error);

	dbus_set_error_from_message(&error, reply);

	if (data->function)
		data->function(&error, data->user_data);

	if (data->destroy)
		data->destroy(data->user_data);

	dbus_error_free(&error);

	dbus_message_unref(reply);
}

gboolean g_dbus_proxy_set_property_basic(GDBusProxy *proxy,
				const char *name, int type, const void *value,
				GDBusResultFunction function, void *user_data,
				GDBusDestroyFunction destroy)
{
	struct set_property_data *data;
	GDBusClient *client;
	DBusMessage *msg;
	DBusMessageIter iter, variant;
	DBusPendingCall *call;
	char type_as_str[2];

	if (proxy == NULL || name == NULL || value == NULL)
		return FALSE;

	if (dbus_type_is_basic(type) == FALSE)
		return FALSE;

	client = proxy->client;
	if (client == NULL)
		return FALSE;

	data = g_try_new0(struct set_property_data, 1);
	if (data == NULL)
		return FALSE;

	data->function = function;
	data->user_data = user_data;
	data->destroy = destroy;

	msg = dbus_message_new_method_call(client->service_name,
			proxy->obj_path, DBUS_INTERFACE_PROPERTIES, "Set");
	if (msg == NULL) {
		g_free(data);
		return FALSE;
	}

	type_as_str[0] = (char) type;
	type_as_str[1] = '\0';

	dbus_message_iter_init_append(msg, &iter);
	dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING,
							&proxy->interface);
	dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &name);

	dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
						type_as_str, &variant);
	dbus_message_iter_append_basic(&variant, type, value);
	dbus_message_iter_close_container(&iter, &variant);

	if (dbus_connection_send_with_reply(client->dbus_conn, msg,
							&call, -1) == FALSE) {
		dbus_message_unref(msg);
		g_free(data);
		return FALSE;
	}

	dbus_pending_call_set_notify(call, set_property_reply, data, g_free);
	dbus_pending_call_unref(call);

	dbus_message_unref(msg);

	return TRUE;
}

struct method_call_data {
	GDBusReturnFunction function;
	void *user_data;
	GDBusDestroyFunction destroy;
};

static void method_call_reply(DBusPendingCall *call, void *user_data)
{
	struct method_call_data *data = user_data;
	DBusMessage *reply = dbus_pending_call_steal_reply(call);

	if (data->function)
		data->function(reply, data->user_data);

	if (data->destroy)
		data->destroy(data->user_data);

	dbus_message_unref(reply);
}

gboolean g_dbus_proxy_method_call(GDBusProxy *proxy, const char *method,
				GDBusSetupFunction setup,
				GDBusReturnFunction function, void *user_data,
				GDBusDestroyFunction destroy)
{
	struct method_call_data *data;
	GDBusClient *client;
	DBusMessage *msg;
	DBusPendingCall *call;

	if (proxy == NULL || method == NULL)
		return FALSE;

	client = proxy->client;
	if (client == NULL)
		return FALSE;

	data = g_try_new0(struct method_call_data, 1);
	if (data == NULL)
		return FALSE;

	data->function = function;
	data->user_data = user_data;
	data->destroy = destroy;

	msg = dbus_message_new_method_call(client->service_name,
				proxy->obj_path, proxy->interface, method);
	if (msg == NULL) {
		g_free(data);
		return FALSE;
	}

	if (setup) {
		DBusMessageIter iter;

		dbus_message_iter_init_append(msg, &iter);
		setup(&iter, data->user_data);
	}

	if (dbus_connection_send_with_reply(client->dbus_conn, msg,
					&call, METHOD_CALL_TIMEOUT) == FALSE) {
		dbus_message_unref(msg);
		g_free(data);
		return FALSE;
	}

	dbus_pending_call_set_notify(call, method_call_reply, data, g_free);
	dbus_pending_call_unref(call);

	dbus_message_unref(msg);

	return TRUE;
}

gboolean g_dbus_proxy_set_property_watch(GDBusProxy *proxy,
			GDBusPropertyFunction function, void *user_data)
{
	if (proxy == NULL)
		return FALSE;

	proxy->prop_func = function;
	proxy->prop_data = user_data;

	return TRUE;
}

static void refresh_properties(GDBusClient *client)
{
	GList *list;

	for (list = g_list_first(client->proxy_list); list;
						list = g_list_next(list)) {
		GDBusProxy *proxy = list->data;

		get_all_properties(proxy);
        }
}

static void properties_changed(GDBusClient *client, const char *path,
							DBusMessage *msg)
{
	GDBusProxy *proxy = NULL;
	DBusMessageIter iter, entry;
	const char *interface;
	GList *list;

	if (dbus_message_iter_init(msg, &iter) == FALSE)
		return;

	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
		return;

	dbus_message_iter_get_basic(&iter, &interface);
	dbus_message_iter_next(&iter);

	for (list = g_list_first(client->proxy_list); list;
						list = g_list_next(list)) {
		GDBusProxy *data = list->data;

		if (g_str_equal(data->interface, interface) == TRUE &&
				g_str_equal(data->obj_path, path) == TRUE) {
			proxy = data;
			break;
		}
	}

	if (proxy == NULL)
		return;

	update_properties(proxy, &iter);

	dbus_message_iter_next(&iter);

	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY)
		return;

	dbus_message_iter_recurse(&iter, &entry);

	while (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_STRING) {
		const char *name;

		dbus_message_iter_get_basic(&entry, &name);

		g_hash_table_remove(proxy->prop_list, name);

		if (proxy->prop_func)
			proxy->prop_func(proxy, name, NULL, proxy->prop_data);

		if (client->property_changed)
			client->property_changed(proxy, name, NULL,
							client->user_data);

		dbus_message_iter_next(&entry);
	}
}

static void parse_properties(GDBusClient *client, const char *path,
				const char *interface, DBusMessageIter *iter)
{
	GDBusProxy *proxy;

	if (g_str_equal(interface, DBUS_INTERFACE_INTROSPECTABLE) == TRUE)
		return;

	if (g_str_equal(interface, DBUS_INTERFACE_PROPERTIES) == TRUE)
		return;

	proxy = proxy_lookup(client, path, interface);
	if (proxy) {
		update_properties(proxy, iter);
		return;
	}

	proxy = proxy_new(client, path, interface);
	if (proxy == NULL)
		return;

	update_properties(proxy, iter);

	if (client->proxy_added)
		client->proxy_added(proxy, client->user_data);

	client->proxy_list = g_list_append(client->proxy_list, proxy);
}

static void parse_interfaces(GDBusClient *client, const char *path,
						DBusMessageIter *iter)
{
	DBusMessageIter dict;

	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
		return;

	dbus_message_iter_recurse(iter, &dict);

	while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
		DBusMessageIter entry;
		const char *interface;

		dbus_message_iter_recurse(&dict, &entry);

		if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
			break;

		dbus_message_iter_get_basic(&entry, &interface);
		dbus_message_iter_next(&entry);

		parse_properties(client, path, interface, &entry);

		dbus_message_iter_next(&dict);
	}
}

static void interfaces_added(GDBusClient *client, DBusMessage *msg)
{
	DBusMessageIter iter;
	const char *path;

	if (dbus_message_iter_init(msg, &iter) == FALSE)
		return;

	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_OBJECT_PATH)
		return;

	dbus_message_iter_get_basic(&iter, &path);
	dbus_message_iter_next(&iter);

	g_dbus_client_ref(client);

	parse_interfaces(client, path, &iter);

	g_dbus_client_unref(client);
}

static void interfaces_removed(GDBusClient *client, DBusMessage *msg)
{
	DBusMessageIter iter, entry;
	const char *path;

	if (dbus_message_iter_init(msg, &iter) == FALSE)
		return;

	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_OBJECT_PATH)
		return;

	dbus_message_iter_get_basic(&iter, &path);
	dbus_message_iter_next(&iter);

	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY)
		return;

	dbus_message_iter_recurse(&iter, &entry);

	g_dbus_client_ref(client);

	while (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_STRING) {
		const char *interface;

		dbus_message_iter_get_basic(&entry, &interface);
		proxy_remove(client, path, interface);
		dbus_message_iter_next(&entry);
	}

	g_dbus_client_unref(client);
}

static void parse_managed_objects(GDBusClient *client, DBusMessage *msg)
{
	DBusMessageIter iter, dict;

	if (dbus_message_iter_init(msg, &iter) == FALSE)
		return;

	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY)
		return;

	dbus_message_iter_recurse(&iter, &dict);

	while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
		DBusMessageIter entry;
		const char *path;

		dbus_message_iter_recurse(&dict, &entry);

		if (dbus_message_iter_get_arg_type(&entry) !=
							DBUS_TYPE_OBJECT_PATH)
			break;

		dbus_message_iter_get_basic(&entry, &path);
		dbus_message_iter_next(&entry);

		parse_interfaces(client, path, &entry);

		dbus_message_iter_next(&dict);
	}
}

static void get_managed_objects_reply(DBusPendingCall *call, void *user_data)
{
	GDBusClient *client = user_data;
	DBusMessage *reply = dbus_pending_call_steal_reply(call);
	DBusError error;

	dbus_error_init(&error);

	if (dbus_set_error_from_message(&error, reply) == TRUE) {
		dbus_error_free(&error);
		goto done;
	}

	parse_managed_objects(client, reply);

done:
	dbus_message_unref(reply);

	g_dbus_client_unref(client);
}

static void get_managed_objects(GDBusClient *client)
{
	DBusMessage *msg;
	DBusPendingCall *call;

	if (!client->proxy_added && !client->proxy_removed) {
		refresh_properties(client);
		return;
	}

	msg = dbus_message_new_method_call(client->service_name, "/",
					DBUS_INTERFACE_DBUS ".ObjectManager",
							"GetManagedObjects");
	if (msg == NULL)
		return;

	dbus_message_append_args(msg, DBUS_TYPE_INVALID);

	if (dbus_connection_send_with_reply(client->dbus_conn, msg,
							&call, -1) == FALSE) {
		dbus_message_unref(msg);
		return;
	}

	g_dbus_client_ref(client);

	dbus_pending_call_set_notify(call, get_managed_objects_reply,
							client, NULL);
	dbus_pending_call_unref(call);

	dbus_message_unref(msg);
}

static void get_name_owner_reply(DBusPendingCall *call, void *user_data)
{
	GDBusClient *client = user_data;
	DBusMessage *reply = dbus_pending_call_steal_reply(call);
	DBusError error;
	const char *name;

	g_dbus_client_ref(client);

	dbus_error_init(&error);

	if (dbus_set_error_from_message(&error, reply) == TRUE) {
		dbus_error_free(&error);
		goto done;
	}

	if (dbus_message_get_args(reply, NULL, DBUS_TYPE_STRING, &name,
						DBUS_TYPE_INVALID) == FALSE)
		goto done;

	if (client->unique_name == NULL) {
		client->unique_name = g_strdup(name);

		if (client->connect_func)
			client->connect_func(client->dbus_conn,
							client->connect_data);

		get_managed_objects(client);
	}

done:
	dbus_message_unref(reply);

	dbus_pending_call_unref(client->pending_call);
	client->pending_call = NULL;

	g_dbus_client_unref(client);
}

static void get_name_owner(GDBusClient *client, const char *name)
{
	DBusMessage *msg;

	msg = dbus_message_new_method_call(DBUS_SERVICE_DBUS, DBUS_PATH_DBUS,
					DBUS_INTERFACE_DBUS, "GetNameOwner");
	if (msg == NULL)
		return;

	dbus_message_append_args(msg, DBUS_TYPE_STRING, &name,
						DBUS_TYPE_INVALID);

	if (dbus_connection_send_with_reply(client->dbus_conn, msg,
					&client->pending_call, -1) == FALSE) {
		dbus_message_unref(msg);
		return;
	}

	dbus_pending_call_set_notify(client->pending_call,
					get_name_owner_reply, client, NULL);

	dbus_message_unref(msg);
}

static DBusHandlerResult message_filter(DBusConnection *connection,
					DBusMessage *message, void *user_data)
{
	GDBusClient *client = user_data;
	const char *sender;

	if (dbus_message_get_type(message) != DBUS_MESSAGE_TYPE_SIGNAL)
		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;

	sender = dbus_message_get_sender(message);

	if (g_str_equal(sender, DBUS_SERVICE_DBUS) == TRUE) {
		const char *interface, *member;
		const char *name, *old, *new;

		interface = dbus_message_get_interface(message);

		if (g_str_equal(interface, DBUS_INTERFACE_DBUS) == FALSE)
			return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;

		member = dbus_message_get_member(message);

		if (g_str_equal(member, "NameOwnerChanged") == FALSE)
			return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;

		if (dbus_message_get_args(message, NULL,
						DBUS_TYPE_STRING, &name,
						DBUS_TYPE_STRING, &old,
						DBUS_TYPE_STRING, &new,
						DBUS_TYPE_INVALID) == FALSE)
			return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;

		if (g_str_equal(name, client->service_name) == FALSE)
			return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;

		if (*new == '\0' && client->unique_name != NULL &&
				g_str_equal(old, client->unique_name) == TRUE) {
			if (client->disconn_func)
				client->disconn_func(client->dbus_conn,
							client->disconn_data);

			g_free(client->unique_name);
			client->unique_name = NULL;
		} else if (*old == '\0' && client->unique_name == NULL) {
			client->unique_name = g_strdup(new);

			if (client->connect_func)
				client->connect_func(client->dbus_conn,
							client->connect_data);

			get_managed_objects(client);
		}

		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
	}

	if (client->unique_name == NULL)
		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;

	if (g_str_equal(sender, client->unique_name) == TRUE) {
		const char *path, *interface, *member;

		path = dbus_message_get_path(message);
		interface = dbus_message_get_interface(message);
		member = dbus_message_get_member(message);

		if (g_str_equal(path, "/") == TRUE) {
			if (g_str_equal(interface, DBUS_INTERFACE_DBUS
						".ObjectManager") == FALSE)
				return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;

			if (g_str_equal(member, "InterfacesAdded") == TRUE) {
				interfaces_added(client, message);
				return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
			}

			if (g_str_equal(member, "InterfacesRemoved") == TRUE) {
				interfaces_removed(client, message);
				return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
			}

			return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
		}

		if (g_str_has_prefix(path, client->base_path) == FALSE)
			return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;

		if (g_str_equal(interface, DBUS_INTERFACE_PROPERTIES) == TRUE) {
			if (g_str_equal(member, "PropertiesChanged") == TRUE)
				properties_changed(client, path, message);

			return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
		}

		if (client->signal_func)
			client->signal_func(client->dbus_conn,
					message, client->signal_data);
	}

	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}

GDBusClient *g_dbus_client_new(DBusConnection *connection,
					const char *service, const char *path)
{
	GDBusClient *client;
	unsigned int i;

	if (connection == NULL)
		return NULL;

	client = g_try_new0(GDBusClient, 1);
	if (client == NULL)
		return NULL;

	if (dbus_connection_add_filter(connection, message_filter,
						client, NULL) == FALSE) {
		g_free(client);
		return NULL;
	}

	client->dbus_conn = dbus_connection_ref(connection);
	client->service_name = g_strdup(service);
	client->base_path = g_strdup(path);

	get_name_owner(client, client->service_name);

	client->match_rules = g_ptr_array_sized_new(4);
	g_ptr_array_set_free_func(client->match_rules, g_free);

	g_ptr_array_add(client->match_rules, g_strdup_printf("type='signal',"
				"sender='%s',path='%s',interface='%s',"
				"member='NameOwnerChanged',arg0='%s'",
				DBUS_SERVICE_DBUS, DBUS_PATH_DBUS,
				DBUS_INTERFACE_DBUS, client->service_name));
	g_ptr_array_add(client->match_rules, g_strdup_printf("type='signal',"
				"sender='%s',"
				"path='/',interface='%s.ObjectManager',"
				"member='InterfacesAdded'",
				client->service_name, DBUS_INTERFACE_DBUS));
	g_ptr_array_add(client->match_rules, g_strdup_printf("type='signal',"
				"sender='%s',"
				"path='/',interface='%s.ObjectManager',"
				"member='InterfacesRemoved'",
				client->service_name, DBUS_INTERFACE_DBUS));
	g_ptr_array_add(client->match_rules, g_strdup_printf("type='signal',"
				"sender='%s',path_namespace='%s'",
				client->service_name, client->base_path));

	for (i = 0; i < client->match_rules->len; i++) {
		modify_match(client->dbus_conn, "AddMatch",
				g_ptr_array_index(client->match_rules, i));
	}

	return g_dbus_client_ref(client);
}

GDBusClient *g_dbus_client_ref(GDBusClient *client)
{
	if (client == NULL)
		return NULL;

	g_atomic_int_inc(&client->ref_count);

	return client;
}

void g_dbus_client_unref(GDBusClient *client)
{
	unsigned int i;

	if (client == NULL)
		return;

	if (g_atomic_int_dec_and_test(&client->ref_count) == FALSE)
		return;

	if (client->pending_call != NULL) {
		dbus_pending_call_cancel(client->pending_call);
		dbus_pending_call_unref(client->pending_call);
	}

	for (i = 0; i < client->match_rules->len; i++) {
		modify_match(client->dbus_conn, "RemoveMatch",
				g_ptr_array_index(client->match_rules, i));
	}

	g_ptr_array_free(client->match_rules, TRUE);

	dbus_connection_remove_filter(client->dbus_conn,
						message_filter, client);

	g_list_free_full(client->proxy_list, proxy_free);

	if (client->disconn_func)
		client->disconn_func(client->dbus_conn, client->disconn_data);

	dbus_connection_unref(client->dbus_conn);

	g_free(client->service_name);
	g_free(client->unique_name);
	g_free(client->base_path);

	g_free(client);
}

gboolean g_dbus_client_set_connect_watch(GDBusClient *client,
				GDBusWatchFunction function, void *user_data)
{
	if (client == NULL)
		return FALSE;

	client->connect_func = function;
	client->connect_data = user_data;

	return TRUE;
}

gboolean g_dbus_client_set_disconnect_watch(GDBusClient *client,
				GDBusWatchFunction function, void *user_data)
{
	if (client == NULL)
		return FALSE;

	client->disconn_func = function;
	client->disconn_data = user_data;

	return TRUE;
}

gboolean g_dbus_client_set_signal_watch(GDBusClient *client,
				GDBusMessageFunction function, void *user_data)
{
	if (client == NULL)
		return FALSE;

	client->signal_func = function;
	client->signal_data = user_data;

	return TRUE;
}

gboolean g_dbus_client_set_proxy_handlers(GDBusClient *client,
					GDBusProxyFunction proxy_added,
					GDBusProxyFunction proxy_removed,
					GDBusPropertyFunction property_changed,
					void *user_data)
{
	if (client == NULL)
		return FALSE;

	client->proxy_added = proxy_added;
	client->proxy_removed = proxy_removed;
	client->property_changed = property_changed;
	client->user_data = user_data;

	get_managed_objects(client);

	return TRUE;
}
