// gcc -o test test.c `pkg-config --libs --cflags gtk+-3.0 accountsservice libnotify`

#include <gtk/gtk.h>
#include <act/act.h>
#include <libnotify/notify.h>
#include <stdlib.h>

static void
notification_closed (NotifyNotification *notification,
		     gpointer user_data)
{
	gtk_main_quit ();
}

static void
ok_clicked (NotifyNotification *notification,
	    char *action,
	    gpointer user_data)
{
	gtk_main_quit ();
}

static void
details_clicked (NotifyNotification *notification,
		 char *action,
		 gpointer user_data)
{
	g_spawn_command_line_async ("gnome-control-center user-accounts history", NULL);
	g_message ("Launch history");
	gtk_main_quit ();
}

static void
show_last_login (gint64 last_login_time)
{
	NotifyNotification *notification;
	GDateTime *date;
	char *str;

	date = g_date_time_new_from_unix_local (last_login_time);
	str = g_date_time_format (date, "Last signed in on %c");

	/* FIXME: Add an icon */
	notification = notify_notification_new ("Welcome back", str, NULL);
	g_signal_connect (G_OBJECT (notification), "closed",
			  G_CALLBACK (notification_closed), NULL);
	g_free (str);

	notify_notification_add_action (notification,
					"ok",
					"OK",
					ok_clicked,
					NULL,
					NULL);
	notify_notification_add_action (notification,
					"details",
					"Show Details",
					details_clicked,
					NULL,
					NULL);
	notify_notification_show (notification, NULL);

	/* FIXME: Number of failures since then:
	 * https://bugzilla.gnome.org/show_bug.cgi?id=708846 */
}

static void
process_logins (ActUserManager *um)
{
	ActUser *user;
	const GVariant *history;
	GVariantIter *iter, *iter2;
	gint64 login_time;
	gint64 logout_time;
	const gchar *type;
	GVariant *variant;
	const gchar *key;
	gint64 last_login_time;

	user = act_user_manager_get_user_by_id (um, geteuid ());
	history = act_user_get_login_history (user);

	last_login_time = -1;

	g_variant_get ((GVariant *) history, "a(xxa{sv})", &iter);
	while (g_variant_iter_loop (iter, "(xxa{sv})", &login_time, &logout_time, &iter2)) {
		while (g_variant_iter_loop (iter2, "{sv}", &key, &variant)) {
			if (g_strcmp0 (key, "type") == 0) {
				type = g_variant_get_string (variant, NULL);

				/* Display only x-session and tty records */
				if (!g_str_has_prefix (type, ":") &&
				    !g_str_has_prefix (type, "tty")) {
					g_debug ("Ignoring login type '%s'", type);
					continue;
				}

				/* The history is supposed to be sorted
				 * and we don't break out here because there might
				 * be old logins without logouts (on-going sessions
				 * somewhere else, or broken recording) */
				if (login_time > 0 && logout_time > 0)
					last_login_time = login_time;

				g_debug ("key: %s type: %s login: %" G_GINT64_FORMAT " logout: %" G_GINT64_FORMAT, key, type, login_time, logout_time);
			} else {
				g_debug ("Unknown key: %s", key);
			}
		}
	}

	/* Never logged in? */
	if (last_login_time >= 0)
		show_last_login (last_login_time);
	else
		gtk_main_quit ();
}

static void
users_loaded (ActUserManager     *um,
	      GParamSpec         *pspec,
	      gpointer            user_data)
{
	process_logins (um);
}

int main (int argc, char **argv)
{
	gboolean loaded;
	ActUserManager *um;

	gtk_init (&argc, &argv);
	notify_init ("test");

	um = act_user_manager_get_default ();
	g_object_get (um, "is-loaded", &loaded, NULL);
	if (loaded)
		process_logins (um);
	else
		g_signal_connect (um, "notify::is-loaded", G_CALLBACK (users_loaded), NULL);

	gtk_main ();

	return 0;
}
