#include <gio/gio.h>
#include <gio/gunixsocketaddress.h>
#include <glib/gstdio.h>
#include <string.h>

#include "gdbus-sessionbus.h"

#include "glib/glib-private.h"

static gboolean
time_out (gpointer unused G_GNUC_UNUSED)
{
  g_error ("Timed out");
  /* not reached */
  return FALSE;
}

static guint
add_timeout (guint seconds)
{
#ifdef G_OS_UNIX
  /* Safety-catch against the main loop having blocked */
  alarm (seconds + 5);
#endif
  return g_timeout_add_seconds (seconds, time_out, NULL);
}

static void
cancel_timeout (guint timeout_id)
{
#ifdef G_OS_UNIX
  alarm (0);
#endif
  g_source_remove (timeout_id);
}

/* Markup printing {{{1 */

/* This used to be part of GLib, but it was removed before the stable
 * release because it wasn't generally useful.  We want it here, though.
 */
static void
indent_string (GString *string,
               gint     indent)
{
  while (indent--)
    g_string_append_c (string, ' ');
}

static GString *
g_menu_markup_print_string (GString    *string,
                            GMenuModel *model,
                            gint        indent,
                            gint        tabstop)
{
  gboolean need_nl = FALSE;
  gint i, n;

  if G_UNLIKELY (string == NULL)
    string = g_string_new (NULL);

  n = g_menu_model_get_n_items (model);

  for (i = 0; i < n; i++)
    {
      GMenuAttributeIter *attr_iter;
      GMenuLinkIter *link_iter;
      GString *contents;
      GString *attrs;

      attr_iter = g_menu_model_iterate_item_attributes (model, i);
      link_iter = g_menu_model_iterate_item_links (model, i);
      contents = g_string_new (NULL);
      attrs = g_string_new (NULL);

      while (g_menu_attribute_iter_next (attr_iter))
        {
          const char *name = g_menu_attribute_iter_get_name (attr_iter);
          GVariant *value = g_menu_attribute_iter_get_value (attr_iter);

          if (g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
            {
              gchar *str;
              str = g_markup_printf_escaped (" %s='%s'", name, g_variant_get_string (value, NULL));
              g_string_append (attrs, str);
              g_free (str);
            }

          else
            {
              gchar *printed;
              gchar *str;
              const gchar *type;

              printed = g_variant_print (value, TRUE);
              type = g_variant_type_peek_string (g_variant_get_type (value));
              str = g_markup_printf_escaped ("<attribute name='%s' type='%s'>%s</attribute>\n", name, type, printed);
              indent_string (contents, indent + tabstop);
              g_string_append (contents, str);
              g_free (printed);
              g_free (str);
            }

          g_variant_unref (value);
        }
      g_object_unref (attr_iter);

      while (g_menu_link_iter_next (link_iter))
        {
          const gchar *name = g_menu_link_iter_get_name (link_iter);
          GMenuModel *menu = g_menu_link_iter_get_value (link_iter);
          gchar *str;

          if (contents->str[0])
            g_string_append_c (contents, '\n');

          str = g_markup_printf_escaped ("<link name='%s'>\n", name);
          indent_string (contents, indent + tabstop);
          g_string_append (contents, str);
          g_free (str);

          g_menu_markup_print_string (contents, menu, indent + 2 * tabstop, tabstop);

          indent_string (contents, indent + tabstop);
          g_string_append (contents, "</link>\n");
          g_object_unref (menu);
        }
      g_object_unref (link_iter);

      if (contents->str[0])
        {
          indent_string (string, indent);
          g_string_append_printf (string, "<item%s>\n", attrs->str);
          g_string_append (string, contents->str);
          indent_string (string, indent);
          g_string_append (string, "</item>\n");
          need_nl = TRUE;
        }

      else
        {
          if (need_nl)
            g_string_append_c (string, '\n');

          indent_string (string, indent);
          g_string_append_printf (string, "<item%s/>\n", attrs->str);
          need_nl = FALSE;
        }

      g_string_free (contents, TRUE);
      g_string_free (attrs, TRUE);
    }

  return string;
}

/* TestItem {{{1 */

/* This utility struct is used by both the RandomMenu and MirrorMenu
 * class implementations below.
 */
typedef struct {
  GHashTable *attributes;
  GHashTable *links;
} TestItem;

static TestItem *
test_item_new (GHashTable *attributes,
               GHashTable *links)
{
  TestItem *item;

  item = g_slice_new (TestItem);
  item->attributes = g_hash_table_ref (attributes);
  item->links = g_hash_table_ref (links);

  return item;
}

static void
test_item_free (gpointer data)
{
  TestItem *item = data;

  g_hash_table_unref (item->attributes);
  g_hash_table_unref (item->links);

  g_slice_free (TestItem, item);
}

/* RandomMenu {{{1 */
#define MAX_ITEMS 5
#define TOP_ORDER 4

typedef struct {
  GMenuModel parent_instance;

  GSequence *items;
  gint order;
} RandomMenu;

typedef GMenuModelClass RandomMenuClass;

static GType random_menu_get_type (void);
G_DEFINE_TYPE (RandomMenu, random_menu, G_TYPE_MENU_MODEL)

static gboolean
random_menu_is_mutable (GMenuModel *model)
{
  return TRUE;
}

static gint
random_menu_get_n_items (GMenuModel *model)
{
  RandomMenu *menu = (RandomMenu *) model;

  return g_sequence_get_length (menu->items);
}

static void
random_menu_get_item_attributes (GMenuModel  *model,
                                 gint         position,
                                 GHashTable **table)
{
  RandomMenu *menu = (RandomMenu *) model;
  TestItem *item;

  item = g_sequence_get (g_sequence_get_iter_at_pos (menu->items, position));
  *table = g_hash_table_ref (item->attributes);
}

static void
random_menu_get_item_links (GMenuModel  *model,
                            gint         position,
                            GHashTable **table)
{
  RandomMenu *menu = (RandomMenu *) model;
  TestItem *item;

  item = g_sequence_get (g_sequence_get_iter_at_pos (menu->items, position));
  *table = g_hash_table_ref (item->links);
}

static void
random_menu_finalize (GObject *object)
{
  RandomMenu *menu = (RandomMenu *) object;

  g_sequence_free (menu->items);

  G_OBJECT_CLASS (random_menu_parent_class)
    ->finalize (object);
}

static void
random_menu_init (RandomMenu *menu)
{
}

static void
random_menu_class_init (GMenuModelClass *class)
{
  GObjectClass *object_class = G_OBJECT_CLASS (class);

  class->is_mutable = random_menu_is_mutable;
  class->get_n_items = random_menu_get_n_items;
  class->get_item_attributes = random_menu_get_item_attributes;
  class->get_item_links = random_menu_get_item_links;

  object_class->finalize = random_menu_finalize;
}

static RandomMenu * random_menu_new (GRand *rand, gint order);

static void
random_menu_change (RandomMenu *menu,
                    GRand      *rand)
{
  gint position, removes, adds;
  GSequenceIter *point;
  gint n_items;
  gint i;

  n_items = g_sequence_get_length (menu->items);

  do
    {
      position = g_rand_int_range (rand, 0, n_items + 1);
      removes = g_rand_int_range (rand, 0, n_items - position + 1);
      adds = g_rand_int_range (rand, 0, MAX_ITEMS - (n_items - removes) + 1);
    }
  while (removes == 0 && adds == 0);

  point = g_sequence_get_iter_at_pos (menu->items, position + removes);

  if (removes)
    {
      GSequenceIter *start;

      start = g_sequence_get_iter_at_pos (menu->items, position);
      g_sequence_remove_range (start, point);
    }

  for (i = 0; i < adds; i++)
    {
      const gchar *label;
      GHashTable *links;
      GHashTable *attributes;

      attributes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_variant_unref);
      links = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_object_unref);

      if (menu->order > 0 && g_rand_boolean (rand))
        {
          RandomMenu *child;
	  const gchar *subtype;

          child = random_menu_new (rand, menu->order - 1);

          if (g_rand_boolean (rand))
            {
              subtype = G_MENU_LINK_SECTION;
              /* label some section headers */
              if (g_rand_boolean (rand))
                label = "Section";
              else
                label = NULL;
            }
          else
            {
              /* label all submenus */
              subtype = G_MENU_LINK_SUBMENU;
              label = "Submenu";
            }

          g_hash_table_insert (links, g_strdup (subtype), child);
        }
      else
        /* label all terminals */
        label = "Menu Item";

      if (label)
        g_hash_table_insert (attributes, g_strdup ("label"), g_variant_ref_sink (g_variant_new_string (label)));

      g_sequence_insert_before (point, test_item_new (attributes, links));
      g_hash_table_unref (links);
      g_hash_table_unref (attributes);
    }

  g_menu_model_items_changed (G_MENU_MODEL (menu), position, removes, adds);
}

