/*
 * Copyright © 2011 Canonical Ltd.
 *
 * This library is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * licence, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
 * USA.
 *
 * Author: Ryan Lortie <desrt@desrt.ca>
 */

#include "config.h"

#include "gdbusmenumodel.h"

#include "gmenumodel.h"

/* Prelude {{{1 */

/**
 * SECTION:gdbusmenumodel
 * @title: GDBusMenuModel
 * @short_description: A D-Bus GMenuModel implementation
 * @see_also: <link linkend="gio-GMenuModel-exporter">GMenuModel Exporter</link>
 *
 * #GDBusMenuModel is an implementation of #GMenuModel that can be used
 * as a proxy for a menu model that is exported over D-Bus with
 * g_dbus_connection_export_menu_model().
 */

/*
 * There are 3 main (quasi-)classes involved here:
 *
 *   - GDBusMenuPath
 *   - GDBusMenuGroup
 *   - GDBusMenuModel
 *
 * Each of these classes exists as a parameterised singleton keyed to a
 * particular thing:
 *
 *   - GDBusMenuPath represents a D-Bus object path on a particular
 *     unique bus name on a particular GDBusConnection and in a
 *     particular GMainContext.
 *
 *   - GDBusMenuGroup represents a particular group on a particular
 *     GDBusMenuPath.
 *
 *   - GDBusMenuModel represents a particular menu within a particular
 *     GDBusMenuGroup.
 *
 * There are also two (and a half) utility structs:
 *
 *  - PathIdentifier and ConstPathIdentifier
 *  - GDBusMenuModelItem
 *
 * PathIdentifier is the 4-tuple of (GMainContext, GDBusConnection,
 * unique name, object path) that uniquely identifies a particular
 * GDBusMenuPath.  It holds ownership on each of these things, so we
 * have a ConstPathIdentifier variant that does not.
 *
 * We have a 3-level hierarchy of hashtables:
 *
 *   - a global hashtable (g_dbus_menu_paths) maps from PathIdentifier
 *     to GDBusMenuPath
 *
 *   - each GDBusMenuPath has a hashtable mapping from guint (group
 *     number) to GDBusMenuGroup
 *
 *   - each GDBusMenuGroup has a hashtable mapping from guint (menu
 *     number) to GDBusMenuModel.
 *
 * In this way, each quintuplet of (connection, bus name, object path,
 * group id, menu id) maps to a single GDBusMenuModel instance that can be
 * located via 3 hashtable lookups.
 *
 * All of the 3 classes are refcounted (GDBusMenuPath and
 * GDBusMenuGroup manually, and GDBusMenuModel by virtue of being a
 * GObject).  The hashtables do not hold references -- rather, when the
 * last reference is dropped, the object is removed from the hashtable.
 *
 * The hard references go in the other direction: GDBusMenuModel is created
 * as the user requests it and only exists as long as the user holds a
 * reference on it.  GDBusMenuModel holds a reference on the GDBusMenuGroup
 * from which it came. GDBusMenuGroup holds a reference on
 * GDBusMenuPath.
 *
 * In addition to refcounts, each object has an 'active' variable (ints
 * for GDBusMenuPath and GDBusMenuGroup, boolean for GDBusMenuModel).
 *
 *   - GDBusMenuModel is inactive when created and becomes active only when
 *     first queried for information.  This prevents extra work from
 *     happening just by someone acquiring a GDBusMenuModel (and not
 *     actually trying to display it yet).
 *
 *   - The active count on GDBusMenuGroup is equal to the number of
 *     GDBusMenuModel instances in that group that are active.  When the
 *     active count transitions from 0 to 1, the group calls the 'Start'
 *     method on the service to begin monitoring that group.  When it
 *     drops from 1 to 0, the group calls the 'End' method to stop
 *     monitoring.
 *
 *   - The active count on GDBusMenuPath is equal to the number of
 *     GDBusMenuGroup instances on that path with a non-zero active
 *     count.  When the active count transitions from 0 to 1, the path
 *     sets up a signal subscription to monitor any changes.  The signal
 *     subscription is taken down when the active count transitions from
 *     1 to 0.
 *
 * When active, GDBusMenuPath gets incoming signals when changes occur.
 * If the change signal mentions a group for which we currently have an
 * active GDBusMenuGroup, the change signal is passed along to that
 * group.  If the group is inactive, the change signal is ignored.
 *
 * Most of the "work" occurs in GDBusMenuGroup.  In addition to the
 * hashtable of GDBusMenuModel instances, it keeps a hashtable of the actual
 * menu contents, each encoded as GSequence of GDBusMenuModelItem.  It
 * initially populates this table with the results of the "Start" method
 * call and then updates it according to incoming change signals.  If
 * the change signal mentions a menu for which we current have an active
 * GDBusMenuModel, the change signal is passed along to that model.  If the
 * model is inactive, the change signal is ignored.
 *
 * GDBusMenuModelItem is just a pair of hashtables, one for the attributes
 * and one for the links of the item.  Both map strings to GVariant
 * instances.  In the case of links, the GVariant has type '(uu)' and is
 * turned into a GDBusMenuModel at the point that the user pulls it through
 * the API.
 *
 * Following the "empty is the same as non-existent" rule, the hashtable
 * of GSequence of GDBusMenuModelItem holds NULL for empty menus.
 *
 * GDBusMenuModel contains very little functionality of its own.  It holds a
 * (weak) reference to the GSequence of GDBusMenuModelItem contained in the
 * GDBusMenuGroup.  It uses this GSequence to implement the GMenuModel
 * interface.  It also emits the "items-changed" signal if it is active
 * and it was told that the contents of the GSequence changed.
 */

