/* GDBus - GLib D-Bus Library
 *
 * Copyright (C) 2008-2010 Red Hat, Inc.
 *
 * 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.1 of the License, 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, see <http://www.gnu.org/licenses/>.
 *
 * Author: David Zeuthen <davidz@redhat.com>
 */

#include "config.h"

#include "gdbusobjectmanager.h"
#include "gdbusobjectmanagerserver.h"
#include "gdbusobject.h"
#include "gdbusobjectskeleton.h"
#include "gdbusinterfaceskeleton.h"
#include "gdbusconnection.h"
#include "gdbusintrospection.h"
#include "gdbusmethodinvocation.h"
#include "gdbuserror.h"

#include "gioerror.h"

#include "glibintl.h"

/**
 * SECTION:gdbusobjectmanagerserver
 * @short_description: Service-side object manager
 * @include: gio/gio.h
 *
 * #GDBusObjectManagerServer is used to export #GDBusObject instances using
 * the standardized
 * [org.freedesktop.DBus.ObjectManager](http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-objectmanager)
 * interface. For example, remote D-Bus clients can get all objects
 * and properties in a single call. Additionally, any change in the
 * object hierarchy is broadcast using signals. This means that D-Bus
 * clients can keep caches up to date by only listening to D-Bus
 * signals.
 *
 * The recommended path to export an object manager at is the path form of the
 * well-known name of a D-Bus service, or below. For example, if a D-Bus service
 * is available at the well-known name `net.example.ExampleService1`, the object
 * manager should typically be exported at `/net/example/ExampleService1`, or
 * below (to allow for multiple object managers in a service).
 *
 * It is supported, but not recommended, to export an object manager at the root
 * path, `/`.
 *
 * See #GDBusObjectManagerClient for the client-side code that is
 * intended to be used with #GDBusObjectManagerServer or any D-Bus
 * object implementing the org.freedesktop.DBus.ObjectManager
 * interface.
 */

typedef struct
{
  GDBusObjectSkeleton *object;
  GDBusObjectManagerServer *manager;
  GHashTable *map_iface_name_to_iface;
  gboolean exported;
} RegistrationData;

static void registration_data_free (RegistrationData *data);

static void export_all (GDBusObjectManagerServer *manager);
static void unexport_all (GDBusObjectManagerServer *manager, gboolean only_manager);

static void g_dbus_object_manager_server_emit_interfaces_added (GDBusObjectManagerServer *manager,
                                                         RegistrationData   *data,
                                                         const gchar *const *interfaces,
                                                         const gchar *object_path);

static void g_dbus_object_manager_server_emit_interfaces_removed (GDBusObjectManagerServer *manager,
                                                           RegistrationData   *data,
                                                           const gchar *const *interfaces);

static gboolean g_dbus_object_manager_server_unexport_unlocked (GDBusObjectManagerServer  *manager,
                                                                const gchar               *object_path);

struct _GDBusObjectManagerServerPrivate
{
  GMutex lock;
  GDBusConnection *connection;
  gchar *object_path;
  gchar *object_path_ending_in_slash;
  GHashTable *map_object_path_to_data;
  guint manager_reg_id;
};

enum
{
  PROP_0,
  PROP_CONNECTION,
  PROP_OBJECT_PATH
};

static void dbus_object_manager_interface_init (GDBusObjectManagerIface *iface);

G_DEFINE_TYPE_WITH_CODE (GDBusObjectManagerServer, g_dbus_object_manager_server, G_TYPE_OBJECT,
                         G_ADD_PRIVATE (GDBusObjectManagerServer)
                         G_IMPLEMENT_INTERFACE (G_TYPE_DBUS_OBJECT_MANAGER, dbus_object_manager_interface_init))

static void g_dbus_object_manager_server_constructed (GObject *object);

static void
g_dbus_object_manager_server_finalize (GObject *object)
{
  GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (object);

  if (manager->priv->connection != NULL)
    {
      unexport_all (manager, TRUE);
      g_object_unref (manager->priv->connection);
    }
  g_hash_table_unref (manager->priv->map_object_path_to_data);
  g_free (manager->priv->object_path);
  g_free (manager->priv->object_path_ending_in_slash);

  g_mutex_clear (&manager->priv->lock);

  if (G_OBJECT_CLASS (g_dbus_object_manager_server_parent_class)->finalize != NULL)
    G_OBJECT_CLASS (g_dbus_object_manager_server_parent_class)->finalize (object);
}

