/* gcc `pkg-config --cflags --libs glib-2.0 gio-2.0 libebook-1.2` test.c -g -o test && ./test */

#include <glib.h>
#include <libebook/libebook.h>
#include <libedataserver/libedataserver.h>
#include <stdio.h>
#include <string.h>

static EBookClient *
open_sync (ESource *source)
{
	EClient *client;

	client = e_book_client_connect_sync (source, NULL, NULL);

	return E_BOOK_CLIENT (client);
}

static EBookClient *
open_async (ESource *source)
{
	EAsyncClosure *closure;
	GAsyncResult *result;
	EClient *client;

	closure = e_async_closure_new ();
	e_book_client_connect (source, NULL, e_async_closure_callback, closure);

	result = e_async_closure_wait (closure);

	client = e_book_client_connect_finish (result, NULL);

	e_async_closure_free (closure);

	return E_BOOK_CLIENT (client);
}

static void
book_notify_cb (EBookClient *book,
		GParamSpec *param)
{
	printf ("%p %s: %s\n", book, __FUNCTION__, param->name);
}

static void
book_backend_property_changed_cb (EBookClient *book,
				  const gchar *name)
{
	printf ("%p %s: %s\n", book, __FUNCTION__, name);
}

static void
book_gone_cb (gpointer user_data,
	      GObject *obj)
{
	printf ("%p %s:\n", obj, __FUNCTION__);
}

static gboolean
unref_book_cb (gpointer book)
{
	g_object_unref (book);
	return FALSE;
}

typedef enum
{
	OpenSync,
	OpenAsync
} TestType;

static void
test (ESource *source,
      TestType type)
{
	EBookClient *book;
	GSList *contacts;
	char *test = NULL;

	if (type == OpenSync) {
		book = open_sync (source);
		test = "OpenSync";
	} else if (type == OpenAsync) {
		book = open_async (source);
		test = "OpenAsync";
	}

	g_signal_connect (book, "notify", G_CALLBACK (book_notify_cb), NULL);
	g_signal_connect (book, "backend-property-changed", G_CALLBACK (book_backend_property_changed_cb), NULL);

	printf ("Test: %s book:%p\n", test, book);
	printf ("   Name: %s\n", e_source_get_display_name (source));
	printf ("   Read-only: %d\n", e_client_is_readonly (E_CLIENT (book)));
	printf ("   Online: %d\n", e_client_is_online (E_CLIENT (book)));
	printf ("   Opened: %d\n", e_client_is_opened (E_CLIENT (book)));
	e_book_client_get_contacts_sync (book, "(is \"email\"  \"zyx@no.where\")", &contacts, NULL, NULL);	
	printf ("   Found contacts: %d\n", g_slist_length (contacts));
	printf ("\n");

	g_slist_free_full (contacts, g_object_unref);
	g_object_weak_ref (G_OBJECT (book), book_gone_cb, NULL);
	g_timeout_add_seconds (2, unref_book_cb, book);
}

static GMainLoop *loop = NULL;

static gboolean
timeout_cb (gpointer user_data)
{
	g_main_loop_quit (loop);
	return FALSE;
}

static gboolean
idle_cb (gpointer user_data)
{
	test (user_data, OpenSync);
	test (user_data, OpenAsync);

	g_timeout_add_seconds (7, timeout_cb, NULL);
	return FALSE;
}

int
main (int argc, char **argv)
{
	ESourceRegistry *registry;
	ESource *local;

	g_type_init ();

	registry = e_source_registry_new_sync (NULL, NULL);
	local = e_source_registry_ref_builtin_address_book (registry);
	g_object_unref (registry);

	loop = g_main_loop_new (NULL, FALSE);
	g_idle_add (idle_cb, local);

	g_main_loop_run (loop);
	g_main_loop_unref (loop);

	g_object_unref (local);

	return 0;
}