typedef struct _GDBusMenuGroup GDBusMenuGroup;
typedef struct _GDBusMenuPath GDBusMenuPath;

static void                     g_dbus_menu_group_changed               (GDBusMenuGroup  *group,
                                                                         guint            menu_id,
                                                                         gint             position,
                                                                         gint             removed,
                                                                         GVariant        *added);
static void                     g_dbus_menu_model_changed               (GDBusMenuModel  *proxy,
                                                                         GSequence       *items,
                                                                         gint             position,
                                                                         gint             removed,
                                                                         gint             added);
static GDBusMenuGroup *         g_dbus_menu_group_get_from_path         (GDBusMenuPath   *path,
                                                                         guint            group_id);
static GDBusMenuModel *         g_dbus_menu_model_get_from_group        (GDBusMenuGroup  *group,
                                                                         guint            menu_id);

/* PathIdentifier {{{1 */
typedef struct
{
  GMainContext *context;
  GDBusConnection *connection;
  gchar *bus_name;
  gchar *object_path;
} PathIdentifier;

typedef const struct
{
  GMainContext *context;
  GDBusConnection *connection;
  const gchar *bus_name;
  const gchar *object_path;
} ConstPathIdentifier;

static guint
path_identifier_hash (gconstpointer data)
{
  ConstPathIdentifier *id = data;

  return g_str_hash (id->object_path);
}

static gboolean
path_identifier_equal (gconstpointer a,
                       gconstpointer b)
{
  ConstPathIdentifier *id_a = a;
  ConstPathIdentifier *id_b = b;

  return id_a->connection == id_b->connection &&
         g_str_equal (id_a->bus_name, id_b->bus_name) &&
         g_str_equal (id_a->object_path, id_b->object_path);
}

static void
path_identifier_free (PathIdentifier *id)
{
  g_main_context_unref (id->context);
  g_object_unref (id->connection);
  g_free (id->bus_name);
  g_free (id->object_path);

  g_slice_free (PathIdentifier, id);
}

static PathIdentifier *
path_identifier_new (ConstPathIdentifier *cid)
{
  PathIdentifier *id;

  id = g_slice_new (PathIdentifier);
  id->context = g_main_context_ref (cid->context);
  id->connection = g_object_ref (cid->connection);
  id->bus_name = g_strdup (cid->bus_name);
  id->object_path = g_strdup (cid->object_path);

  return id;
}

/* GDBusMenuPath {{{1 */

struct _GDBusMenuPath
{
  PathIdentifier *id;
  gint ref_count;

  GHashTable *groups;
  gint active;
  guint watch_id;
};