static void
g_dbus_object_manager_server_get_property (GObject    *object,
                                           guint       prop_id,
                                           GValue     *value,
                                           GParamSpec *pspec)
{
  GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (object);

  switch (prop_id)
    {
    case PROP_CONNECTION:
      g_mutex_lock (&manager->priv->lock);
      g_value_set_object (value, manager->priv->connection);
      g_mutex_unlock (&manager->priv->lock);
      break;

    case PROP_OBJECT_PATH:
      g_value_set_string (value, g_dbus_object_manager_get_object_path (G_DBUS_OBJECT_MANAGER (manager)));
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

static void
g_dbus_object_manager_server_set_property (GObject       *object,
                                           guint          prop_id,
                                           const GValue  *value,
                                           GParamSpec    *pspec)
{
  GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (object);

  switch (prop_id)
    {
    case PROP_CONNECTION:
      g_dbus_object_manager_server_set_connection (manager, g_value_get_object (value));
      break;

    case PROP_OBJECT_PATH:
      g_assert (manager->priv->object_path == NULL);
      g_assert (g_variant_is_object_path (g_value_get_string (value)));
      manager->priv->object_path = g_value_dup_string (value);
      if (g_str_equal (manager->priv->object_path, "/"))
        manager->priv->object_path_ending_in_slash = g_strdup (manager->priv->object_path);
      else
        manager->priv->object_path_ending_in_slash = g_strdup_printf ("%s/", manager->priv->object_path);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

static void
g_dbus_object_manager_server_class_init (GDBusObjectManagerServerClass *klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);

  gobject_class->finalize     = g_dbus_object_manager_server_finalize;
  gobject_class->constructed  = g_dbus_object_manager_server_constructed;
  gobject_class->set_property = g_dbus_object_manager_server_set_property;
  gobject_class->get_property = g_dbus_object_manager_server_get_property;

  /**
   * GDBusObjectManagerServer:connection:
   *
   * The #GDBusConnection to export objects on.
   *
   * Since: 2.30
   */
  g_object_class_install_property (gobject_class,
                                   PROP_CONNECTION,
                                   g_param_spec_object ("connection",
                                                        "Connection",
                                                        "The connection to export objects on",
                                                        G_TYPE_DBUS_CONNECTION,
                                                        G_PARAM_READABLE |
                                                        G_PARAM_WRITABLE |
                                                        G_PARAM_STATIC_STRINGS));

  /**
   * GDBusObjectManagerServer:object-path:
   *
   * The object path to register the manager object at.
   *
   * Since: 2.30
   */
  g_object_class_install_property (gobject_class,
                                   PROP_OBJECT_PATH,
                                   g_param_spec_string ("object-path",
                                                        "Object Path",
                                                        "The object path to register the manager object at",
                                                        NULL,
                                                        G_PARAM_READABLE |
                                                        G_PARAM_WRITABLE |
                                                        G_PARAM_CONSTRUCT_ONLY |
                                                        G_PARAM_STATIC_STRINGS));
}

static void
g_dbus_object_manager_server_init (GDBusObjectManagerServer *manager)
{
  manager->priv = g_dbus_object_manager_server_get_instance_private (manager);
  g_mutex_init (&manager->priv->lock);
  manager->priv->map_object_path_to_data = g_hash_table_new_full (g_str_hash,
                                                                  g_str_equal,
                                                                  g_free,
                                                                  (GDestroyNotify) registration_data_free);
}

/**
 * g_dbus_object_manager_server_new:
 * @object_path: The object path to export the manager object at.
 *
 * Creates a new #GDBusObjectManagerServer object.
 *
 * The returned server isn't yet exported on any connection. To do so,
 * use g_dbus_object_manager_server_set_connection(). Normally you
 * want to export all of your objects before doing so to avoid
 * [InterfacesAdded](http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-objectmanager)
 * signals being emitted.
 *
 * Returns: A #GDBusObjectManagerServer object. Free with g_object_unref().
 *
 * Since: 2.30
 */
GDBusObjectManagerServer *
g_dbus_object_manager_server_new (const gchar     *object_path)
{
  g_return_val_if_fail (g_variant_is_object_path (object_path), NULL);
  return G_DBUS_OBJECT_MANAGER_SERVER (g_object_new (G_TYPE_DBUS_OBJECT_MANAGER_SERVER,
                                                     "object-path", object_path,
                                                     NULL));
}

/**
 * g_dbus_object_manager_server_set_connection:
 * @manager: A #GDBusObjectManagerServer.
 * @connection: (nullable): A #GDBusConnection or %NULL.
 *
 * Exports all objects managed by @manager on @connection. If
 * @connection is %NULL, stops exporting objects.
 */
void
g_dbus_object_manager_server_set_connection (GDBusObjectManagerServer  *manager,
                                             GDBusConnection           *connection)
{
  g_return_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager));
  g_return_if_fail (connection == NULL || G_IS_DBUS_CONNECTION (connection));

  g_mutex_lock (&manager->priv->lock);

  if (manager->priv->connection == connection)
    {
      g_mutex_unlock (&manager->priv->lock);
      goto out;
    }

  if (manager->priv->connection != NULL)
    {
      unexport_all (manager, FALSE);
      g_object_unref (manager->priv->connection);
      manager->priv->connection = NULL;
    }

  manager->priv->connection = connection != NULL ? g_object_ref (connection) : NULL;
  if (manager->priv->connection != NULL)
    export_all (manager);

  g_mutex_unlock (&manager->priv->lock);

  g_object_notify (G_OBJECT (manager), "connection");
 out:
  ;
}

/**
 * g_dbus_object_manager_server_get_connection:
 * @manager: A #GDBusObjectManagerServer
 *
 * Gets the #GDBusConnection used by @manager.
 *
 * Returns: (transfer full) (nullable): A #GDBusConnection object or %NULL if
 *   @manager isn't exported on a connection. The returned object should
 *   be freed with g_object_unref().
 *
 * Since: 2.30
 */
GDBusConnection *
g_dbus_object_manager_server_get_connection (GDBusObjectManagerServer *manager)
{
  GDBusConnection *ret;
  g_return_val_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager), NULL);
  g_mutex_lock (&manager->priv->lock);
  ret = manager->priv->connection != NULL ? g_object_ref (manager->priv->connection) : NULL;
  g_mutex_unlock (&manager->priv->lock);
  return ret;
}