static RandomMenu *
random_menu_new (GRand *rand,
                 gint   order)
{
  RandomMenu *menu;

  menu = g_object_new (random_menu_get_type (), NULL);
  menu->items = g_sequence_new (test_item_free);
  menu->order = order;

  random_menu_change (menu, rand);

  return menu;
}

/* MirrorMenu {{{1 */
typedef struct {
  GMenuModel parent_instance;

  GMenuModel *clone_of;
  GSequence *items;
  gulong handler_id;
} MirrorMenu;

typedef GMenuModelClass MirrorMenuClass;

static GType mirror_menu_get_type (void);
G_DEFINE_TYPE (MirrorMenu, mirror_menu, G_TYPE_MENU_MODEL)

static gboolean
mirror_menu_is_mutable (GMenuModel *model)
{
  MirrorMenu *menu = (MirrorMenu *) model;

  return menu->handler_id != 0;
}

static gint
mirror_menu_get_n_items (GMenuModel *model)
{
  MirrorMenu *menu = (MirrorMenu *) model;

  return g_sequence_get_length (menu->items);
}

static void
mirror_menu_get_item_attributes (GMenuModel  *model,
                                 gint         position,
                                 GHashTable **table)
{
  MirrorMenu *menu = (MirrorMenu *) model;
  TestItem *item;

  item = g_sequence_get (g_sequence_get_iter_at_pos (menu->items, position));
  *table = g_hash_table_ref (item->attributes);
}

static void
mirror_menu_get_item_links (GMenuModel  *model,
                            gint         position,
                            GHashTable **table)
{
  MirrorMenu *menu = (MirrorMenu *) model;
  TestItem *item;

  item = g_sequence_get (g_sequence_get_iter_at_pos (menu->items, position));
  *table = g_hash_table_ref (item->links);
}

static void
mirror_menu_finalize (GObject *object)
{
  MirrorMenu *menu = (MirrorMenu *) object;

  if (menu->handler_id)
    g_signal_handler_disconnect (menu->clone_of, menu->handler_id);

  g_sequence_free (menu->items);
  g_object_unref (menu->clone_of);

  G_OBJECT_CLASS (mirror_menu_parent_class)
    ->finalize (object);
}

static void
mirror_menu_init (MirrorMenu *menu)
{
}