static GHashTable *g_dbus_menu_paths;

static GDBusMenuPath *
g_dbus_menu_path_ref (GDBusMenuPath *path)
{
  path->ref_count++;

  return path;
}

static void
g_dbus_menu_path_unref (GDBusMenuPath *path)
{
  if (--path->ref_count == 0)
    {
      g_hash_table_remove (g_dbus_menu_paths, path->id);
      g_hash_table_unref (path->groups);
      path_identifier_free (path->id);

      g_slice_free (GDBusMenuPath, path);
    }
}

static void
g_dbus_menu_path_signal (GDBusConnection *connection,
                         const gchar     *sender_name,
                         const gchar     *object_path,
                         const gchar     *interface_name,
                         const gchar     *signal_name,
                         GVariant        *parameters,
                         gpointer         user_data)
{
  GDBusMenuPath *path = user_data;
  GVariantIter *iter;
  guint group_id;
  guint menu_id;
  guint position;
  guint removes;
  GVariant *adds;

  if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(a(uuuuaa{sv}))")))
    return;

  g_variant_get (parameters, "(a(uuuuaa{sv}))", &iter);
  while (g_variant_iter_loop (iter, "(uuuu@aa{sv})", &group_id, &menu_id, &position, &removes, &adds))
    {
      GDBusMenuGroup *group;

      group = g_hash_table_lookup (path->groups, GINT_TO_POINTER (group_id));

      if (group != NULL)
        g_dbus_menu_group_changed (group, menu_id, position, removes, adds);
    }
  g_variant_iter_free (iter);
}

static void
g_dbus_menu_path_activate (GDBusMenuPath *path)
{
  if (path->active++ == 0)
    path->watch_id = g_dbus_connection_signal_subscribe (path->id->connection, path->id->bus_name,
                                                         "org.gtk.Menus", "Changed", path->id->object_path,
                                                         NULL, G_DBUS_SIGNAL_FLAGS_NONE,
                                                         g_dbus_menu_path_signal, path, NULL);
}

static void
g_dbus_menu_path_deactivate (GDBusMenuPath *path)
{
  if (--path->active == 0)
    g_dbus_connection_signal_unsubscribe (path->id->connection, path->watch_id);
}

static GDBusMenuPath *
g_dbus_menu_path_get (GMainContext    *context,
                      GDBusConnection *connection,
                      const gchar     *bus_name,
                      const gchar     *object_path)
{
  ConstPathIdentifier cid = { context, connection, bus_name, object_path };
  GDBusMenuPath *path;

  if (g_dbus_menu_paths == NULL)
    g_dbus_menu_paths = g_hash_table_new (path_identifier_hash, path_identifier_equal);

  path = g_hash_table_lookup (g_dbus_menu_paths, &cid);

  if (path == NULL)
    {
      path = g_slice_new (GDBusMenuPath);
      path->id = path_identifier_new (&cid);
      path->groups = g_hash_table_new (NULL, NULL);
      path->ref_count = 0;
      path->active = 0;

      g_hash_table_insert (g_dbus_menu_paths, path->id, path);
    }

  return g_dbus_menu_path_ref (path);
}

/* GDBusMenuGroup, GDBusMenuModelItem {{{1 */
typedef enum
{
  GROUP_OFFLINE,
  GROUP_PENDING,
  GROUP_ONLINE
} GroupStatus;

struct _GDBusMenuGroup
{
  GDBusMenuPath *path;
  guint id;

  GHashTable *proxies; /* uint -> unowned GDBusMenuModel */
  GHashTable *menus;   /* uint -> owned GSequence */
  gint ref_count;
  GroupStatus state;
  gint active;
};

typedef struct
{
  GHashTable *attributes;
  GHashTable *links;
} GDBusMenuModelItem;

static GDBusMenuGroup *
g_dbus_menu_group_ref (GDBusMenuGroup *group)
{
  group->ref_count++;

  return group;
}