/* ---------------------------------------------------------------------------------------------------- */

static void
registration_data_export_interface (RegistrationData        *data,
                                    GDBusInterfaceSkeleton  *interface_skeleton,
                                    const gchar             *object_path)
{
  GDBusInterfaceInfo *info;
  GError *error;

  info = g_dbus_interface_skeleton_get_info (interface_skeleton);
  error = NULL;
  if (data->manager->priv->connection != NULL)
    {
      if (!g_dbus_interface_skeleton_export (interface_skeleton,
                                             data->manager->priv->connection,
                                             object_path,
                                             &error))
        {
          g_warning ("%s: Error registering object at %s with interface %s: %s",
                     G_STRLOC,
                     object_path,
                     info->name,
                     error->message);
          g_error_free (error);
        }
    }

  g_assert (g_hash_table_lookup (data->map_iface_name_to_iface, info->name) == NULL);
  g_hash_table_insert (data->map_iface_name_to_iface,
                       info->name,
                       g_object_ref (interface_skeleton));

  /* if we are already exported, then... */
  if (data->exported)
    {
      const gchar *interfaces[2];
      /* emit InterfacesAdded on the ObjectManager object */
      interfaces[0] = info->name;
      interfaces[1] = NULL;
      g_dbus_object_manager_server_emit_interfaces_added (data->manager, data, interfaces, object_path);
    }
}

static void
registration_data_unexport_interface (RegistrationData       *data,
                                      GDBusInterfaceSkeleton *interface_skeleton)
{
  GDBusInterfaceInfo *info;
  GDBusInterfaceSkeleton *iface;

  info = g_dbus_interface_skeleton_get_info (interface_skeleton);
  iface = g_hash_table_lookup (data->map_iface_name_to_iface, info->name);
  g_assert (iface != NULL);

  if (data->manager->priv->connection != NULL)
    g_dbus_interface_skeleton_unexport (iface);

  g_warn_if_fail (g_hash_table_remove (data->map_iface_name_to_iface, info->name));

  /* if we are already exported, then... */
  if (data->exported)
    {
      const gchar *interfaces[2];
      /* emit InterfacesRemoved on the ObjectManager object */
      interfaces[0] = info->name;
      interfaces[1] = NULL;
      g_dbus_object_manager_server_emit_interfaces_removed (data->manager, data, interfaces);
    }
}

/* ---------------------------------------------------------------------------------------------------- */

static void
on_interface_added (GDBusObject    *object,
                    GDBusInterface *interface,
                    gpointer        user_data)
{
  RegistrationData *data = user_data;
  const gchar *object_path;
  g_mutex_lock (&data->manager->priv->lock);
  object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (data->object));
  registration_data_export_interface (data, G_DBUS_INTERFACE_SKELETON (interface), object_path);
  g_mutex_unlock (&data->manager->priv->lock);
}

static void
on_interface_removed (GDBusObject    *object,
                      GDBusInterface *interface,
                      gpointer        user_data)
{
  RegistrationData *data = user_data;
  g_mutex_lock (&data->manager->priv->lock);
  registration_data_unexport_interface (data, G_DBUS_INTERFACE_SKELETON (interface));
  g_mutex_unlock (&data->manager->priv->lock);
}