static void
mirror_menu_class_init (GMenuModelClass *class)
{
  GObjectClass *object_class = G_OBJECT_CLASS (class);

  class->is_mutable = mirror_menu_is_mutable;
  class->get_n_items = mirror_menu_get_n_items;
  class->get_item_attributes = mirror_menu_get_item_attributes;
  class->get_item_links = mirror_menu_get_item_links;

  object_class->finalize = mirror_menu_finalize;
}

static MirrorMenu * mirror_menu_new (GMenuModel *clone_of);

static void
mirror_menu_changed (GMenuModel *model,
                     gint        position,
                     gint        removed,
                     gint        added,
                     gpointer    user_data)
{
  MirrorMenu *menu = user_data;
  GSequenceIter *point;
  gint i;

  g_assert (model == menu->clone_of);

  point = g_sequence_get_iter_at_pos (menu->items, position + removed);

  if (removed)
    {
      GSequenceIter *start;

      start = g_sequence_get_iter_at_pos (menu->items, position);
      g_sequence_remove_range (start, point);
    }

  for (i = position; i < position + added; i++)
    {
      GMenuAttributeIter *attr_iter;
      GMenuLinkIter *link_iter;
      GHashTable *links;
      GHashTable *attributes;
      const gchar *name;
      GMenuModel *child;
      GVariant *value;

      attributes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_variant_unref);
      links = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_object_unref);

      attr_iter = g_menu_model_iterate_item_attributes (model, i);
      while (g_menu_attribute_iter_get_next (attr_iter, &name, &value))
        {
          g_hash_table_insert (attributes, g_strdup (name), value);
        }
      g_object_unref (attr_iter);

      link_iter = g_menu_model_iterate_item_links (model, i);
      while (g_menu_link_iter_get_next (link_iter, &name, &child))
        {
          g_hash_table_insert (links, g_strdup (name), mirror_menu_new (child));
          g_object_unref (child);
        }
      g_object_unref (link_iter);

      g_sequence_insert_before (point, test_item_new (attributes, links));
      g_hash_table_unref (attributes);
      g_hash_table_unref (links);
    }

  g_menu_model_items_changed (G_MENU_MODEL (menu), position, removed, added);
}

static MirrorMenu *
mirror_menu_new (GMenuModel *clone_of)
{
  MirrorMenu *menu;

  menu = g_object_new (mirror_menu_get_type (), NULL);
  menu->items = g_sequence_new (test_item_free);
  menu->clone_of = g_object_ref (clone_of);

  if (g_menu_model_is_mutable (clone_of))
    menu->handler_id = g_signal_connect (clone_of, "items-changed", G_CALLBACK (mirror_menu_changed), menu);
  mirror_menu_changed (clone_of, 0, 0, g_menu_model_get_n_items (clone_of), menu);

  return menu;
}

/* check_menus_equal(), assert_menus_equal() {{{1 */
static gboolean
check_menus_equal (GMenuModel *a,
                   GMenuModel *b)
{
  gboolean equal = TRUE;
  gint a_n, b_n;
  gint i;

  a_n = g_menu_model_get_n_items (a);
  b_n = g_menu_model_get_n_items (b);

  if (a_n != b_n)
    return FALSE;

  for (i = 0; i < a_n; i++)
    {
      GMenuAttributeIter *attr_iter;
      GVariant *a_value, *b_value;
      GMenuLinkIter *link_iter;
      GMenuModel *a_menu, *b_menu;
      const gchar *name;

      attr_iter = g_menu_model_iterate_item_attributes (a, i);
      while (g_menu_attribute_iter_get_next (attr_iter, &name, &a_value))
        {
          b_value = g_menu_model_get_item_attribute_value (b, i, name, NULL);
          equal &= b_value && g_variant_equal (a_value, b_value);
          if (b_value)
            g_variant_unref (b_value);
          g_variant_unref (a_value);
        }
      g_object_unref (attr_iter);

      attr_iter = g_menu_model_iterate_item_attributes (b, i);
      while (g_menu_attribute_iter_get_next (attr_iter, &name, &b_value))
        {
          a_value = g_menu_model_get_item_attribute_value (a, i, name, NULL);
          equal &= a_value && g_variant_equal (a_value, b_value);
          if (a_value)
            g_variant_unref (a_value);
          g_variant_unref (b_value);
        }
      g_object_unref (attr_iter);

      link_iter = g_menu_model_iterate_item_links (a, i);
      while (g_menu_link_iter_get_next (link_iter, &name, &a_menu))
        {
          b_menu = g_menu_model_get_item_link (b, i, name);
          equal &= b_menu && check_menus_equal (a_menu, b_menu);
          if (b_menu)
            g_object_unref (b_menu);
          g_object_unref (a_menu);
        }
      g_object_unref (link_iter);

      link_iter = g_menu_model_iterate_item_links (b, i);
      while (g_menu_link_iter_get_next (link_iter, &name, &b_menu))
        {
          a_menu = g_menu_model_get_item_link (a, i, name);
          equal &= a_menu && check_menus_equal (a_menu, b_menu);
          if (a_menu)
            g_object_unref (a_menu);
          g_object_unref (b_menu);
        }
      g_object_unref (link_iter);
    }

  return equal;
}

static void
assert_menus_equal (GMenuModel *a,
                    GMenuModel *b)
{
  if (!check_menus_equal (a, b))
    {
      GString *string;

      string = g_string_new ("\n  <a>\n");
      g_menu_markup_print_string (string, G_MENU_MODEL (a), 4, 2);
      g_string_append (string, "  </a>\n\n-------------\n  <b>\n");
      g_menu_markup_print_string (string, G_MENU_MODEL (b), 4, 2);
      g_string_append (string, "  </b>\n");
      g_error ("%s", string->str);
    }
}

