/* Build with gcc folks-test.c `pkg-config folks --cflags --libs` */

#include <folks/folks.h>

static gint64 start_time;
static guint idle_id;

static void
aggregator_individuals_changed_cb (FolksIndividualAggregator *aggregator,
    GeeMultiMap *changes,
    gpointer user_data)
{
  GeeSet *removed;
  GeeCollection *added;

  removed = gee_multi_map_get_keys (changes);
  added = gee_multi_map_get_values (changes);

  g_print ("%f: Added: %d, Removed: %d, quiescent: %s\n",
      (g_get_monotonic_time () - start_time) / 1000000.0,
      gee_collection_get_size (GEE_COLLECTION (added)),
      gee_collection_get_size (GEE_COLLECTION (removed)),
      folks_individual_aggregator_get_is_quiescent (aggregator) ? "Yes" : "No");

  g_object_unref (added);
  g_object_unref (removed);
}

static gboolean
idle_cb (gpointer user_data)
{
  FolksIndividualAggregator *aggregator = user_data;

  g_print ("%f: idle, quiescent: %s\n",
      (g_get_monotonic_time () - start_time) / 1000000.0,
      folks_individual_aggregator_get_is_quiescent (aggregator) ? "Yes" : "No");

  return TRUE;
}

static void
aggregator_quiescent_cb (FolksIndividualAggregator *aggregator)
{
  g_print ("%f: quiescent changed: %s\n",
      (g_get_monotonic_time () - start_time) / 1000000.0,
      folks_individual_aggregator_get_is_quiescent (aggregator) ? "Yes" : "No");

  if (folks_individual_aggregator_get_is_quiescent (aggregator))
    {
      g_source_remove (idle_id);
      idle_id = 0;
    }
  else if (idle_id == 0)
    {
      idle_id = g_idle_add (idle_cb, aggregator);
    }
}

static void
aggregator_prepared_cb (GObject *source,
    GAsyncResult *result,
    gpointer user_data)
{
  FolksIndividualAggregator *aggregator = FOLKS_INDIVIDUAL_AGGREGATOR (source);
  GError *error = NULL;

  folks_individual_aggregator_prepare_finish (aggregator, result, &error);
  g_assert_no_error (error);

  g_print ("%f: aggregator prepared\n",
      (g_get_monotonic_time () - start_time) / 1000000.0);
}

int
main (int argc,
  char **argv)
{
  FolksIndividualAggregator *aggregator;
  GMainLoop *loop;

  g_type_init ();

  start_time = g_get_monotonic_time ();

  aggregator = folks_individual_aggregator_new ();
  g_signal_connect (aggregator, "notify::is-quiescent",
      G_CALLBACK (aggregator_quiescent_cb),
      NULL);
  g_signal_connect (aggregator, "individuals-changed-detailed",
      G_CALLBACK (aggregator_individuals_changed_cb),
      NULL);
  folks_individual_aggregator_prepare (aggregator, aggregator_prepared_cb, NULL);

  idle_id = g_idle_add (idle_cb, aggregator);

  loop = g_main_loop_new (NULL, FALSE);
  g_main_loop_run (loop);

  g_object_unref (aggregator);
  g_main_loop_unref (loop);
}