/* ---------------------------------------------------------------------------------------------------- */


static void
registration_data_free (RegistrationData *data)
{
  GHashTableIter iter;
  GDBusInterfaceSkeleton *iface;

  data->exported = FALSE;

  g_hash_table_iter_init (&iter, data->map_iface_name_to_iface);
  while (g_hash_table_iter_next (&iter, NULL, (gpointer) &iface))
    {
      if (data->manager->priv->connection != NULL)
        g_dbus_interface_skeleton_unexport (iface);
    }

  g_signal_handlers_disconnect_by_func (data->object, G_CALLBACK (on_interface_added), data);
  g_signal_handlers_disconnect_by_func (data->object, G_CALLBACK (on_interface_removed), data);
  g_object_unref (data->object);
  g_hash_table_destroy (data->map_iface_name_to_iface);
  g_free (data);
}

/* ---------------------------------------------------------------------------------------------------- */

static void
g_dbus_object_manager_server_export_unlocked (GDBusObjectManagerServer  *manager,
                                              GDBusObjectSkeleton       *object,
                                              const gchar               *object_path)
{
  RegistrationData *data;
  GList *existing_interfaces;
  GList *l;
  GPtrArray *interface_names;

  g_return_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager));
  g_return_if_fail (G_IS_DBUS_OBJECT (object));
  g_return_if_fail (g_str_has_prefix (object_path, manager->priv->object_path_ending_in_slash));

  interface_names = g_ptr_array_new ();

  data = g_hash_table_lookup (manager->priv->map_object_path_to_data, object_path);
  if (data != NULL)
    g_dbus_object_manager_server_unexport_unlocked (manager, object_path);

  data = g_new0 (RegistrationData, 1);
  data->object = g_object_ref (object);
  data->manager = manager;
  data->map_iface_name_to_iface = g_hash_table_new_full (g_str_hash,
                                                         g_str_equal,
                                                         NULL,
                                                         (GDestroyNotify) g_object_unref);

  g_signal_connect (object,
                    "interface-added",
                    G_CALLBACK (on_interface_added),
                    data);
  g_signal_connect (object,
                    "interface-removed",
                    G_CALLBACK (on_interface_removed),
                    data);

  /* Register all known interfaces - note that data->exported is FALSE so
   * we don't emit any InterfacesAdded signals.
   */
  existing_interfaces = g_dbus_object_get_interfaces (G_DBUS_OBJECT (object));
  for (l = existing_interfaces; l != NULL; l = l->next)
    {
      GDBusInterfaceSkeleton *interface_skeleton = G_DBUS_INTERFACE_SKELETON (l->data);
      registration_data_export_interface (data, interface_skeleton, object_path);
      g_ptr_array_add (interface_names, g_dbus_interface_skeleton_get_info (interface_skeleton)->name);
    }
  g_list_free_full (existing_interfaces, g_object_unref);
  g_ptr_array_add (interface_names, NULL);

  data->exported = TRUE;

  /* now emit InterfacesAdded() for all the interfaces */
  g_dbus_object_manager_server_emit_interfaces_added (manager, data, (const gchar *const *) interface_names->pdata, object_path);
  g_ptr_array_unref (interface_names);

  g_hash_table_insert (manager->priv->map_object_path_to_data,
                       g_strdup (object_path),
                       data);
}

/**
 * g_dbus_object_manager_server_export:
 * @manager: A #GDBusObjectManagerServer.
 * @object: A #GDBusObjectSkeleton.
 *
 * Exports @object on @manager.
 *
 * If there is already a #GDBusObject exported at the object path,
 * then the old object is removed.
 *
 * The object path for @object must be in the hierarchy rooted by the
 * object path for @manager.
 *
 * Note that @manager will take a reference on @object for as long as
 * it is exported.
 *
 * Since: 2.30
 */
void
g_dbus_object_manager_server_export (GDBusObjectManagerServer  *manager,
                                     GDBusObjectSkeleton       *object)
{
  g_return_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager));
  g_mutex_lock (&manager->priv->lock);
  g_dbus_object_manager_server_export_unlocked (manager, object,
                                                g_dbus_object_get_object_path (G_DBUS_OBJECT (object)));
  g_mutex_unlock (&manager->priv->lock);
}

/**
 * g_dbus_object_manager_server_export_uniquely:
 * @manager: A #GDBusObjectManagerServer.
 * @object: An object.
 *
 * Like g_dbus_object_manager_server_export() but appends a string of
 * the form _N (with N being a natural number) to @object's object path
 * if an object with the given path already exists. As such, the
 * #GDBusObjectProxy:g-object-path property of @object may be modified.
 *
 * Since: 2.30
 */