static void
assert_menuitem_equal (GMenuItem  *item,
                       GMenuModel *model,
                       gint        index)
{
  GMenuAttributeIter *attr_iter;
  GMenuLinkIter *link_iter;
  const gchar *name;
  GVariant *value;
  GMenuModel *linked_model;

  /* NOTE we can't yet test whether item has attributes or links that
   * are not in the model, because there's no iterator API for menu
   * items */

  attr_iter = g_menu_model_iterate_item_attributes (model, index);
  while (g_menu_attribute_iter_get_next (attr_iter, &name, &value))
    {
      GVariant *item_value;

      item_value = g_menu_item_get_attribute_value (item, name, g_variant_get_type (value));
      g_assert (item_value && g_variant_equal (item_value, value));

      g_variant_unref (item_value);
      g_variant_unref (value);
    }

  link_iter = g_menu_model_iterate_item_links (model, index);
  while (g_menu_link_iter_get_next (link_iter, &name, &linked_model))
    {
      GMenuModel *item_linked_model;

      item_linked_model = g_menu_item_get_link (item, name);
      g_assert (linked_model == item_linked_model);

      g_object_unref (item_linked_model);
      g_object_unref (linked_model);
    }

  g_object_unref (attr_iter);
  g_object_unref (link_iter);
}

/* Test cases {{{1 */
static void
test_equality (void)
{
  GRand *randa, *randb;
  guint32 seed;
  gint i;

  seed = g_test_rand_int ();

  randa = g_rand_new_with_seed (seed);
  randb = g_rand_new_with_seed (seed);

  for (i = 0; i < 500; i++)
    {
      RandomMenu *a, *b;

      a = random_menu_new (randa, TOP_ORDER);
      b = random_menu_new (randb, TOP_ORDER);
      assert_menus_equal (G_MENU_MODEL (a), G_MENU_MODEL (b));
      g_object_unref (b);
      g_object_unref (a);
    }

  g_rand_int (randa);

  for (i = 0; i < 500;)
    {
      RandomMenu *a, *b;

      a = random_menu_new (randa, TOP_ORDER);
      b = random_menu_new (randb, TOP_ORDER);
      if (check_menus_equal (G_MENU_MODEL (a), G_MENU_MODEL (b)))
        {
          /* by chance, they may really be equal.  double check. */
          GString *as, *bs;

          as = g_menu_markup_print_string (NULL, G_MENU_MODEL (a), 4, 2);
          bs = g_menu_markup_print_string (NULL, G_MENU_MODEL (b), 4, 2);
          g_assert_cmpstr (as->str, ==, bs->str);
          g_string_free (bs, TRUE);
          g_string_free (as, TRUE);

          /* we're here because randa and randb just generated equal
           * menus.  they may do it again, so throw away randb and make
           * a fresh one.
           */
          g_rand_free (randb);
          randb = g_rand_new_with_seed (g_rand_int (randa));
        }
      else
        /* make sure we get enough unequals (ie: no GRand failure) */
        i++;

      g_object_unref (b);
      g_object_unref (a);
    }

  g_rand_free (randb);
  g_rand_free (randa);
}

static void
test_random (void)
{
  RandomMenu *random;
  MirrorMenu *mirror;
  GRand *rand;
  gint i;

  rand = g_rand_new_with_seed (g_test_rand_int ());
  random = random_menu_new (rand, TOP_ORDER);
  mirror = mirror_menu_new (G_MENU_MODEL (random));

  for (i = 0; i < 500; i++)
    {
      assert_menus_equal (G_MENU_MODEL (random), G_MENU_MODEL (mirror));
      random_menu_change (random, rand);
    }

  g_object_unref (mirror);
  g_object_unref (random);

  g_rand_free (rand);
}

typedef struct
{
  GDBusConnection *client_connection;
  GDBusConnection *server_connection;
  GDBusServer *server;

  GThread *service_thread;
  /* Protects server_connection and service_loop. */
  GMutex service_loop_lock;
  GCond service_loop_cond;

  GMainLoop *service_loop;
} PeerConnection;

static gboolean
on_new_connection (GDBusServer *server,
                   GDBusConnection *connection,
                   gpointer user_data)
{
  PeerConnection *data = user_data;

  g_mutex_lock (&data->service_loop_lock);
  data->server_connection = g_object_ref (connection);
  g_cond_broadcast (&data->service_loop_cond);
  g_mutex_unlock (&data->service_loop_lock);

  return TRUE;
}

static void
create_service_loop (GMainContext   *service_context,
                     PeerConnection *data)
{
  g_assert (data->service_loop == NULL);
  g_mutex_lock (&data->service_loop_lock);
  data->service_loop = g_main_loop_new (service_context, FALSE);
  g_cond_broadcast (&data->service_loop_cond);
  g_mutex_unlock (&data->service_loop_lock);
}

static void
teardown_service_loop (PeerConnection *data)
{
  g_mutex_lock (&data->service_loop_lock);
  g_clear_pointer (&data->service_loop, g_main_loop_unref);
  g_mutex_unlock (&data->service_loop_lock);
}

static void
await_service_loop (PeerConnection *data)
{
  g_mutex_lock (&data->service_loop_lock);
  while (data->service_loop == NULL)
    g_cond_wait (&data->service_loop_cond, &data->service_loop_lock);
  g_mutex_unlock (&data->service_loop_lock);
}

static void
await_server_connection (PeerConnection *data)
{
  g_mutex_lock (&data->service_loop_lock);
  while (data->server_connection == NULL)
    g_cond_wait (&data->service_loop_cond, &data->service_loop_lock);
  g_mutex_unlock (&data->service_loop_lock);
}