static void
g_dbus_menu_group_unref (GDBusMenuGroup *group)
{
  if (--group->ref_count == 0)
    {
      g_assert (group->state == GROUP_OFFLINE);
      g_assert (group->active == 0);

      g_hash_table_remove (group->path->groups, GINT_TO_POINTER (group->id));
      g_hash_table_unref (group->proxies);
      g_hash_table_unref (group->menus);

      g_dbus_menu_path_unref (group->path);

      g_slice_free (GDBusMenuGroup, group);
    }
}

static void
g_dbus_menu_model_item_free (gpointer data)
{
  GDBusMenuModelItem *item = data;

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

  g_slice_free (GDBusMenuModelItem, item);
}

static GDBusMenuModelItem *
g_dbus_menu_group_create_item (GVariant *description)
{
  GDBusMenuModelItem *item;
  GVariantIter iter;
  const gchar *key;
  GVariant *value;

  item = g_slice_new (GDBusMenuModelItem);
  item->attributes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_variant_unref);
  item->links = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_variant_unref);

  g_variant_iter_init (&iter, description);
  while (g_variant_iter_loop (&iter, "{&sv}", &key, &value))
    if (key[0] == ':')
      /* key + 1 to skip the ':' */
      g_hash_table_insert (item->links, g_strdup (key + 1), g_variant_ref (value));
    else
      g_hash_table_insert (item->attributes, g_strdup (key), g_variant_ref (value));

  return item;
}

/*
 * GDBusMenuGroup can be in three states:
 *
 * OFFLINE: not subscribed to this group
 * PENDING: we made the call to subscribe to this group, but the result
 *          has not come back yet
 * ONLINE: we are fully subscribed
 *
 * We can get into some nasty situations where we make a call due to an
 * activation request but receive a deactivation request before the call
 * returns.  If another activation request occurs then we could risk
 * sending a Start request even though one is already in progress.  For
 * this reason, we have to carefully consider what to do in each of the
 * three states for each of the following situations:
 *
 *  - activation requested
 *  - deactivation requested
 *  - Start call finishes
 *
 * To simplify things a bit, we do not have a callback for the Stop
 * call.  We just send it and assume that it takes effect immediately.
 *
 * Activation requested:
 *   OFFLINE: make the Start call and transition to PENDING
 *   PENDING: do nothing -- call is already in progress.
 *   ONLINE: this should not be possible
 *
 * Deactivation requested:
 *   OFFLINE: this should not be possible
 *   PENDING: do nothing -- handle it when the Start call finishes
 *   ONLINE: send the Stop call and move to OFFLINE immediately
 *
 * Start call finishes:
 *   OFFLINE: this should not be possible
 *   PENDING:
 *     If we should be active (ie: active count > 0): move to ONLINE
 *     If not: send Stop call and move to OFFLINE immediately
 *   ONLINE: this should not be possible
 *
 * We have to take care with regards to signal subscriptions (ie:
 * activation of the GDBusMenuPath).  The signal subscription is always
 * established when transitioning from OFFLINE to PENDING and taken down
 * when transitioning to OFFLINE (from either PENDING or ONLINE).
 *
 * Since there are two places where we transition to OFFLINE, we split
 * that code out into a separate function.
 */
static void
g_dbus_menu_group_go_offline (GDBusMenuGroup *group)
{
  g_dbus_menu_path_deactivate (group->path);
  g_dbus_connection_call (group->path->id->connection,
                          group->path->id->bus_name,
                          group->path->id->object_path,
                          "org.gtk.Menus", "End",
                          g_variant_new_parsed ("([ %u ],)", group->id),
                          NULL, G_DBUS_CALL_FLAGS_NONE, -1,
                          NULL, NULL, NULL);
  group->state = GROUP_OFFLINE;
}