void
g_dbus_object_manager_server_export_uniquely (GDBusObjectManagerServer *manager,
                                              GDBusObjectSkeleton      *object)
{
  const gchar *orig_object_path;
  gchar *object_path;
  guint count;
  gboolean modified;

  orig_object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (object));

  g_return_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager));
  g_return_if_fail (G_IS_DBUS_OBJECT (object));
  g_return_if_fail (g_str_has_prefix (orig_object_path, manager->priv->object_path_ending_in_slash));

  g_mutex_lock (&manager->priv->lock);

  object_path = g_strdup (orig_object_path);
  count = 1;
  modified = FALSE;
  while (TRUE)
    {
      RegistrationData *data;
      data = g_hash_table_lookup (manager->priv->map_object_path_to_data, object_path);
      if (data == NULL)
        {
          break;
        }
      g_free (object_path);
      object_path = g_strdup_printf ("%s_%d", orig_object_path, count++);
      modified = TRUE;
    }

  g_dbus_object_manager_server_export_unlocked (manager, object, object_path);

  g_mutex_unlock (&manager->priv->lock);

  if (modified)
    g_dbus_object_skeleton_set_object_path (G_DBUS_OBJECT_SKELETON (object), object_path);

  g_free (object_path);

}

/**
 * g_dbus_object_manager_server_is_exported:
 * @manager: A #GDBusObjectManagerServer.
 * @object: An object.
 *
 * Returns whether @object is currently exported on @manager.
 *
 * Returns: %TRUE if @object is exported
 *
 * Since: 2.34
 **/
gboolean
g_dbus_object_manager_server_is_exported (GDBusObjectManagerServer *manager,
                                          GDBusObjectSkeleton      *object)
{
  RegistrationData *data = NULL;
  const gchar *object_path;
  gboolean object_is_exported;

  g_return_val_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager), FALSE);
  g_return_val_if_fail (G_IS_DBUS_OBJECT (object), FALSE);

  g_mutex_lock (&manager->priv->lock);

  object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (object));
  if (object_path != NULL)
    data = g_hash_table_lookup (manager->priv->map_object_path_to_data, object_path);
  object_is_exported = (data != NULL);

  g_mutex_unlock (&manager->priv->lock);

  return object_is_exported;
}

/* ---------------------------------------------------------------------------------------------------- */

static gboolean
g_dbus_object_manager_server_unexport_unlocked (GDBusObjectManagerServer  *manager,
                                                const gchar               *object_path)
{
  RegistrationData *data;
  gboolean ret;

  g_return_val_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager), FALSE);
  g_return_val_if_fail (g_variant_is_object_path (object_path), FALSE);
  g_return_val_if_fail (g_str_has_prefix (object_path, manager->priv->object_path_ending_in_slash), FALSE);

  ret = FALSE;

  data = g_hash_table_lookup (manager->priv->map_object_path_to_data, object_path);
  if (data != NULL)
    {
      GPtrArray *interface_names;
      GHashTableIter iter;
      const gchar *iface_name;

      interface_names = g_ptr_array_new ();
      g_hash_table_iter_init (&iter, data->map_iface_name_to_iface);
      while (g_hash_table_iter_next (&iter, (gpointer) &iface_name, NULL))
        g_ptr_array_add (interface_names, (gpointer) iface_name);
      g_ptr_array_add (interface_names, NULL);
      /* now emit InterfacesRemoved() for all the interfaces */
      g_dbus_object_manager_server_emit_interfaces_removed (manager, data, (const gchar *const *) interface_names->pdata);
      g_ptr_array_unref (interface_names);

      g_hash_table_remove (manager->priv->map_object_path_to_data, object_path);
      ret = TRUE;
    }

  return ret;
}

/**
 * g_dbus_object_manager_server_unexport:
 * @manager: A #GDBusObjectManagerServer.
 * @object_path: An object path.
 *
 * If @manager has an object at @path, removes the object. Otherwise
 * does nothing.
 *
 * Note that @object_path must be in the hierarchy rooted by the
 * object path for @manager.
 *
 * Returns: %TRUE if object at @object_path was removed, %FALSE otherwise.
 *
 * Since: 2.30
 */
gboolean
g_dbus_object_manager_server_unexport (GDBusObjectManagerServer  *manager,
                                       const gchar         *object_path)
{
  gboolean ret;
  g_return_val_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager), FALSE);
  g_mutex_lock (&manager->priv->lock);
  ret = g_dbus_object_manager_server_unexport_unlocked (manager, object_path);
  g_mutex_unlock (&manager->priv->lock);
  return ret;
}


/* ---------------------------------------------------------------------------------------------------- */