static gpointer
service_thread_func (gpointer user_data)
{
  PeerConnection *data = user_data;
  GMainContext *service_context;
  GError *error;
  gchar *address;
  gchar *tmpdir;
  GDBusServerFlags flags;
  gchar *guid;

  service_context = g_main_context_new ();
  g_main_context_push_thread_default (service_context);

  tmpdir = NULL;
  flags = G_DBUS_SERVER_FLAGS_NONE;

#ifdef G_OS_UNIX
  if (g_unix_socket_address_abstract_names_supported ())
    address = g_strdup ("unix:tmpdir=/tmp/test-dbus-peer");
  else
    {
      tmpdir = g_dir_make_tmp ("test-dbus-peer-XXXXXX", NULL);
      address = g_strdup_printf ("unix:tmpdir=%s", tmpdir);
    }
#else
  address = g_strdup ("nonce-tcp:");
  flags |= G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS;
#endif

  guid = g_dbus_generate_guid ();

  error = NULL;
  data->server = g_dbus_server_new_sync (address,
                                         flags,
                                         guid,
                                         NULL,
                                         NULL,
                                         &error);
  g_assert_no_error (error);
  g_free (address);
  g_free (guid);

  g_signal_connect (data->server,
                    "new-connection",
                    G_CALLBACK (on_new_connection),
                    data);

  g_dbus_server_start (data->server);

  create_service_loop (service_context, data);
  g_main_loop_run (data->service_loop);

  g_main_context_pop_thread_default (service_context);

  teardown_service_loop (data);
  g_main_context_unref (service_context);

  if (tmpdir)
    {
      g_rmdir (tmpdir);
      g_free (tmpdir);
    }

  return NULL;
}

static void
peer_connection_up (PeerConnection *data)
{
  GError *error;

  memset (data, '\0', sizeof (PeerConnection));

  g_mutex_init (&data->service_loop_lock);
  g_cond_init (&data->service_loop_cond);

  /* bring up a server - we run the server in a different thread to
     avoid deadlocks */
  data->service_thread = g_thread_new ("test_dbus_peer",
                                       service_thread_func,
                                       data);
  await_service_loop (data);
  g_assert (data->server != NULL);

  /* bring up a connection and accept it */
  error = NULL;
  data->client_connection =
    g_dbus_connection_new_for_address_sync (g_dbus_server_get_client_address (data->server),
                                            G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
                                            NULL, /* GDBusAuthObserver */
                                            NULL, /* cancellable */
                                            &error);
  g_assert_no_error (error);
  g_assert (data->client_connection != NULL);
  await_server_connection (data);
}

static void
peer_connection_down (PeerConnection *data)
{
  g_object_unref (data->client_connection);
  g_object_unref (data->server_connection);

  g_dbus_server_stop (data->server);
  g_object_unref (data->server);

  g_main_loop_quit (data->service_loop);
  g_thread_join (data->service_thread);

  g_mutex_clear (&data->service_loop_lock);
  g_cond_clear (&data->service_loop_cond);
}

struct roundtrip_state
{
  RandomMenu *random;
  MirrorMenu *proxy_mirror;
  GDBusMenuModel *proxy;
  GMainLoop *loop;
  GRand *rand;
  gint success;
  gint count;
};

static gboolean
roundtrip_step (gpointer data)
{
  struct roundtrip_state *state = data;

  if (check_menus_equal (G_MENU_MODEL (state->random), G_MENU_MODEL (state->proxy)) &&
      check_menus_equal (G_MENU_MODEL (state->random), G_MENU_MODEL (state->proxy_mirror)))
    {
      state->success++;
      state->count = 0;

      if (state->success < 100)
        random_menu_change (state->random, state->rand);
      else
        g_main_loop_quit (state->loop);
    }
  else if (state->count == 100)
    {
      assert_menus_equal (G_MENU_MODEL (state->random), G_MENU_MODEL (state->proxy));
      g_assert_not_reached ();
    }
  else
    state->count++;

  return G_SOURCE_CONTINUE;
}

static void
do_roundtrip (GDBusConnection *exporter_connection,
              GDBusConnection *proxy_connection)
{
  struct roundtrip_state state;
  guint export_id;
  guint id;

  state.rand = g_rand_new_with_seed (g_test_rand_int ());

  state.random = random_menu_new (state.rand, 2);
  export_id = g_dbus_connection_export_menu_model (exporter_connection,
                                                   "/",
                                                   G_MENU_MODEL (state.random),
                                                   NULL);
  state.proxy = g_dbus_menu_model_get (proxy_connection,
                                       g_dbus_connection_get_unique_name (proxy_connection),
                                       "/");
  state.proxy_mirror = mirror_menu_new (G_MENU_MODEL (state.proxy));
  state.count = 0;
  state.success = 0;

  id = g_timeout_add (10, roundtrip_step, &state);

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

  g_main_loop_unref (state.loop);
  g_source_remove (id);
  g_object_unref (state.proxy);
  g_dbus_connection_unexport_menu_model (exporter_connection, export_id);
  g_object_unref (state.random);
  g_object_unref (state.proxy_mirror);
  g_rand_free (state.rand);
}

static void
test_dbus_roundtrip (void)
{
  GDBusConnection *bus;

  bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
  do_roundtrip (bus, bus);
  g_object_unref (bus);
}

static void
test_dbus_peer_roundtrip (void)
{
#ifdef _GLIB_ADDRESS_SANITIZER
  g_test_incomplete ("FIXME: Leaks a GCancellableSource, see glib#2313");
  (void) peer_connection_up;
  (void) peer_connection_down;
#else
  PeerConnection peer;

  peer_connection_up (&peer);
  do_roundtrip (peer.server_connection, peer.client_connection);
  peer_connection_down (&peer);
#endif
}