static void
g_dbus_menu_group_start_ready (GObject      *source_object,
                               GAsyncResult *result,
                               gpointer      user_data)
{
  GDBusConnection *connection = G_DBUS_CONNECTION (source_object);
  GDBusMenuGroup *group = user_data;
  GVariant *reply;

  g_assert (group->state == GROUP_PENDING);

  reply = g_dbus_connection_call_finish (connection, result, NULL);

  if (group->active)
    {
      group->state = GROUP_ONLINE;

      /* If we receive no reply, just act like we got an empty reply. */
      if (reply)
        {
          GVariantIter *iter;
          GVariant *items;
          guint group_id;
          guint menu_id;

          g_variant_get (reply, "(a(uuaa{sv}))", &iter);
          while (g_variant_iter_loop (iter, "(uu@aa{sv})", &group_id, &menu_id, &items))
            if (group_id == group->id)
              g_dbus_menu_group_changed (group, menu_id, 0, 0, items);
          g_variant_iter_free (iter);
        }
    }
  else
    g_dbus_menu_group_go_offline (group);

  if (reply)
    g_variant_unref (reply);

  g_dbus_menu_group_unref (group);
}

static void
g_dbus_menu_group_activate (GDBusMenuGroup *group)
{
  if (group->active++ == 0)
    {
      g_assert (group->state != GROUP_ONLINE);

      if (group->state == GROUP_OFFLINE)
        {
          g_dbus_menu_path_activate (group->path);

          g_dbus_connection_call (group->path->id->connection,
                                  group->path->id->bus_name,
                                  group->path->id->object_path,
                                  "org.gtk.Menus", "Start",
                                  g_variant_new_parsed ("([ %u ],)", group->id),
                                  G_VARIANT_TYPE ("(a(uuaa{sv}))"),
                                  G_DBUS_CALL_FLAGS_NONE, -1, NULL,
                                  g_dbus_menu_group_start_ready,
                                  g_dbus_menu_group_ref (group));
          group->state = GROUP_PENDING;
        }
    }
}

static void
g_dbus_menu_group_deactivate (GDBusMenuGroup *group)
{
  if (--group->active == 0)
    {
      g_assert (group->state != GROUP_OFFLINE);

      if (group->state == GROUP_ONLINE)
        {
          /* We are here because nobody is watching, so just free
           * everything and don't bother with the notifications.
           */
          g_hash_table_remove_all (group->menus);

          g_dbus_menu_group_go_offline (group);
        }
    }
}

static void
g_dbus_menu_group_changed (GDBusMenuGroup *group,
                           guint           menu_id,
                           gint            position,
                           gint            removed,
                           GVariant       *added)
{
  GSequenceIter *point;
  GVariantIter iter;
  GDBusMenuModel *proxy;
  GSequence *items;
  GVariant *item;
  gint n_added;

  /* We could have signals coming to us when we're not active (due to
   * some other process having subscribed to this group) or when we're
   * pending.  In both of those cases, we want to ignore the signal
   * since we'll get our own information when we call "Start" for
   * ourselves.
   */
  if (group->state != GROUP_ONLINE)
    return;

  items = g_hash_table_lookup (group->menus, GINT_TO_POINTER (menu_id));

  if (items == NULL)
    {
      items = g_sequence_new (g_dbus_menu_model_item_free);
      g_hash_table_insert (group->menus, GINT_TO_POINTER (menu_id), items);
    }

  point = g_sequence_get_iter_at_pos (items, position + removed);

  g_return_if_fail (point != NULL);

  if (removed)
    {
      GSequenceIter *start;

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

  n_added = g_variant_iter_init (&iter, added);
  while (g_variant_iter_loop (&iter, "@a{sv}", &item))
    g_sequence_insert_before (point, g_dbus_menu_group_create_item (item));

  if (g_sequence_get_length (items) == 0)
    {
      g_hash_table_remove (group->menus, GINT_TO_POINTER (menu_id));
      items = NULL;
    }

  if ((proxy = g_hash_table_lookup (group->proxies, GINT_TO_POINTER (menu_id))))
    g_dbus_menu_model_changed (proxy, items, position, removed, n_added);
}

static GDBusMenuGroup *
g_dbus_menu_group_get_from_path (GDBusMenuPath *path,
                                 guint          group_id)
{
  GDBusMenuGroup *group;

  group = g_hash_table_lookup (path->groups, GINT_TO_POINTER (group_id));

  if (group == NULL)
    {
      group = g_slice_new (GDBusMenuGroup);
      group->path = g_dbus_menu_path_ref (path);
      group->id = group_id;
      group->proxies = g_hash_table_new (NULL, NULL);
      group->menus = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) g_sequence_free);
      group->state = GROUP_OFFLINE;
      group->active = 0;
      group->ref_count = 0;

      g_hash_table_insert (path->groups, GINT_TO_POINTER (group->id), group);
    }

  return g_dbus_menu_group_ref (group);
}