static const GDBusArgInfo manager_interfaces_added_signal_info_arg0 =
{
  -1,
  "object_path",
  "o",
  (GDBusAnnotationInfo**) NULL,
};

static const GDBusArgInfo manager_interfaces_added_signal_info_arg1 =
{
  -1,
  "interfaces_and_properties",
  "a{sa{sv}}",
  (GDBusAnnotationInfo**) NULL,
};

static const GDBusArgInfo * const manager_interfaces_added_signal_info_arg_pointers[] =
{
  &manager_interfaces_added_signal_info_arg0,
  &manager_interfaces_added_signal_info_arg1,
  NULL
};

static const GDBusSignalInfo manager_interfaces_added_signal_info =
{
  -1,
  "InterfacesAdded",
  (GDBusArgInfo**) &manager_interfaces_added_signal_info_arg_pointers,
  (GDBusAnnotationInfo**) NULL
};

/* ---------- */

static const GDBusArgInfo manager_interfaces_removed_signal_info_arg0 =
{
  -1,
  "object_path",
  "o",
  (GDBusAnnotationInfo**) NULL,
};

static const GDBusArgInfo manager_interfaces_removed_signal_info_arg1 =
{
  -1,
  "interfaces",
  "as",
  (GDBusAnnotationInfo**) NULL,
};

static const GDBusArgInfo * const manager_interfaces_removed_signal_info_arg_pointers[] =
{
  &manager_interfaces_removed_signal_info_arg0,
  &manager_interfaces_removed_signal_info_arg1,
  NULL
};

static const GDBusSignalInfo manager_interfaces_removed_signal_info =
{
  -1,
  "InterfacesRemoved",
  (GDBusArgInfo**) &manager_interfaces_removed_signal_info_arg_pointers,
  (GDBusAnnotationInfo**) NULL
};

/* ---------- */

static const GDBusSignalInfo * const manager_signal_info_pointers[] =
{
  &manager_interfaces_added_signal_info,
  &manager_interfaces_removed_signal_info,
  NULL
};

/* ---------- */

static const GDBusArgInfo manager_get_all_method_info_out_arg0 =
{
  -1,
  "object_paths_interfaces_and_properties",
  "a{oa{sa{sv}}}",
  (GDBusAnnotationInfo**) NULL,
};

static const GDBusArgInfo * const manager_get_all_method_info_out_arg_pointers[] =
{
  &manager_get_all_method_info_out_arg0,
  NULL
};

static const GDBusMethodInfo manager_get_all_method_info =
{
  -1,
  "GetManagedObjects",
  (GDBusArgInfo**) NULL,
  (GDBusArgInfo**) &manager_get_all_method_info_out_arg_pointers,
  (GDBusAnnotationInfo**) NULL
};

static const GDBusMethodInfo * const manager_method_info_pointers[] =
{
  &manager_get_all_method_info,
  NULL
};

/* ---------- */

static const GDBusInterfaceInfo manager_interface_info =
{
  -1,
  "org.freedesktop.DBus.ObjectManager",
  (GDBusMethodInfo **) manager_method_info_pointers,
  (GDBusSignalInfo **) manager_signal_info_pointers,
  (GDBusPropertyInfo **) NULL,
  (GDBusAnnotationInfo **) NULL
};

static void
manager_method_call (GDBusConnection       *connection,
                     const gchar           *sender,
                     const gchar           *object_path,
                     const gchar           *interface_name,
                     const gchar           *method_name,
                     GVariant              *parameters,
                     GDBusMethodInvocation *invocation,
                     gpointer               user_data)
{
  GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (user_data);
  GVariantBuilder array_builder;
  GHashTableIter object_iter;
  RegistrationData *data;

  g_mutex_lock (&manager->priv->lock);

  if (g_strcmp0 (method_name, "GetManagedObjects") == 0)
    {
      g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("a{oa{sa{sv}}}"));
      g_hash_table_iter_init (&object_iter, manager->priv->map_object_path_to_data);
      while (g_hash_table_iter_next (&object_iter, NULL, (gpointer) &data))
        {
          GVariantBuilder interfaces_builder;
          GHashTableIter interface_iter;
          GDBusInterfaceSkeleton *iface;
          const gchar *iter_object_path;

          g_variant_builder_init (&interfaces_builder, G_VARIANT_TYPE ("a{sa{sv}}"));
          g_hash_table_iter_init (&interface_iter, data->map_iface_name_to_iface);
          while (g_hash_table_iter_next (&interface_iter, NULL, (gpointer) &iface))
            {
              GVariant *properties = g_dbus_interface_skeleton_get_properties (iface);
              g_variant_builder_add (&interfaces_builder, "{s@a{sv}}",
                                     g_dbus_interface_skeleton_get_info (iface)->name,
                                     properties);
              g_variant_unref (properties);
            }
          iter_object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (data->object));
          g_variant_builder_add (&array_builder,
                                 "{oa{sa{sv}}}",
                                 iter_object_path,
                                 &interfaces_builder);
        }

      g_dbus_method_invocation_return_value (invocation,
                                             g_variant_new ("(a{oa{sa{sv}}})",
                                                            &array_builder));
    }
  else
    {
      g_dbus_method_invocation_return_error (invocation,
                                             G_DBUS_ERROR,
                                             G_DBUS_ERROR_UNKNOWN_METHOD,
                                             "Unknown method %s - only GetManagedObjects() is supported",
                                             method_name);
    }
  g_mutex_unlock (&manager->priv->lock);
}