static gint items_changed_count;

static void
items_changed (GMenuModel *model,
               gint        position,
               gint        removed,
               gint        added,
               gpointer    data)
{
  items_changed_count++;
}

static gboolean
stop_loop (gpointer data)
{
  GMainLoop *loop = data;

  g_main_loop_quit (loop);

  return G_SOURCE_REMOVE;
}

static void
do_subscriptions (GDBusConnection *exporter_connection,
                  GDBusConnection *proxy_connection)
{
  GMenu *menu;
  GDBusMenuModel *proxy;
  GMainLoop *loop;
  GError *error = NULL;
  guint export_id;
  guint timeout_id;

  timeout_id = add_timeout (60);
  loop = g_main_loop_new (NULL, FALSE);

  menu = g_menu_new ();

  export_id = g_dbus_connection_export_menu_model (exporter_connection,
                                                   "/",
                                                   G_MENU_MODEL (menu),
                                                   &error);
  g_assert_no_error (error);

  proxy = g_dbus_menu_model_get (proxy_connection,
                                 g_dbus_connection_get_unique_name (proxy_connection),
                                 "/");
  items_changed_count = 0;
  g_signal_connect (proxy, "items-changed",
                    G_CALLBACK (items_changed), NULL);

  g_menu_append (menu, "item1", NULL);
  g_menu_append (menu, "item2", NULL);
  g_menu_append (menu, "item3", NULL);

  g_assert_cmpint (items_changed_count, ==, 0);

  /* We don't subscribe to change-notification until we look at the items */
  g_timeout_add (100, stop_loop, loop);
  g_main_loop_run (loop);

  /* Looking at the items triggers subscription */
  g_menu_model_get_n_items (G_MENU_MODEL (proxy));

  while (items_changed_count < 1)
    g_main_context_iteration (NULL, TRUE);

  /* We get all three items in one batch */
  g_assert_cmpint (items_changed_count, ==, 1);
  g_assert_cmpint (g_menu_model_get_n_items (G_MENU_MODEL (proxy)), ==, 3);

  /* If we wait, we don't get any more */
  g_timeout_add (100, stop_loop, loop);
  g_main_loop_run (loop);
  g_assert_cmpint (items_changed_count, ==, 1);
  g_assert_cmpint (g_menu_model_get_n_items (G_MENU_MODEL (proxy)), ==, 3);

  /* Now we're subscribed, we get changes individually */
  g_menu_append (menu, "item4", NULL);
  g_menu_append (menu, "item5", NULL);
  g_menu_append (menu, "item6", NULL);
  g_menu_remove (menu, 0);
  g_menu_remove (menu, 0);

  while (items_changed_count < 6)
    g_main_context_iteration (NULL, TRUE);

  g_assert_cmpint (items_changed_count, ==, 6);

  g_assert_cmpint (g_menu_model_get_n_items (G_MENU_MODEL (proxy)), ==, 4);

  /* After destroying the proxy and waiting a bit, we don't get any more
   * items-changed signals */
  g_object_unref (proxy);

  g_timeout_add (100, stop_loop, loop);
  g_main_loop_run (loop);

  g_menu_remove (menu, 0);
  g_menu_remove (menu, 0);

  g_timeout_add (100, stop_loop, loop);
  g_main_loop_run (loop);

  g_assert_cmpint (items_changed_count, ==, 6);

  g_dbus_connection_unexport_menu_model (exporter_connection, export_id);
  g_object_unref (menu);

  g_main_loop_unref (loop);
  cancel_timeout (timeout_id);
}

static void
test_dbus_subscriptions (void)
{
  GDBusConnection *bus;

  bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
  do_subscriptions (bus, bus);
  g_object_unref (bus);
}

static void
test_dbus_peer_subscriptions (void)
{
#ifdef _GLIB_ADDRESS_SANITIZER
  g_test_incomplete ("FIXME: Leaks a GCancellableSource, see glib#2313");
  (void) peer_connection_up;
  (void) peer_connection_down;
#else
  PeerConnection peer;

  peer_connection_up (&peer);
  do_subscriptions (peer.server_connection, peer.client_connection);
  peer_connection_down (&peer);
#endif
}

static gpointer
do_modify (gpointer data)
{
  RandomMenu *menu = data;
  GRand *rand;
  gint i;

  rand = g_rand_new_with_seed (g_test_rand_int ());

  for (i = 0; i < 10000; i++)
    {
      random_menu_change (menu, rand);
    }

  g_rand_free (rand);

  return NULL;
}

static gpointer
do_export (gpointer data)
{
  GMenuModel *menu = data;
  gint i;
  GDBusConnection *bus;
  gchar *path;
  GError *error = NULL;
  guint id;

  bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
  path = g_strdup_printf ("/%p", data);

  for (i = 0; i < 10000; i++)
    {
      id = g_dbus_connection_export_menu_model (bus, path, menu, &error);
      g_assert_no_error (error);
      g_dbus_connection_unexport_menu_model (bus, id);
      while (g_main_context_iteration (NULL, FALSE));
    }

  g_free (path);

  g_object_unref (bus);

  return NULL;
}

static void
test_dbus_threaded (void)
{
  RandomMenu *menu[10];
  GThread *call[10];
  GThread *export[10];
  gint i;

  for (i = 0; i < 10; i++)
    {
      GRand *rand = g_rand_new_with_seed (g_test_rand_int ());
      menu[i] = random_menu_new (rand, 2);
      call[i] = g_thread_new ("call", do_modify, menu[i]);
      export[i] = g_thread_new ("export", do_export, menu[i]);
      g_rand_free (rand);
    }

  for (i = 0; i < 10; i++)
    {
      g_thread_join (call[i]);
      g_thread_join (export[i]);
    }

  for (i = 0; i < 10; i++)
    g_object_unref (menu[i]);
}