static GDBusMenuGroup *
g_dbus_menu_group_get (GMainContext    *context,
                       GDBusConnection *connection,
                       const gchar     *bus_name,
                       const gchar     *object_path,
                       guint            group_id)
{
  GDBusMenuGroup *group;
  GDBusMenuPath *path;

  path = g_dbus_menu_path_get (context, connection, bus_name, object_path);
  group = g_dbus_menu_group_get_from_path (path, group_id);
  g_dbus_menu_path_unref (path);

  return group;
}

/* GDBusMenuModel {{{1 */

typedef GMenuModelClass GDBusMenuModelClass;
struct _GDBusMenuModel
{
  GMenuModel parent;

  GDBusMenuGroup *group;
  guint id;

  GSequence *items; /* unowned */
  gboolean active;
};

G_DEFINE_TYPE (GDBusMenuModel, g_dbus_menu_model, G_TYPE_MENU_MODEL)

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

static gint
g_dbus_menu_model_get_n_items (GMenuModel *model)
{
  GDBusMenuModel *proxy = G_DBUS_MENU_MODEL (model);

  if (!proxy->active)
    {
      g_dbus_menu_group_activate (proxy->group);
      proxy->active = TRUE;
    }

  return proxy->items ? g_sequence_get_length (proxy->items) : 0;
}

static void
g_dbus_menu_model_get_item_attributes (GMenuModel  *model,
                                       gint         item_index,
                                       GHashTable **table)
{
  GDBusMenuModel *proxy = G_DBUS_MENU_MODEL (model);
  GDBusMenuModelItem *item;
  GSequenceIter *iter;

  g_return_if_fail (proxy->active);
  g_return_if_fail (proxy->items);

  iter = g_sequence_get_iter_at_pos (proxy->items, item_index);
  g_return_if_fail (iter);

  item = g_sequence_get (iter);
  g_return_if_fail (item);

  *table = g_hash_table_ref (item->attributes);
}

static void
g_dbus_menu_model_get_item_links (GMenuModel  *model,
                                  gint         item_index,
                                  GHashTable **table)
{
  GDBusMenuModel *proxy = G_DBUS_MENU_MODEL (model);
  GDBusMenuModelItem *item;
  GSequenceIter *iter;

  g_return_if_fail (proxy->active);
  g_return_if_fail (proxy->items);

  iter = g_sequence_get_iter_at_pos (proxy->items, item_index);
  g_return_if_fail (iter);

  item = g_sequence_get (iter);
  g_return_if_fail (item);

  *table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);

  {
    GHashTableIter tmp;
    gpointer key;
    gpointer value;

    g_hash_table_iter_init (&tmp, item->links);
    while (g_hash_table_iter_next (&tmp, &key, &value))
      {
        if (g_variant_is_of_type (value, G_VARIANT_TYPE ("(uu)")))
          {
            guint group_id, menu_id;
            GDBusMenuGroup *group;
            GDBusMenuModel *link;

            g_variant_get (value, "(uu)", &group_id, &menu_id);

            /* save the hash lookup in a relatively common case */
            if (proxy->group->id != group_id)
              group = g_dbus_menu_group_get_from_path (proxy->group->path, group_id);
            else
              group = g_dbus_menu_group_ref (proxy->group);

            link = g_dbus_menu_model_get_from_group (group, menu_id);

            g_hash_table_insert (*table, g_strdup (key), link);

            g_dbus_menu_group_unref (group);
          }
      }
  }
}