static const GDBusInterfaceVTable manager_interface_vtable =
{
  manager_method_call, /* handle_method_call */
  NULL, /* get_property */
  NULL, /* set_property */
  { 0 }
};

/* ---------------------------------------------------------------------------------------------------- */

static void
g_dbus_object_manager_server_constructed (GObject *object)
{
  GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (object);

  if (manager->priv->connection != NULL)
    export_all (manager);

  if (G_OBJECT_CLASS (g_dbus_object_manager_server_parent_class)->constructed != NULL)
    G_OBJECT_CLASS (g_dbus_object_manager_server_parent_class)->constructed (object);
}

static void
g_dbus_object_manager_server_emit_interfaces_added (GDBusObjectManagerServer *manager,
                                                    RegistrationData   *data,
                                                    const gchar *const *interfaces,
                                                    const gchar *object_path)
{
  GVariantBuilder array_builder;
  GError *error;
  guint n;

  if (data->manager->priv->connection == NULL)
    goto out;

  g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("a{sa{sv}}"));
  for (n = 0; interfaces[n] != NULL; n++)
    {
      GDBusInterfaceSkeleton *iface;
      GVariant *properties;

      iface = g_hash_table_lookup (data->map_iface_name_to_iface, interfaces[n]);
      g_assert (iface != NULL);
      properties = g_dbus_interface_skeleton_get_properties (iface);
      g_variant_builder_add (&array_builder, "{s@a{sv}}", interfaces[n], properties);
      g_variant_unref (properties);
    }

  error = NULL;
  g_dbus_connection_emit_signal (data->manager->priv->connection,
                                 NULL, /* destination_bus_name */
                                 manager->priv->object_path,
                                 manager_interface_info.name,
                                 "InterfacesAdded",
                                 g_variant_new ("(oa{sa{sv}})",
                                                object_path,
                                                &array_builder),
                                 &error);
  if (error)
    {
      if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CLOSED))
        g_warning ("Couldn't emit InterfacesAdded signal: %s", error->message);
      g_error_free (error);
    }
 out:
  ;
}

static void
g_dbus_object_manager_server_emit_interfaces_removed (GDBusObjectManagerServer *manager,
                                                      RegistrationData   *data,
                                                      const gchar *const *interfaces)
{
  GVariantBuilder array_builder;
  GError *error;
  guint n;
  const gchar *object_path;

  if (data->manager->priv->connection == NULL)
    goto out;

  g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("as"));
  for (n = 0; interfaces[n] != NULL; n++)
    g_variant_builder_add (&array_builder, "s", interfaces[n]);

  error = NULL;
  object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (data->object));
  g_dbus_connection_emit_signal (data->manager->priv->connection,
                                 NULL, /* destination_bus_name */
                                 manager->priv->object_path,
                                 manager_interface_info.name,
                                 "InterfacesRemoved",
                                 g_variant_new ("(oas)",
                                                object_path,
                                                &array_builder),
                                 &error);
  if (error)
    {
      if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CLOSED))
        g_warning ("Couldn't emit InterfacesRemoved signal: %s", error->message);
      g_error_free (error);
    }
 out:
  ;
}

/* ---------------------------------------------------------------------------------------------------- */

static GList *
g_dbus_object_manager_server_get_objects (GDBusObjectManager  *_manager)
{
  GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (_manager);
  GList *ret;
  GHashTableIter iter;
  RegistrationData *data;

  g_mutex_lock (&manager->priv->lock);

  ret = NULL;
  g_hash_table_iter_init (&iter, manager->priv->map_object_path_to_data);
  while (g_hash_table_iter_next (&iter, NULL, (gpointer) &data))
    {
      ret = g_list_prepend (ret, g_object_ref (data->object));
    }

  g_mutex_unlock (&manager->priv->lock);

  return ret;
}

static const gchar *
g_dbus_object_manager_server_get_object_path (GDBusObjectManager *_manager)
{
  GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (_manager);
  return manager->priv->object_path;
}