static void
test_attributes (void)
{
  GMenu *menu;
  GMenuItem *item;
  GVariant *v;

  menu = g_menu_new ();

  item = g_menu_item_new ("test", NULL);
  g_menu_item_set_attribute_value (item, "boolean", g_variant_new_boolean (FALSE));
  g_menu_item_set_attribute_value (item, "string", g_variant_new_string ("bla"));

  g_menu_item_set_attribute (item, "double", "d", 1.5);
  v = g_variant_new_parsed ("[('one', 1), ('two', %i), (%s, 3)]", 2, "three");
  g_menu_item_set_attribute_value (item, "complex", v);
  g_menu_item_set_attribute_value (item, "test-123", g_variant_new_string ("test-123"));

  g_menu_append_item (menu, item);

  g_menu_item_set_attribute (item, "double", "d", G_PI);

  g_assert_cmpint (g_menu_model_get_n_items (G_MENU_MODEL (menu)), ==, 1);

  v = g_menu_model_get_item_attribute_value (G_MENU_MODEL (menu), 0, "boolean", NULL);
  g_assert (g_variant_is_of_type (v, G_VARIANT_TYPE_BOOLEAN));
  g_variant_unref (v);

  v = g_menu_model_get_item_attribute_value (G_MENU_MODEL (menu), 0, "string", NULL);
  g_assert (g_variant_is_of_type (v, G_VARIANT_TYPE_STRING));
  g_variant_unref (v);

  v = g_menu_model_get_item_attribute_value (G_MENU_MODEL (menu), 0, "double", NULL);
  g_assert (g_variant_is_of_type (v, G_VARIANT_TYPE_DOUBLE));
  g_variant_unref (v);

  v = g_menu_model_get_item_attribute_value (G_MENU_MODEL (menu), 0, "complex", NULL);
  g_assert (g_variant_is_of_type (v, G_VARIANT_TYPE("a(si)")));
  g_variant_unref (v);

  g_menu_remove_all (menu);

  g_object_unref (menu);
  g_object_unref (item);
}

static void
test_attribute_iter (void)
{
  GMenu *menu;
  GMenuItem *item;
  const gchar *name;
  GVariant *v;
  GMenuAttributeIter *iter;
  GHashTable *found;

  menu = g_menu_new ();

  item = g_menu_item_new ("test", NULL);
  g_menu_item_set_attribute_value (item, "boolean", g_variant_new_boolean (FALSE));
  g_menu_item_set_attribute_value (item, "string", g_variant_new_string ("bla"));

  g_menu_item_set_attribute (item, "double", "d", 1.5);
  v = g_variant_new_parsed ("[('one', 1), ('two', %i), (%s, 3)]", 2, "three");
  g_menu_item_set_attribute_value (item, "complex", v);
  g_menu_item_set_attribute_value (item, "test-123", g_variant_new_string ("test-123"));

  g_menu_append_item (menu, item);

  g_menu_item_set_attribute (item, "double", "d", G_PI);

  g_assert_cmpint (g_menu_model_get_n_items (G_MENU_MODEL (menu)), ==, 1);

  found = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)g_variant_unref); 

  iter = g_menu_model_iterate_item_attributes (G_MENU_MODEL (menu), 0);
  while (g_menu_attribute_iter_get_next (iter, &name, &v))
    g_hash_table_insert (found, g_strdup (name), v);

  g_assert_cmpint (g_hash_table_size (found), ==, 6);
  
  v = g_hash_table_lookup (found, "label");
  g_assert (g_variant_is_of_type (v, G_VARIANT_TYPE_STRING));

  v = g_hash_table_lookup (found, "boolean");
  g_assert (g_variant_is_of_type (v, G_VARIANT_TYPE_BOOLEAN));
 
  v = g_hash_table_lookup (found, "string");
  g_assert (g_variant_is_of_type (v, G_VARIANT_TYPE_STRING));

  v = g_hash_table_lookup (found, "double");
  g_assert (g_variant_is_of_type (v, G_VARIANT_TYPE_DOUBLE));

  v = g_hash_table_lookup (found, "complex");
  g_assert (g_variant_is_of_type (v, G_VARIANT_TYPE("a(si)")));

  v = g_hash_table_lookup (found, "test-123");
  g_assert (g_variant_is_of_type (v, G_VARIANT_TYPE_STRING));

  g_hash_table_unref (found);

  g_menu_remove_all (menu);

  g_object_unref (menu);
  g_object_unref (item);
}

static void
test_links (void)
{
  GMenu *menu;
  GMenuModel *m;
  GMenuModel *x;
  GMenuItem *item;

  m = G_MENU_MODEL (g_menu_new ());
  g_menu_append (G_MENU (m), "test", NULL);

  menu = g_menu_new ();

  item = g_menu_item_new ("test2", NULL);
  g_menu_item_set_link (item, "submenu", m);
  g_menu_prepend_item (menu, item);

  item = g_menu_item_new ("test1", NULL);
  g_menu_item_set_link (item, "section", m);
  g_menu_insert_item (menu, 0, item);

  item = g_menu_item_new ("test3", NULL);
  g_menu_item_set_link (item, "wallet", m);
  g_menu_insert_item (menu, 1000, item);

  item = g_menu_item_new ("test4", NULL);
  g_menu_item_set_link (item, "purse", m);
  g_menu_item_set_link (item, "purse", NULL);
  g_menu_append_item (menu, item);

  g_assert_cmpint (g_menu_model_get_n_items (G_MENU_MODEL (menu)), ==, 4);

  x = g_menu_model_get_item_link (G_MENU_MODEL (menu), 0, "section");
  g_assert (x == m);
  g_object_unref (x);

  x = g_menu_model_get_item_link (G_MENU_MODEL (menu), 1, "submenu");
  g_assert (x == m);
  g_object_unref (x);

  x = g_menu_model_get_item_link (G_MENU_MODEL (menu), 2, "wallet");
  g_assert (x == m);
  g_object_unref (x);

  x = g_menu_model_get_item_link (G_MENU_MODEL (menu), 3, "purse");
  g_assert (x == NULL);

  g_object_unref (m);
  g_object_unref (menu);
}