static void
g_dbus_menu_model_finalize (GObject *object)
{
  GDBusMenuModel *proxy = G_DBUS_MENU_MODEL (object);

  if (proxy->active)
    g_dbus_menu_group_deactivate (proxy->group);

  g_hash_table_remove (proxy->group->proxies, GINT_TO_POINTER (proxy->id));
  g_dbus_menu_group_unref (proxy->group);

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

static void
g_dbus_menu_model_init (GDBusMenuModel *proxy)
{
}

static void
g_dbus_menu_model_class_init (GDBusMenuModelClass *class)
{
  GObjectClass *object_class = G_OBJECT_CLASS (class);

  class->is_mutable = g_dbus_menu_model_is_mutable;
  class->get_n_items = g_dbus_menu_model_get_n_items;
  class->get_item_attributes = g_dbus_menu_model_get_item_attributes;
  class->get_item_links = g_dbus_menu_model_get_item_links;

  object_class->finalize = g_dbus_menu_model_finalize;
}

static void
g_dbus_menu_model_changed (GDBusMenuModel *proxy,
                           GSequence      *items,
                           gint            position,
                           gint            removed,
                           gint            added)
{
  proxy->items = items;

  if (proxy->active && (removed || added))
    g_menu_model_items_changed (G_MENU_MODEL (proxy), position, removed, added);
}

static GDBusMenuModel *
g_dbus_menu_model_get_from_group (GDBusMenuGroup *group,
                                  guint           menu_id)
{
  GDBusMenuModel *proxy;

  proxy = g_hash_table_lookup (group->proxies, GINT_TO_POINTER (menu_id));
  if (proxy)
    g_object_ref (proxy);

  if (proxy == NULL)
    {
      proxy = g_object_new (G_TYPE_DBUS_MENU_MODEL, NULL);
      proxy->items = g_hash_table_lookup (group->menus, GINT_TO_POINTER (menu_id));
      g_hash_table_insert (group->proxies, GINT_TO_POINTER (menu_id), proxy);
      proxy->group = g_dbus_menu_group_ref (group);
      proxy->id = menu_id;
    }

  return proxy;
}

/**
 * g_dbus_menu_model_get:
 * @connection: a #GDBusConnection
 * @bus_name: the bus name which exports the menu model
 * @object_path: the object path at which the menu model is exported
 *
 * Obtains a #GDBusMenuModel for the menu model which is exported
 * at the given @bus_name and @object_path.
 *
 * The thread default main context is taken at the time of this call.
 * All signals on the menu model (and any linked models) are reported
 * with respect to this context.  All calls on the returned menu model
 * (and linked models) must also originate from this same context, with
 * the thread default main context unchanged.
 *
 * Returns: (transfer full): a #GDBusMenuModel object. Free with
 *     g_object_unref().
 *
 * Since: 2.32
 */
GDBusMenuModel *
g_dbus_menu_model_get (GDBusConnection *connection,
                       const gchar     *bus_name,
                       const gchar     *object_path)
{
  GDBusMenuGroup *group;
  GDBusMenuModel *proxy;
  GMainContext *context;

  context = g_main_context_get_thread_default ();
  if (context == NULL)
    context = g_main_context_default ();

  group = g_dbus_menu_group_get (context, connection, bus_name, object_path, 0);
  proxy = g_dbus_menu_model_get_from_group (group, 0);
  g_dbus_menu_group_unref (group);

  return proxy;
}

#if 0
static void
dump_proxy (gpointer key, gpointer value, gpointer data)
{
  GDBusMenuModel *proxy = value;

  g_print ("    menu %d refcount %d active %d\n",
           proxy->id, G_OBJECT (proxy)->ref_count, proxy->active);
}

static void
dump_group (gpointer key, gpointer value, gpointer data)
{
  GDBusMenuGroup *group = value;

  g_print ("  group %d refcount %d state %d active %d\n",
           group->id, group->ref_count, group->state, group->active);

  g_hash_table_foreach (group->proxies, dump_proxy, NULL);
}

static void
dump_path (gpointer key, gpointer value, gpointer data)
{
  PathIdentifier *pid = key;
  GDBusMenuPath *path = value;

  g_print ("%s active %d\n", pid->object_path, path->active);
  g_hash_table_foreach (path->groups, dump_group, NULL);
}

void
g_dbus_menu_model_dump (void)
{
  g_hash_table_foreach (g_dbus_menu_paths, dump_path, NULL);
}

#endif

/* Epilogue {{{1 */
/* vim:set foldmethod=marker: */