static GDBusObject *
g_dbus_object_manager_server_get_object (GDBusObjectManager *_manager,
                                         const gchar        *object_path)
{
  GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (_manager);
  GDBusObject *ret;
  RegistrationData *data;

  ret = NULL;

  g_mutex_lock (&manager->priv->lock);
  data = g_hash_table_lookup (manager->priv->map_object_path_to_data, object_path);
  if (data != NULL)
    ret = g_object_ref (G_DBUS_OBJECT (data->object));
  g_mutex_unlock (&manager->priv->lock);

  return ret;
}

static GDBusInterface *
g_dbus_object_manager_server_get_interface  (GDBusObjectManager  *_manager,
                                             const gchar         *object_path,
                                             const gchar         *interface_name)
{
  GDBusInterface *ret;
  GDBusObject *object;

  ret = NULL;

  object = g_dbus_object_manager_get_object (_manager, object_path);
  if (object == NULL)
    goto out;

  ret = g_dbus_object_get_interface (object, interface_name);
  g_object_unref (object);

 out:
  return ret;
}

static void
dbus_object_manager_interface_init (GDBusObjectManagerIface *iface)
{
  iface->get_object_path = g_dbus_object_manager_server_get_object_path;
  iface->get_objects     = g_dbus_object_manager_server_get_objects;
  iface->get_object      = g_dbus_object_manager_server_get_object;
  iface->get_interface   = g_dbus_object_manager_server_get_interface;
}

/* ---------------------------------------------------------------------------------------------------- */

static void
export_all (GDBusObjectManagerServer *manager)
{
  GHashTableIter iter;
  const gchar *object_path;
  RegistrationData *data;
  GHashTableIter iface_iter;
  GDBusInterfaceSkeleton *iface;
  GError *error;

  g_return_if_fail (manager->priv->connection != NULL);

  error = NULL;
  g_warn_if_fail (manager->priv->manager_reg_id == 0);
  manager->priv->manager_reg_id = g_dbus_connection_register_object (manager->priv->connection,
                                                                     manager->priv->object_path,
                                                                     (GDBusInterfaceInfo *) &manager_interface_info,
                                                                     &manager_interface_vtable,
                                                                     manager,
                                                                     NULL, /* user_data_free_func */
                                                                     &error);
  if (manager->priv->manager_reg_id == 0)
    {
      g_warning ("%s: Error registering manager at %s: %s",
                 G_STRLOC,
                 manager->priv->object_path,
                 error->message);
      g_error_free (error);
    }

  g_hash_table_iter_init (&iter, manager->priv->map_object_path_to_data);
  while (g_hash_table_iter_next (&iter, (gpointer) &object_path, (gpointer) &data))
    {
      g_hash_table_iter_init (&iface_iter, data->map_iface_name_to_iface);
      while (g_hash_table_iter_next (&iface_iter, NULL, (gpointer) &iface))
        {
          g_warn_if_fail (g_dbus_interface_skeleton_get_connection (iface) == NULL);
          error = NULL;
          if (!g_dbus_interface_skeleton_export (iface,
                                                 manager->priv->connection,
                                                 object_path,
                                                 &error))
            {
              g_warning ("%s: Error registering object at %s with interface %s: %s",
                         G_STRLOC,
                         object_path,
                         g_dbus_interface_skeleton_get_info (iface)->name,
                         error->message);
              g_error_free (error);
            }
        }
    }
}

static void
unexport_all (GDBusObjectManagerServer *manager, gboolean only_manager)
{
  GHashTableIter iter;
  RegistrationData *data;
  GHashTableIter iface_iter;
  GDBusInterfaceSkeleton *iface;

  g_return_if_fail (manager->priv->connection != NULL);

  g_warn_if_fail (manager->priv->manager_reg_id > 0);
  if (manager->priv->manager_reg_id > 0)
    {
      g_warn_if_fail (g_dbus_connection_unregister_object (manager->priv->connection,
                                                           manager->priv->manager_reg_id));
      manager->priv->manager_reg_id = 0;
    }
  if (only_manager)
    goto out;

  g_hash_table_iter_init (&iter, manager->priv->map_object_path_to_data);
  while (g_hash_table_iter_next (&iter, NULL, (gpointer) &data))
    {
      g_hash_table_iter_init (&iface_iter, data->map_iface_name_to_iface);
      while (g_hash_table_iter_next (&iface_iter, NULL, (gpointer) &iface))
        {
          g_warn_if_fail (g_dbus_interface_skeleton_get_connection (iface) != NULL);
          g_dbus_interface_skeleton_unexport (iface);
        }
    }
 out:
  ;
}

/* ---------------------------------------------------------------------------------------------------- */