static void
test_mutable (void)
{
  GMenu *menu;

  menu = g_menu_new ();
  g_menu_append (menu, "test", "test");

  g_assert (g_menu_model_is_mutable (G_MENU_MODEL (menu)));
  g_menu_freeze (menu);
  g_assert (!g_menu_model_is_mutable (G_MENU_MODEL (menu)));

  g_object_unref (menu);
}

static void
test_convenience (void)
{
  GMenu *m1, *m2;
  GMenu *sub;
  GMenuItem *item;

  m1 = g_menu_new ();
  m2 = g_menu_new ();
  sub = g_menu_new ();

  g_menu_prepend (m1, "label1", "do::something");
  g_menu_insert (m2, 0, "label1", "do::something");

  g_menu_append (m1, "label2", "do::somethingelse");
  g_menu_insert (m2, -1, "label2", "do::somethingelse");

  g_menu_insert_section (m1, 10, "label3", G_MENU_MODEL (sub));
  item = g_menu_item_new_section ("label3", G_MENU_MODEL (sub));
  g_menu_insert_item (m2, 10, item);
  g_object_unref (item);

  g_menu_prepend_section (m1, "label4", G_MENU_MODEL (sub));
  g_menu_insert_section (m2, 0, "label4", G_MENU_MODEL (sub));

  g_menu_append_section (m1, "label5", G_MENU_MODEL (sub));
  g_menu_insert_section (m2, -1, "label5", G_MENU_MODEL (sub));

  g_menu_insert_submenu (m1, 5, "label6", G_MENU_MODEL (sub));
  item = g_menu_item_new_submenu ("label6", G_MENU_MODEL (sub));
  g_menu_insert_item (m2, 5, item);
  g_object_unref (item);

  g_menu_prepend_submenu (m1, "label7", G_MENU_MODEL (sub));
  g_menu_insert_submenu (m2, 0, "label7", G_MENU_MODEL (sub));

  g_menu_append_submenu (m1, "label8", G_MENU_MODEL (sub));
  g_menu_insert_submenu (m2, -1, "label8", G_MENU_MODEL (sub));

  assert_menus_equal (G_MENU_MODEL (m1), G_MENU_MODEL (m2));

  g_object_unref (m1);
  g_object_unref (m2);
}

static void
test_menuitem (void)
{
  GMenu *menu;
  GMenu *submenu;
  GMenuItem *item;
  GIcon *icon;
  gboolean b;
  gchar *s;

  menu = g_menu_new ();
  submenu = g_menu_new ();

  item = g_menu_item_new ("label", "action");
  g_menu_item_set_attribute (item, "attribute", "b", TRUE);
  g_menu_item_set_link (item, G_MENU_LINK_SUBMENU, G_MENU_MODEL (submenu));
  g_menu_append_item (menu, item);

  icon = g_themed_icon_new ("bla");
  g_menu_item_set_icon (item, icon);
  g_object_unref (icon);

  g_assert (g_menu_item_get_attribute (item, "attribute", "b", &b));
  g_assert (b);

  g_menu_item_set_action_and_target (item, "action", "(bs)", TRUE, "string");
  g_assert (g_menu_item_get_attribute (item, "target", "(bs)", &b, &s));
  g_assert (b);
  g_assert_cmpstr (s, ==, "string");
  g_free (s);

  g_object_unref (item);

  item = g_menu_item_new_from_model (G_MENU_MODEL (menu), 0);
  assert_menuitem_equal (item, G_MENU_MODEL (menu), 0);
  g_object_unref (item);

  g_object_unref (menu);
  g_object_unref (submenu);
}

/* Epilogue {{{1 */
int
main (int argc, char **argv)
{
  gboolean ret;

  g_test_init (&argc, &argv, NULL);

  session_bus_up ();

  g_test_add_func ("/gmenu/equality", test_equality);
  g_test_add_func ("/gmenu/random", test_random);
  g_test_add_func ("/gmenu/dbus/roundtrip", test_dbus_roundtrip);
  g_test_add_func ("/gmenu/dbus/subscriptions", test_dbus_subscriptions);
  g_test_add_func ("/gmenu/dbus/threaded", test_dbus_threaded);
  g_test_add_func ("/gmenu/dbus/peer/roundtrip", test_dbus_peer_roundtrip);
  g_test_add_func ("/gmenu/dbus/peer/subscriptions", test_dbus_peer_subscriptions);
  g_test_add_func ("/gmenu/attributes", test_attributes);
  g_test_add_func ("/gmenu/attributes/iterate", test_attribute_iter);
  g_test_add_func ("/gmenu/links", test_links);
  g_test_add_func ("/gmenu/mutable", test_mutable);
  g_test_add_func ("/gmenu/convenience", test_convenience);
  g_test_add_func ("/gmenu/menuitem", test_menuitem);

  ret = g_test_run ();

  session_bus_down ();

  return ret;
}
/* vim:set foldmethod=marker: */
