/* 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 "gcancellable.h"
#include "gdbusobjectmanager.h"
#include "gdbusobjectmanagerclient.h"
#include "gdbusobject.h"
#include "gdbusprivate.h"
#include "gioenumtypes.h"
#include "gioerror.h"
#include "ginitable.h"
#include "gasyncresult.h"
#include "gasyncinitable.h"
#include "gdbusconnection.h"
#include "gdbusutils.h"
#include "gdbusobject.h"
#include "gdbusobjectproxy.h"
#include "gdbusproxy.h"
#include "gdbusinterface.h"

#include "glibintl.h"
#include "gmarshal-internal.h"

/**
 * SECTION:gdbusobjectmanagerclient
 * @short_description: Client-side object manager
 * @include: gio/gio.h
 *
 * #GDBusObjectManagerClient is used to create, monitor and delete object
 * proxies for remote objects exported by a #GDBusObjectManagerServer (or any
 * code implementing the
 * [org.freedesktop.DBus.ObjectManager](http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-objectmanager)
 * interface).
 *
 * Once an instance of this type has been created, you can connect to
 * the #GDBusObjectManager::object-added and
 * #GDBusObjectManager::object-removed signals and inspect the
 * #GDBusObjectProxy objects returned by
 * g_dbus_object_manager_get_objects().
 *
 * If the name for a #GDBusObjectManagerClient is not owned by anyone at
 * object construction time, the default behavior is to request the
 * message bus to launch an owner for the name. This behavior can be
 * disabled using the %G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_DO_NOT_AUTO_START
 * flag. It's also worth noting that this only works if the name of
 * interest is activatable in the first place. E.g. in some cases it
 * is not possible to launch an owner for the requested name. In this
 * case, #GDBusObjectManagerClient object construction still succeeds but
 * there will be no object proxies
 * (e.g. g_dbus_object_manager_get_objects() returns the empty list) and
 * the #GDBusObjectManagerClient:name-owner property is %NULL.
 *
 * The owner of the requested name can come and go (for example
 * consider a system service being restarted) – #GDBusObjectManagerClient
 * handles this case too; simply connect to the #GObject::notify
 * signal to watch for changes on the #GDBusObjectManagerClient:name-owner
 * property. When the name owner vanishes, the behavior is that
 * #GDBusObjectManagerClient:name-owner is set to %NULL (this includes
 * emission of the #GObject::notify signal) and then
 * #GDBusObjectManager::object-removed signals are synthesized
 * for all currently existing object proxies. Since
 * #GDBusObjectManagerClient:name-owner is %NULL when this happens, you can
 * use this information to disambiguate a synthesized signal from a
 * genuine signal caused by object removal on the remote
 * #GDBusObjectManager. Similarly, when a new name owner appears,
 * #GDBusObjectManager::object-added signals are synthesized
 * while #GDBusObjectManagerClient:name-owner is still %NULL. Only when all
 * object proxies have been added, the #GDBusObjectManagerClient:name-owner
 * is set to the new name owner (this includes emission of the
 * #GObject::notify signal).  Furthermore, you are guaranteed that
 * #GDBusObjectManagerClient:name-owner will alternate between a name owner
 * (e.g. `:1.42`) and %NULL even in the case where
 * the name of interest is atomically replaced
 *
 * Ultimately, #GDBusObjectManagerClient is used to obtain #GDBusProxy
 * instances. All signals (including the
 * org.freedesktop.DBus.Properties::PropertiesChanged signal)
 * delivered to #GDBusProxy instances are guaranteed to originate
 * from the name owner. This guarantee along with the behavior
 * described above, means that certain race conditions including the
 * "half the proxy is from the old owner and the other half is from
 * the new owner" problem cannot happen.
 *
 * To avoid having the application connect to signals on the returned
 * #GDBusObjectProxy and #GDBusProxy objects, the
 * #GDBusObject::interface-added,
 * #GDBusObject::interface-removed,
 * #GDBusProxy::g-properties-changed and
 * #GDBusProxy::g-signal signals
 * are also emitted on the #GDBusObjectManagerClient instance managing these
 * objects. The signals emitted are
 * #GDBusObjectManager::interface-added,
 * #GDBusObjectManager::interface-removed,
 * #GDBusObjectManagerClient::interface-proxy-properties-changed and
 * #GDBusObjectManagerClient::interface-proxy-signal.
 *
 * Note that all callbacks and signals are emitted in the
 * [thread-default main context][g-main-context-push-thread-default]
 * that the #GDBusObjectManagerClient object was constructed
 * in. Additionally, the #GDBusObjectProxy and #GDBusProxy objects
 * originating from the #GDBusObjectManagerClient object will be created in
 * the same context and, consequently, will deliver signals in the
 * same main loop.
 */

struct _GDBusObjectManagerClientPrivate
{
  GMutex lock;

  GBusType bus_type;
  GDBusConnection *connection;
  gchar *object_path;
  gchar *name;
  gchar *name_owner;
  GDBusObjectManagerClientFlags flags;

  GDBusProxy *control_proxy;

  GHashTable *map_object_path_to_object_proxy;

  guint signal_subscription_id;
  gchar *match_rule;

  GDBusProxyTypeFunc get_proxy_type_func;
  gpointer get_proxy_type_user_data;
  GDestroyNotify get_proxy_type_destroy_notify;

  gulong name_owner_signal_id;
  gulong signal_signal_id;
  GCancellable *cancel;
};

enum
{
  PROP_0,
  PROP_BUS_TYPE,
  PROP_CONNECTION,
  PROP_FLAGS,
  PROP_OBJECT_PATH,
  PROP_NAME,
  PROP_NAME_OWNER,
  PROP_GET_PROXY_TYPE_FUNC,
  PROP_GET_PROXY_TYPE_USER_DATA,
  PROP_GET_PROXY_TYPE_DESTROY_NOTIFY
};

enum
{
  INTERFACE_PROXY_SIGNAL_SIGNAL,
  INTERFACE_PROXY_PROPERTIES_CHANGED_SIGNAL,
  LAST_SIGNAL
};

static guint signals[LAST_SIGNAL] = { 0 };

static void initable_iface_init       (GInitableIface *initable_iface);
static void async_initable_iface_init (GAsyncInitableIface *async_initable_iface);
static void dbus_object_manager_interface_init (GDBusObjectManagerIface *iface);

G_DEFINE_TYPE_WITH_CODE (GDBusObjectManagerClient, g_dbus_object_manager_client, G_TYPE_OBJECT,
                         G_ADD_PRIVATE (GDBusObjectManagerClient)
                         G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, initable_iface_init)
                         G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, async_initable_iface_init)
                         G_IMPLEMENT_INTERFACE (G_TYPE_DBUS_OBJECT_MANAGER, dbus_object_manager_interface_init))

static void maybe_unsubscribe_signals (GDBusObjectManagerClient *manager);

static void on_control_proxy_g_signal (GDBusProxy   *proxy,
                                       const gchar  *sender_name,
                                       const gchar  *signal_name,
                                       GVariant     *parameters,
                                       gpointer      user_data);

static void process_get_all_result (GDBusObjectManagerClient *manager,
                                    GVariant          *value,
                                    const gchar       *name_owner);

static void
g_dbus_object_manager_client_dispose (GObject *object)
{
  GDBusObjectManagerClient *manager = G_DBUS_OBJECT_MANAGER_CLIENT (object);

  if (manager->priv->cancel != NULL)
    {
      g_cancellable_cancel (manager->priv->cancel);
      g_clear_object (&manager->priv->cancel);
    }

  G_OBJECT_CLASS (g_dbus_object_manager_client_parent_class)->dispose (object);
}

static void
g_dbus_object_manager_client_finalize (GObject *object)
{
  GDBusObjectManagerClient *manager = G_DBUS_OBJECT_MANAGER_CLIENT (object);

  maybe_unsubscribe_signals (manager);

  g_hash_table_unref (manager->priv->map_object_path_to_object_proxy);

  if (manager->priv->control_proxy != NULL && manager->priv->signal_signal_id != 0)
    g_signal_handler_disconnect (manager->priv->control_proxy,
                                 manager->priv->signal_signal_id);
  manager->priv->signal_signal_id = 0;

  if (manager->priv->control_proxy != NULL && manager->priv->name_owner_signal_id != 0)
    g_signal_handler_disconnect (manager->priv->control_proxy,
                                 manager->priv->name_owner_signal_id);
  manager->priv->name_owner_signal_id = 0;

  g_clear_object (&manager->priv->control_proxy);

  if (manager->priv->connection != NULL)
    g_object_unref (manager->priv->connection);
  g_free (manager->priv->object_path);
  g_free (manager->priv->name);
  g_free (manager->priv->name_owner);

  if (manager->priv->get_proxy_type_destroy_notify != NULL)
    manager->priv->get_proxy_type_destroy_notify (manager->priv->get_proxy_type_user_data);

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

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

static void
g_dbus_object_manager_client_get_property (GObject    *_object,
                                           guint       prop_id,
                                           GValue     *value,
                                           GParamSpec *pspec)
{
  GDBusObjectManagerClient *manager = G_DBUS_OBJECT_MANAGER_CLIENT (_object);

  switch (prop_id)
    {
    case PROP_CONNECTION:
      g_value_set_object (value, g_dbus_object_manager_client_get_connection (manager));
      break;

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

    case PROP_NAME:
      g_value_set_string (value, g_dbus_object_manager_client_get_name (manager));
      break;

    case PROP_FLAGS:
      g_value_set_flags (value, g_dbus_object_manager_client_get_flags (manager));
      break;

    case PROP_NAME_OWNER:
      g_value_take_string (value, g_dbus_object_manager_client_get_name_owner (manager));
      break;

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

static void
g_dbus_object_manager_client_set_property (GObject       *_object,
                                           guint          prop_id,
                                           const GValue  *value,
                                           GParamSpec    *pspec)
{
  GDBusObjectManagerClient *manager = G_DBUS_OBJECT_MANAGER_CLIENT (_object);
  const gchar *name;

  switch (prop_id)
    {
    case PROP_BUS_TYPE:
      manager->priv->bus_type = g_value_get_enum (value);
      break;

    case PROP_CONNECTION:
      if (g_value_get_object (value) != NULL)
        {
          g_assert (manager->priv->connection == NULL);
          g_assert (G_IS_DBUS_CONNECTION (g_value_get_object (value)));
          manager->priv->connection = g_value_dup_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);
      break;

    case PROP_NAME:
      g_assert (manager->priv->name == NULL);
      name = g_value_get_string (value);
      g_assert (name == NULL || g_dbus_is_name (name));
      manager->priv->name = g_strdup (name);
      break;

    case PROP_FLAGS:
      manager->priv->flags = g_value_get_flags (value);
      break;

    case PROP_GET_PROXY_TYPE_FUNC:
      manager->priv->get_proxy_type_func = g_value_get_pointer (value);
      break;

    case PROP_GET_PROXY_TYPE_USER_DATA:
      manager->priv->get_proxy_type_user_data = g_value_get_pointer (value);
      break;

    case PROP_GET_PROXY_TYPE_DESTROY_NOTIFY:
      manager->priv->get_proxy_type_destroy_notify = g_value_get_pointer (value);
      break;

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

static void
g_dbus_object_manager_client_class_init (GDBusObjectManagerClientClass *klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);

  gobject_class->dispose      = g_dbus_object_manager_client_dispose;
  gobject_class->finalize     = g_dbus_object_manager_client_finalize;
  gobject_class->set_property = g_dbus_object_manager_client_set_property;
  gobject_class->get_property = g_dbus_object_manager_client_get_property;

  /**
   * GDBusObjectManagerClient:connection:
   *
   * The #GDBusConnection to use.
   *
   * Since: 2.30
   */
  g_object_class_install_property (gobject_class,
                                   PROP_CONNECTION,
                                   g_param_spec_object ("connection",
                                                        "Connection",
                                                        "The connection to use",
                                                        G_TYPE_DBUS_CONNECTION,
                                                        G_PARAM_READABLE |
                                                        G_PARAM_WRITABLE |
                                                        G_PARAM_CONSTRUCT_ONLY |
                                                        G_PARAM_STATIC_STRINGS));

  /**
   * GDBusObjectManagerClient:bus-type:
   *
   * If this property is not %G_BUS_TYPE_NONE, then
   * #GDBusObjectManagerClient:connection must be %NULL and will be set to the
   * #GDBusConnection obtained by calling g_bus_get() with the value
   * of this property.
   *
   * Since: 2.30
   */
  g_object_class_install_property (gobject_class,
                                   PROP_BUS_TYPE,
                                   g_param_spec_enum ("bus-type",
                                                      "Bus Type",
                                                      "The bus to connect to, if any",
                                                      G_TYPE_BUS_TYPE,
                                                      G_BUS_TYPE_NONE,
                                                      G_PARAM_WRITABLE |
                                                      G_PARAM_CONSTRUCT_ONLY |
                                                      G_PARAM_STATIC_NAME |
                                                      G_PARAM_STATIC_BLURB |
                                                      G_PARAM_STATIC_NICK));

  /**
   * GDBusObjectManagerClient:flags:
   *
   * Flags from the #GDBusObjectManagerClientFlags enumeration.
   *
   * Since: 2.30
   */
  g_object_class_install_property (gobject_class,
                                   PROP_FLAGS,
                                   g_param_spec_flags ("flags",
                                                       "Flags",
                                                       "Flags for the proxy manager",
                                                       G_TYPE_DBUS_OBJECT_MANAGER_CLIENT_FLAGS,
                                                       G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE,
                                                       G_PARAM_READABLE |
                                                       G_PARAM_WRITABLE |
                                                       G_PARAM_CONSTRUCT_ONLY |
                                                       G_PARAM_STATIC_NAME |
                                                       G_PARAM_STATIC_BLURB |
                                                       G_PARAM_STATIC_NICK));

  /**
   * GDBusObjectManagerClient:object-path:
   *
   * The object path the manager is for.
   *
   * Since: 2.30
   */
  g_object_class_install_property (gobject_class,
                                   PROP_OBJECT_PATH,
                                   g_param_spec_string ("object-path",
                                                        "Object Path",
                                                        "The object path of the control object",
                                                        NULL,
                                                        G_PARAM_READABLE |
                                                        G_PARAM_WRITABLE |
                                                        G_PARAM_CONSTRUCT_ONLY |
                                                        G_PARAM_STATIC_STRINGS));

  /**
   * GDBusObjectManagerClient:name:
   *
   * The well-known name or unique name that the manager is for.
   *
   * Since: 2.30
   */
  g_object_class_install_property (gobject_class,
                                   PROP_NAME,
                                   g_param_spec_string ("name",
                                                        "Name",
                                                        "Name that the manager is for",
                                                        NULL,
                                                        G_PARAM_READABLE |
                                                        G_PARAM_WRITABLE |
                                                        G_PARAM_CONSTRUCT_ONLY |
                                                        G_PARAM_STATIC_STRINGS));

  /**
   * GDBusObjectManagerClient:name-owner:
   *
   * The unique name that owns #GDBusObjectManagerClient:name or %NULL if
   * no-one is currently owning the name. Connect to the
   * #GObject::notify signal to track changes to this property.
   *
   * Since: 2.30
   */
  g_object_class_install_property (gobject_class,
                                   PROP_NAME_OWNER,
                                   g_param_spec_string ("name-owner",
                                                        "Name Owner",
                                                        "The owner of the name we are watching",
                                                        NULL,
                                                        G_PARAM_READABLE |
                                                        G_PARAM_STATIC_STRINGS));

  /**
   * GDBusObjectManagerClient:get-proxy-type-func:
   *
   * The #GDBusProxyTypeFunc to use when determining what #GType to
   * use for interface proxies or %NULL.
   *
   * Since: 2.30
   */
  g_object_class_install_property (gobject_class,
                                   PROP_GET_PROXY_TYPE_FUNC,
                                   g_param_spec_pointer ("get-proxy-type-func",
                                                         "GDBusProxyTypeFunc Function Pointer",
                                                         "The GDBusProxyTypeFunc pointer to use",
                                                         G_PARAM_READABLE |
                                                         G_PARAM_WRITABLE |
                                                         G_PARAM_CONSTRUCT_ONLY |
                                                         G_PARAM_STATIC_STRINGS));

  /**
   * GDBusObjectManagerClient:get-proxy-type-user-data:
   *
   * The #gpointer user_data to pass to #GDBusObjectManagerClient:get-proxy-type-func.
   *
   * Since: 2.30
   */
  g_object_class_install_property (gobject_class,
                                   PROP_GET_PROXY_TYPE_USER_DATA,
                                   g_param_spec_pointer ("get-proxy-type-user-data",
                                                         "GDBusProxyTypeFunc User Data",
                                                         "The GDBusProxyTypeFunc user_data",
                                                         G_PARAM_READABLE |
                                                         G_PARAM_WRITABLE |
                                                         G_PARAM_CONSTRUCT_ONLY |
                                                         G_PARAM_STATIC_STRINGS));

  /**
   * GDBusObjectManagerClient:get-proxy-type-destroy-notify:
   *
   * A #GDestroyNotify for the #gpointer user_data in #GDBusObjectManagerClient:get-proxy-type-user-data.
   *
   * Since: 2.30
   */
  g_object_class_install_property (gobject_class,
                                   PROP_GET_PROXY_TYPE_DESTROY_NOTIFY,
                                   g_param_spec_pointer ("get-proxy-type-destroy-notify",
                                                         "GDBusProxyTypeFunc user data free function",
                                                         "The GDBusProxyTypeFunc user data free function",
                                                         G_PARAM_READABLE |
                                                         G_PARAM_WRITABLE |
                                                         G_PARAM_CONSTRUCT_ONLY |
                                                         G_PARAM_STATIC_STRINGS));

  /**
   * GDBusObjectManagerClient::interface-proxy-signal:
   * @manager: The #GDBusObjectManagerClient emitting the signal.
   * @object_proxy: The #GDBusObjectProxy on which an interface is emitting a D-Bus signal.
   * @interface_proxy: The #GDBusProxy that is emitting a D-Bus signal.
   * @sender_name: The sender of the signal or NULL if the connection is not a bus connection.
   * @signal_name: The signal name.
   * @parameters: A #GVariant tuple with parameters for the signal.
   *
   * Emitted when a D-Bus signal is received on @interface_proxy.
   *
   * This signal exists purely as a convenience to avoid having to
   * connect signals to all interface proxies managed by @manager.
   *
   * This signal is emitted in the
   * [thread-default main context][g-main-context-push-thread-default]
   * that @manager was constructed in.
   *
   * Since: 2.30
   */
  signals[INTERFACE_PROXY_SIGNAL_SIGNAL] =
    g_signal_new (I_("interface-proxy-signal"),
                  G_TYPE_DBUS_OBJECT_MANAGER_CLIENT,
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (GDBusObjectManagerClientClass, interface_proxy_signal),
                  NULL,
                  NULL,
                  _g_cclosure_marshal_VOID__OBJECT_OBJECT_STRING_STRING_VARIANT,
                  G_TYPE_NONE,
                  5,
                  G_TYPE_DBUS_OBJECT_PROXY,
                  G_TYPE_DBUS_PROXY,
                  G_TYPE_STRING,
                  G_TYPE_STRING,
                  G_TYPE_VARIANT);
  g_signal_set_va_marshaller (signals[INTERFACE_PROXY_SIGNAL_SIGNAL],
                              G_TYPE_FROM_CLASS (klass),
                              _g_cclosure_marshal_VOID__OBJECT_OBJECT_STRING_STRING_VARIANTv);

  /**
   * GDBusObjectManagerClient::interface-proxy-properties-changed:
   * @manager: The #GDBusObjectManagerClient emitting the signal.
   * @object_proxy: The #GDBusObjectProxy on which an interface has properties that are changing.
   * @interface_proxy: The #GDBusProxy that has properties that are changing.
   * @changed_properties: A #GVariant containing the properties that changed (type: `a{sv}`).
   * @invalidated_properties: (array zero-terminated=1) (element-type utf8): A %NULL terminated
   *   array of properties that were invalidated.
   *
   * Emitted when one or more D-Bus properties on proxy changes. The
   * local cache has already been updated when this signal fires. Note
   * that both @changed_properties and @invalidated_properties are
   * guaranteed to never be %NULL (either may be empty though).
   *
   * This signal exists purely as a convenience to avoid having to
   * connect signals to all interface proxies managed by @manager.
   *
   * This signal is emitted in the
   * [thread-default main context][g-main-context-push-thread-default]
   * that @manager was constructed in.
   *
   * Since: 2.30
   */
  signals[INTERFACE_PROXY_PROPERTIES_CHANGED_SIGNAL] =
    g_signal_new (I_("interface-proxy-properties-changed"),
                  G_TYPE_DBUS_OBJECT_MANAGER_CLIENT,
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (GDBusObjectManagerClientClass, interface_proxy_properties_changed),
                  NULL,
                  NULL,
                  _g_cclosure_marshal_VOID__OBJECT_OBJECT_VARIANT_BOXED,
                  G_TYPE_NONE,
                  4,
                  G_TYPE_DBUS_OBJECT_PROXY,
                  G_TYPE_DBUS_PROXY,
                  G_TYPE_VARIANT,
                  G_TYPE_STRV);
  g_signal_set_va_marshaller (signals[INTERFACE_PROXY_PROPERTIES_CHANGED_SIGNAL],
                              G_TYPE_FROM_CLASS (klass),
                              _g_cclosure_marshal_VOID__OBJECT_OBJECT_VARIANT_BOXEDv);
}

static void
g_dbus_object_manager_client_init (GDBusObjectManagerClient *manager)
{
  manager->priv = g_dbus_object_manager_client_get_instance_private (manager);
  g_mutex_init (&manager->priv->lock);
  manager->priv->map_object_path_to_object_proxy = g_hash_table_new_full (g_str_hash,
                                                                          g_str_equal,
                                                                          g_free,
                                                                          (GDestroyNotify) g_object_unref);
  manager->priv->cancel = g_cancellable_new ();
}

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

/**
 * g_dbus_object_manager_client_new_sync:
 * @connection: A #GDBusConnection.
 * @flags: Zero or more flags from the #GDBusObjectManagerClientFlags enumeration.
 * @name: (nullable): The owner of the control object (unique or well-known name), or %NULL when not using a message bus connection.
 * @object_path: The object path of the control object.
 * @get_proxy_type_func: (nullable): A #GDBusProxyTypeFunc function or %NULL to always construct #GDBusProxy proxies.
 * @get_proxy_type_user_data: User data to pass to @get_proxy_type_func.
 * @get_proxy_type_destroy_notify: (nullable): Free function for @get_proxy_type_user_data or %NULL.
 * @cancellable: (nullable): A #GCancellable or %NULL
 * @error: Return location for error or %NULL.
 *
 * Creates a new #GDBusObjectManagerClient object.
 *
 * This is a synchronous failable constructor - the calling thread is
 * blocked until a reply is received. See g_dbus_object_manager_client_new()
 * for the asynchronous version.
 *
 * Returns: (transfer full) (type GDBusObjectManagerClient): A
 *   #GDBusObjectManagerClient object or %NULL if @error is set. Free
 *   with g_object_unref().
 *
 * Since: 2.30
 */
GDBusObjectManager *
g_dbus_object_manager_client_new_sync (GDBusConnection               *connection,
                                       GDBusObjectManagerClientFlags  flags,
                                       const gchar                   *name,
                                       const gchar                   *object_path,
                                       GDBusProxyTypeFunc             get_proxy_type_func,
                                       gpointer                       get_proxy_type_user_data,
                                       GDestroyNotify                 get_proxy_type_destroy_notify,
                                       GCancellable                  *cancellable,
                                       GError                       **error)
{
  GInitable *initable;

  g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
  g_return_val_if_fail ((name == NULL && g_dbus_connection_get_unique_name (connection) == NULL) ||
                        g_dbus_is_name (name), NULL);
  g_return_val_if_fail (g_variant_is_object_path (object_path), NULL);
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);

  initable = g_initable_new (G_TYPE_DBUS_OBJECT_MANAGER_CLIENT,
                             cancellable,
                             error,
                             "connection", connection,
                             "flags", flags,
                             "name", name,
                             "object-path", object_path,
                             "get-proxy-type-func", get_proxy_type_func,
                             "get-proxy-type-user-data", get_proxy_type_user_data,
                             "get-proxy-type-destroy-notify", get_proxy_type_destroy_notify,
                             NULL);
  if (initable != NULL)
    return G_DBUS_OBJECT_MANAGER (initable);
  else
    return NULL;
}

/**
 * g_dbus_object_manager_client_new:
 * @connection: A #GDBusConnection.
 * @flags: Zero or more flags from the #GDBusObjectManagerClientFlags enumeration.
 * @name: The owner of the control object (unique or well-known name).
 * @object_path: The object path of the control object.
 * @get_proxy_type_func: (nullable): A #GDBusProxyTypeFunc function or %NULL to always construct #GDBusProxy proxies.
 * @get_proxy_type_user_data: User data to pass to @get_proxy_type_func.
 * @get_proxy_type_destroy_notify: (nullable): Free function for @get_proxy_type_user_data or %NULL.
 * @cancellable: (nullable): A #GCancellable or %NULL
 * @callback: A #GAsyncReadyCallback to call when the request is satisfied.
 * @user_data: The data to pass to @callback.
 *
 * Asynchronously creates a new #GDBusObjectManagerClient object.
 *
 * This is an asynchronous failable constructor. When the result is
 * ready, @callback will be invoked in the
 * [thread-default main context][g-main-context-push-thread-default]
 * of the thread you are calling this method from. You can
 * then call g_dbus_object_manager_client_new_finish() to get the result. See
 * g_dbus_object_manager_client_new_sync() for the synchronous version.
 *
 * Since: 2.30
 */
void
g_dbus_object_manager_client_new (GDBusConnection               *connection,
                                  GDBusObjectManagerClientFlags  flags,
                                  const gchar                   *name,
                                  const gchar                   *object_path,
                                  GDBusProxyTypeFunc             get_proxy_type_func,
                                  gpointer                       get_proxy_type_user_data,
                                  GDestroyNotify                 get_proxy_type_destroy_notify,
                                  GCancellable                  *cancellable,
                                  GAsyncReadyCallback            callback,
                                  gpointer                       user_data)
{
  g_return_if_fail (G_IS_DBUS_CONNECTION (connection));
  g_return_if_fail ((name == NULL && g_dbus_connection_get_unique_name (connection) == NULL) ||
                        g_dbus_is_name (name));
  g_return_if_fail (g_variant_is_object_path (object_path));

  g_async_initable_new_async (G_TYPE_DBUS_OBJECT_MANAGER_CLIENT,
                              G_PRIORITY_DEFAULT,
                              cancellable,
                              callback,
                              user_data,
                              "connection", connection,
                              "flags", flags,
                              "name", name,
                              "object-path", object_path,
                              "get-proxy-type-func", get_proxy_type_func,
                              "get-proxy-type-user-data", get_proxy_type_user_data,
                              "get-proxy-type-destroy-notify", get_proxy_type_destroy_notify,
                              NULL);
}

/**
 * g_dbus_object_manager_client_new_finish:
 * @res: A #GAsyncResult obtained from the #GAsyncReadyCallback passed to g_dbus_object_manager_client_new().
 * @error: Return location for error or %NULL.
 *
 * Finishes an operation started with g_dbus_object_manager_client_new().
 *
 * Returns: (transfer full) (type GDBusObjectManagerClient): A
 *   #GDBusObjectManagerClient object or %NULL if @error is set. Free
 *   with g_object_unref().
 *
 * Since: 2.30
 */
GDBusObjectManager *
g_dbus_object_manager_client_new_finish (GAsyncResult   *res,
                                         GError        **error)
{
  GObject *object;
  GObject *source_object;

  source_object = g_async_result_get_source_object (res);
  g_assert (source_object != NULL);

  object = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object),
                                        res,
                                        error);
  g_object_unref (source_object);

  if (object != NULL)
    return G_DBUS_OBJECT_MANAGER (object);
  else
    return NULL;
}

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

/**
 * g_dbus_object_manager_client_new_for_bus_sync:
 * @bus_type: A #GBusType.
 * @flags: Zero or more flags from the #GDBusObjectManagerClientFlags enumeration.
 * @name: The owner of the control object (unique or well-known name).
 * @object_path: The object path of the control object.
 * @get_proxy_type_func: (nullable): A #GDBusProxyTypeFunc function or %NULL to always construct #GDBusProxy proxies.
 * @get_proxy_type_user_data: User data to pass to @get_proxy_type_func.
 * @get_proxy_type_destroy_notify: (nullable): Free function for @get_proxy_type_user_data or %NULL.
 * @cancellable: (nullable): A #GCancellable or %NULL
 * @error: Return location for error or %NULL.
 *
 * Like g_dbus_object_manager_client_new_sync() but takes a #GBusType instead
 * of a #GDBusConnection.
 *
 * This is a synchronous failable constructor - the calling thread is
 * blocked until a reply is received. See g_dbus_object_manager_client_new_for_bus()
 * for the asynchronous version.
 *
 * Returns: (transfer full) (type GDBusObjectManagerClient): A
 *   #GDBusObjectManagerClient object or %NULL if @error is set. Free
 *   with g_object_unref().
 *
 * Since: 2.30
 */
GDBusObjectManager *
g_dbus_object_manager_client_new_for_bus_sync (GBusType                       bus_type,
                                               GDBusObjectManagerClientFlags  flags,
                                               const gchar                   *name,
                                               const gchar                   *object_path,
                                               GDBusProxyTypeFunc             get_proxy_type_func,
                                               gpointer                       get_proxy_type_user_data,
                                               GDestroyNotify                 get_proxy_type_destroy_notify,
                                               GCancellable                  *cancellable,
                                               GError                       **error)
{
  GInitable *initable;

  g_return_val_if_fail (bus_type != G_BUS_TYPE_NONE, NULL);
  g_return_val_if_fail (g_dbus_is_name (name), NULL);
  g_return_val_if_fail (g_variant_is_object_path (object_path), NULL);
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);

  initable = g_initable_new (G_TYPE_DBUS_OBJECT_MANAGER_CLIENT,
                             cancellable,
                             error,
                             "bus-type", bus_type,
                             "flags", flags,
                             "name", name,
                             "object-path", object_path,
                             "get-proxy-type-func", get_proxy_type_func,
                             "get-proxy-type-user-data", get_proxy_type_user_data,
                             "get-proxy-type-destroy-notify", get_proxy_type_destroy_notify,
                             NULL);
  if (initable != NULL)
    return G_DBUS_OBJECT_MANAGER (initable);
  else
    return NULL;
}

/**
 * g_dbus_object_manager_client_new_for_bus:
 * @bus_type: A #GBusType.
 * @flags: Zero or more flags from the #GDBusObjectManagerClientFlags enumeration.
 * @name: The owner of the control object (unique or well-known name).
 * @object_path: The object path of the control object.
 * @get_proxy_type_func: (nullable): A #GDBusProxyTypeFunc function or %NULL to always construct #GDBusProxy proxies.
 * @get_proxy_type_user_data: User data to pass to @get_proxy_type_func.
 * @get_proxy_type_destroy_notify: (nullable): Free function for @get_proxy_type_user_data or %NULL.
 * @cancellable: (nullable): A #GCancellable or %NULL
 * @callback: A #GAsyncReadyCallback to call when the request is satisfied.
 * @user_data: The data to pass to @callback.
 *
 * Like g_dbus_object_manager_client_new() but takes a #GBusType instead of a
 * #GDBusConnection.
 *
 * This is an asynchronous failable constructor. When the result is
 * ready, @callback will be invoked in the
 * [thread-default main loop][g-main-context-push-thread-default]
 * of the thread you are calling this method from. You can
 * then call g_dbus_object_manager_client_new_for_bus_finish() to get the result. See
 * g_dbus_object_manager_client_new_for_bus_sync() for the synchronous version.
 *
 * Since: 2.30
 */
void
g_dbus_object_manager_client_new_for_bus (GBusType                       bus_type,
                                          GDBusObjectManagerClientFlags  flags,
                                          const gchar                   *name,
                                          const gchar                   *object_path,
                                          GDBusProxyTypeFunc             get_proxy_type_func,
                                          gpointer                       get_proxy_type_user_data,
                                          GDestroyNotify                 get_proxy_type_destroy_notify,
                                          GCancellable                  *cancellable,
                                          GAsyncReadyCallback            callback,
                                          gpointer                       user_data)
{
  g_return_if_fail (bus_type != G_BUS_TYPE_NONE);
  g_return_if_fail (g_dbus_is_name (name));
  g_return_if_fail (g_variant_is_object_path (object_path));

  g_async_initable_new_async (G_TYPE_DBUS_OBJECT_MANAGER_CLIENT,
                              G_PRIORITY_DEFAULT,
                              cancellable,
                              callback,
                              user_data,
                              "bus-type", bus_type,
                              "flags", flags,
                              "name", name,
                              "object-path", object_path,
                              "get-proxy-type-func", get_proxy_type_func,
                              "get-proxy-type-user-data", get_proxy_type_user_data,
                              "get-proxy-type-destroy-notify", get_proxy_type_destroy_notify,
                              NULL);
}

/**
 * g_dbus_object_manager_client_new_for_bus_finish:
 * @res: A #GAsyncResult obtained from the #GAsyncReadyCallback passed to g_dbus_object_manager_client_new_for_bus().
 * @error: Return location for error or %NULL.
 *
 * Finishes an operation started with g_dbus_object_manager_client_new_for_bus().
 *
 * Returns: (transfer full) (type GDBusObjectManagerClient): A
 *   #GDBusObjectManagerClient object or %NULL if @error is set. Free
 *   with g_object_unref().
 *
 * Since: 2.30
 */
GDBusObjectManager *
g_dbus_object_manager_client_new_for_bus_finish (GAsyncResult   *res,
                                                 GError        **error)
{
  GObject *object;
  GObject *source_object;

  source_object = g_async_result_get_source_object (res);
  g_assert (source_object != NULL);

  object = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object),
                                        res,
                                        error);
  g_object_unref (source_object);

  if (object != NULL)
    return G_DBUS_OBJECT_MANAGER (object);
  else
    return NULL;
}

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

/**
 * g_dbus_object_manager_client_get_connection:
 * @manager: A #GDBusObjectManagerClient
 *
 * Gets the #GDBusConnection used by @manager.
 *
 * Returns: (transfer none): A #GDBusConnection object. Do not free,
 *   the object belongs to @manager.
 *
 * Since: 2.30
 */
GDBusConnection *
g_dbus_object_manager_client_get_connection (GDBusObjectManagerClient *manager)
{
  GDBusConnection *ret;
  g_return_val_if_fail (G_IS_DBUS_OBJECT_MANAGER_CLIENT (manager), NULL);
  g_mutex_lock (&manager->priv->lock);
  ret = manager->priv->connection;
  g_mutex_unlock (&manager->priv->lock);
  return ret;
}

/**
 * g_dbus_object_manager_client_get_name:
 * @manager: A #GDBusObjectManagerClient
 *
 * Gets the name that @manager is for, or %NULL if not a message bus
 * connection.
 *
 * Returns: A unique or well-known name. Do not free, the string
 * belongs to @manager.
 *
 * Since: 2.30
 */
const gchar *
g_dbus_object_manager_client_get_name (GDBusObjectManagerClient *manager)
{
  const gchar *ret;
  g_return_val_if_fail (G_IS_DBUS_OBJECT_MANAGER_CLIENT (manager), NULL);
  g_mutex_lock (&manager->priv->lock);
  ret = manager->priv->name;
  g_mutex_unlock (&manager->priv->lock);
  return ret;
}

/**
 * g_dbus_object_manager_client_get_flags:
 * @manager: A #GDBusObjectManagerClient
 *
 * Gets the flags that @manager was constructed with.
 *
 * Returns: Zero of more flags from the #GDBusObjectManagerClientFlags
 * enumeration.
 *
 * Since: 2.30
 */
GDBusObjectManagerClientFlags
g_dbus_object_manager_client_get_flags (GDBusObjectManagerClient *manager)
{
  GDBusObjectManagerClientFlags ret;
  g_return_val_if_fail (G_IS_DBUS_OBJECT_MANAGER_CLIENT (manager), G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE);
  g_mutex_lock (&manager->priv->lock);
  ret = manager->priv->flags;
  g_mutex_unlock (&manager->priv->lock);
  return ret;
}

/**
 * g_dbus_object_manager_client_get_name_owner:
 * @manager: A #GDBusObjectManagerClient.
 *
 * The unique name that owns the name that @manager is for or %NULL if
 * no-one currently owns that name. You can connect to the
 * #GObject::notify signal to track changes to the
 * #GDBusObjectManagerClient:name-owner property.
 *
 * Returns: (nullable): The name owner or %NULL if no name owner
 * exists. Free with g_free().
 *
 * Since: 2.30
 */
gchar *
g_dbus_object_manager_client_get_name_owner (GDBusObjectManagerClient *manager)
{
  gchar *ret;
  g_return_val_if_fail (G_IS_DBUS_OBJECT_MANAGER_CLIENT (manager), NULL);
  g_mutex_lock (&manager->priv->lock);
  ret = g_strdup (manager->priv->name_owner);
  g_mutex_unlock (&manager->priv->lock);
  return ret;
}

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

/* signal handler for all objects we manage - we dispatch signals
 * from here to the objects
 */
static void
signal_cb (GDBusConnection *connection,
           const gchar     *sender_name,
           const gchar     *object_path,
           const gchar     *interface_name,
           const gchar     *signal_name,
           GVariant        *parameters,
           gpointer         user_data)
{
  GDBusObjectManagerClient *manager = G_DBUS_OBJECT_MANAGER_CLIENT (user_data);
  GDBusObjectProxy *object_proxy;
  GDBusInterface *interface;

  g_mutex_lock (&manager->priv->lock);
  object_proxy = g_hash_table_lookup (manager->priv->map_object_path_to_object_proxy, object_path);
  if (object_proxy == NULL)
    {
      g_mutex_unlock (&manager->priv->lock);
      goto out;
    }
  g_object_ref (object_proxy);
  g_mutex_unlock (&manager->priv->lock);

  //g_debug ("yay, signal_cb %s %s: %s\n", signal_name, object_path, g_variant_print (parameters, TRUE));

  g_object_ref (manager);
  if (g_strcmp0 (interface_name, "org.freedesktop.DBus.Properties") == 0)
    {
      if (g_strcmp0 (signal_name, "PropertiesChanged") == 0)
        {
          const gchar *interface_name;
          GVariant *changed_properties;
          const gchar **invalidated_properties;

          g_variant_get (parameters,
                         "(&s@a{sv}^a&s)",
                         &interface_name,
                         &changed_properties,
                         &invalidated_properties);

          interface = g_dbus_object_get_interface (G_DBUS_OBJECT (object_proxy), interface_name);
          if (interface != NULL)
            {
              GVariantIter property_iter;
              const gchar *property_name;
              GVariant *property_value;
              guint n;

              /* update caches... */
              g_variant_iter_init (&property_iter, changed_properties);
              while (g_variant_iter_next (&property_iter,
                                          "{&sv}",
                                          &property_name,
                                          &property_value))
                {
                  g_dbus_proxy_set_cached_property (G_DBUS_PROXY (interface),
                                                    property_name,
                                                    property_value);
                  g_variant_unref (property_value);
                }

              for (n = 0; invalidated_properties[n] != NULL; n++)
                {
                  g_dbus_proxy_set_cached_property (G_DBUS_PROXY (interface),
                                                    invalidated_properties[n],
                                                    NULL);
                }
              /* ... and then synthesize the signal */
              g_signal_emit_by_name (interface,
                                     "g-properties-changed",
                                     changed_properties,
                                     invalidated_properties);
              g_signal_emit (manager,
                             signals[INTERFACE_PROXY_PROPERTIES_CHANGED_SIGNAL],
                             0,
                             object_proxy,
                             interface,
                             changed_properties,
                             invalidated_properties);
              g_object_unref (interface);
            }
          g_variant_unref (changed_properties);
          g_free (invalidated_properties);
        }
    }
  else
    {
      /* regular signal - just dispatch it */
      interface = g_dbus_object_get_interface (G_DBUS_OBJECT (object_proxy), interface_name);
      if (interface != NULL)
        {
          g_signal_emit_by_name (interface,
                                 "g-signal",
                                 sender_name,
                                 signal_name,
                                 parameters);
          g_signal_emit (manager,
                         signals[INTERFACE_PROXY_SIGNAL_SIGNAL],
                         0,
                         object_proxy,
                         interface,
                         sender_name,
                         signal_name,
                         parameters);
          g_object_unref (interface);
        }
    }
  g_object_unref (manager);

 out:
  g_clear_object (&object_proxy);
}

static void
subscribe_signals (GDBusObjectManagerClient *manager,
                   const gchar *name_owner)
{
  GError *error = NULL;
  GVariant *ret;

  g_return_if_fail (G_IS_DBUS_OBJECT_MANAGER_CLIENT (manager));
  g_return_if_fail (manager->priv->signal_subscription_id == 0);
  g_return_if_fail (name_owner == NULL || g_dbus_is_unique_name (name_owner));

  if (name_owner != NULL)
    {
      /* Only add path_namespace if it's non-'/'. This removes a no-op key from
       * the match rule, and also works around a D-Bus bug where
       * path_namespace='/' matches nothing in D-Bus versions < 1.6.18.
       *
       * See: https://bugs.freedesktop.org/show_bug.cgi?id=70799 */
      if (g_str_equal (manager->priv->object_path, "/"))
        {
          manager->priv->match_rule = g_strdup_printf ("type='signal',sender='%s'",
                                                       name_owner);
        }
      else
        {
          manager->priv->match_rule = g_strdup_printf ("type='signal',sender='%s',path_namespace='%s'",
                                                       name_owner, manager->priv->object_path);
        }

      /* The bus daemon may not implement path_namespace so gracefully
       * handle this by using a fallback triggered if @error is set. */
      ret = g_dbus_connection_call_sync (manager->priv->connection,
                                         "org.freedesktop.DBus",
                                         "/org/freedesktop/DBus",
                                         "org.freedesktop.DBus",
                                         "AddMatch",
                                         g_variant_new ("(s)",
                                                        manager->priv->match_rule),
                                         NULL, /* reply_type */
                                         G_DBUS_CALL_FLAGS_NONE,
                                         -1, /* default timeout */
                                         NULL, /* TODO: Cancellable */
                                         &error);

      /* yay, bus daemon supports path_namespace */
      if (ret != NULL)
        g_variant_unref (ret);
    }

  if (error == NULL)
    {
      /* still need to ask GDBusConnection for the callbacks */
      manager->priv->signal_subscription_id =
        g_dbus_connection_signal_subscribe (manager->priv->connection,
                                            name_owner,
                                            NULL, /* interface */
                                            NULL, /* member */
                                            NULL, /* path - TODO: really want wildcard support here */
                                            NULL, /* arg0 */
                                            G_DBUS_SIGNAL_FLAGS_NONE |
                                            G_DBUS_SIGNAL_FLAGS_NO_MATCH_RULE,
                                            signal_cb,
                                            manager,
                                            NULL); /* user_data_free_func */

    }
  else
    {
      /* TODO: we could report this to the user
      g_warning ("Message bus daemon does not support path_namespace: %s (%s %d)",
                 error->message,
                 g_quark_to_string (error->domain),
                 error->code);
      */

      g_error_free (error);

      /* no need to call RemoveMatch when done since it didn't work */
      g_free (manager->priv->match_rule);
      manager->priv->match_rule = NULL;

      /* Fallback is to subscribe to *all* signals from the name owner which
       * is rather wasteful. It's probably not a big practical problem because
       * users typically want all objects that the name owner supplies.
       */
      manager->priv->signal_subscription_id =
        g_dbus_connection_signal_subscribe (manager->priv->connection,
                                            name_owner,
                                            NULL, /* interface */
                                            NULL, /* member */
                                            NULL, /* path - TODO: really want wildcard support here */
                                            NULL, /* arg0 */
                                            G_DBUS_SIGNAL_FLAGS_NONE,
                                            signal_cb,
                                            manager,
                                            NULL); /* user_data_free_func */
    }
}

static void
maybe_unsubscribe_signals (GDBusObjectManagerClient *manager)
{
  g_return_if_fail (G_IS_DBUS_OBJECT_MANAGER_CLIENT (manager));

  if (manager->priv->signal_subscription_id > 0)
    {
      g_dbus_connection_signal_unsubscribe (manager->priv->connection,
                                            manager->priv->signal_subscription_id);
      manager->priv->signal_subscription_id = 0;
    }

  if (manager->priv->match_rule != NULL)
    {
      /* Since the AddMatch call succeeded this is guaranteed to not
       * fail - therefore, don't bother checking the return value
       */
      g_dbus_connection_call (manager->priv->connection,
                              "org.freedesktop.DBus",
                              "/org/freedesktop/DBus",
                              "org.freedesktop.DBus",
                              "RemoveMatch",
                              g_variant_new ("(s)",
                                             manager->priv->match_rule),
                              NULL, /* reply_type */
                              G_DBUS_CALL_FLAGS_NONE,
                              -1, /* default timeout */
                              NULL, /* GCancellable */
                              NULL, /* GAsyncReadyCallback */
                              NULL); /* user data */
      g_free (manager->priv->match_rule);
      manager->priv->match_rule = NULL;
    }

}

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

static GWeakRef *
weak_ref_new (GObject *object)
{
  GWeakRef *weak_ref = g_new0 (GWeakRef, 1);
  g_weak_ref_init (weak_ref, object);
  return g_steal_pointer (&weak_ref);
}

static void
weak_ref_free (GWeakRef *weak_ref)
{
  g_weak_ref_clear (weak_ref);
  g_free (weak_ref);
}

static void
on_get_managed_objects_finish (GObject      *source,
                               GAsyncResult *result,
                               gpointer      user_data)
{

  GDBusProxy *proxy = G_DBUS_PROXY (source);
  GWeakRef *manager_weak = user_data;
  GDBusObjectManagerClient *manager;
  GError *error = NULL;
  GVariant *value = NULL;
  gchar *new_name_owner = NULL;

  value = g_dbus_proxy_call_finish (proxy, result, &error);

  manager = G_DBUS_OBJECT_MANAGER_CLIENT (g_weak_ref_get (manager_weak));
  /* Manager got disposed, nothing to do */
  if (manager == NULL)
    {
      goto out;
    }

  new_name_owner = g_dbus_proxy_get_name_owner (manager->priv->control_proxy);
  if (value == NULL)
    {
      maybe_unsubscribe_signals (manager);
      if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
        {
          g_warning ("Error calling GetManagedObjects() when name owner %s for name %s came back: %s",
                     new_name_owner,
                     manager->priv->name,
                     error->message);
        }
    }
  else
    {
      process_get_all_result (manager, value, new_name_owner);
    }

  /* do the :name-owner notify *AFTER* emitting ::object-proxy-added signals - this
   * way the user knows that the signals were emitted because the name owner came back
   */
  g_mutex_lock (&manager->priv->lock);
  manager->priv->name_owner = g_steal_pointer (&new_name_owner);
  g_mutex_unlock (&manager->priv->lock);
  g_object_notify (G_OBJECT (manager), "name-owner");

  g_object_unref (manager);
 out:
  g_clear_error (&error);
  g_clear_pointer (&value, g_variant_unref);
  weak_ref_free (manager_weak);
}

static void
on_notify_g_name_owner (GObject    *object,
                        GParamSpec *pspec,
                        gpointer    user_data)
{
  GWeakRef *manager_weak = user_data;
  GDBusObjectManagerClient *manager = NULL;
  gchar *old_name_owner;
  gchar *new_name_owner;

  manager = G_DBUS_OBJECT_MANAGER_CLIENT (g_weak_ref_get (manager_weak));
  if (manager == NULL)
    return;

  g_mutex_lock (&manager->priv->lock);
  old_name_owner = manager->priv->name_owner;
  new_name_owner = g_dbus_proxy_get_name_owner (manager->priv->control_proxy);
  manager->priv->name_owner = NULL;

  if (g_strcmp0 (old_name_owner, new_name_owner) != 0)
    {
      GList *l;
      GList *proxies;

      /* remote manager changed; nuke all local proxies  */
      proxies = g_hash_table_get_values (manager->priv->map_object_path_to_object_proxy);
      g_list_foreach (proxies, (GFunc) g_object_ref, NULL);
      g_hash_table_remove_all (manager->priv->map_object_path_to_object_proxy);

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

      /* do the :name-owner notify with a NULL name - this way the user knows
       * the ::object-proxy-removed following is because the name owner went
       * away
       */
      g_object_notify (G_OBJECT (manager), "name-owner");

      for (l = proxies; l != NULL; l = l->next)
        {
          GDBusObjectProxy *object_proxy = G_DBUS_OBJECT_PROXY (l->data);
          g_signal_emit_by_name (manager, "object-removed", object_proxy);
        }
      g_list_free_full (proxies, g_object_unref);

      /* nuke local filter */
      maybe_unsubscribe_signals (manager);
    }
  else
    {
      g_mutex_unlock (&manager->priv->lock);
    }

  if (new_name_owner != NULL)
    {
      //g_debug ("repopulating for %s", new_name_owner);

      subscribe_signals (manager,
                         new_name_owner);
      g_dbus_proxy_call (manager->priv->control_proxy,
                         "GetManagedObjects",
                         NULL, /* parameters */
                         G_DBUS_CALL_FLAGS_NONE,
                         -1,
                         manager->priv->cancel,
                         on_get_managed_objects_finish,
                         weak_ref_new (G_OBJECT (manager)));
    }
  g_free (new_name_owner);
  g_free (old_name_owner);
  g_object_unref (manager);
}

static gboolean
initable_init (GInitable     *initable,
               GCancellable  *cancellable,
               GError       **error)
{
  GDBusObjectManagerClient *manager = G_DBUS_OBJECT_MANAGER_CLIENT (initable);
  gboolean ret;
  GVariant *value;
  GDBusProxyFlags proxy_flags;

  ret = FALSE;

  if (manager->priv->bus_type != G_BUS_TYPE_NONE)
    {
      g_assert (manager->priv->connection == NULL);
      manager->priv->connection = g_bus_get_sync (manager->priv->bus_type, cancellable, error);
      if (manager->priv->connection == NULL)
        goto out;
    }

  proxy_flags = G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES;
  if (manager->priv->flags & G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_DO_NOT_AUTO_START)
    proxy_flags |= G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START;

  manager->priv->control_proxy = g_dbus_proxy_new_sync (manager->priv->connection,
                                                        proxy_flags,
                                                        NULL, /* GDBusInterfaceInfo* */
                                                        manager->priv->name,
                                                        manager->priv->object_path,
                                                        "org.freedesktop.DBus.ObjectManager",
                                                        cancellable,
                                                        error);
  if (manager->priv->control_proxy == NULL)
    goto out;

  /* Use weak refs here. The @control_proxy will emit its signals in the current
   * #GMainContext (since we constructed it just above). However, the user may
   * drop the last external reference to this #GDBusObjectManagerClient in
   * another thread between a signal being emitted and scheduled in an idle
   * callback in this #GMainContext, and that idle callback being invoked. We
   * can’t use a strong reference here, as there’s no
   * g_dbus_object_manager_client_disconnect() (or similar) method to tell us
   * when the last external reference to this object has been dropped, so we
   * can’t break a strong reference count cycle. So use weak refs. */
  manager->priv->name_owner_signal_id =
      g_signal_connect_data (G_OBJECT (manager->priv->control_proxy),
                            "notify::g-name-owner",
                            G_CALLBACK (on_notify_g_name_owner),
                            weak_ref_new (G_OBJECT (manager)),
                            (GClosureNotify) weak_ref_free,
                            0  /* flags */);

  manager->priv->signal_signal_id =
      g_signal_connect_data (manager->priv->control_proxy,
                            "g-signal",
                            G_CALLBACK (on_control_proxy_g_signal),
                            weak_ref_new (G_OBJECT (manager)),
                            (GClosureNotify) weak_ref_free,
                            0  /* flags */);

  manager->priv->name_owner = g_dbus_proxy_get_name_owner (manager->priv->control_proxy);
  if (manager->priv->name_owner == NULL && manager->priv->name != NULL)
    {
      /* it's perfectly fine if there's no name owner.. we're just going to
       * wait until one is ready
       */
    }
  else
    {
      /* yay, we can get the objects */
      subscribe_signals (manager,
                         manager->priv->name_owner);
      value = g_dbus_proxy_call_sync (manager->priv->control_proxy,
                                      "GetManagedObjects",
                                      NULL, /* parameters */
                                      G_DBUS_CALL_FLAGS_NONE,
                                      -1,
                                      cancellable,
                                      error);
      if (value == NULL)
        {
          maybe_unsubscribe_signals (manager);

          g_warn_if_fail (manager->priv->signal_signal_id != 0);
          g_signal_handler_disconnect (manager->priv->control_proxy,
                                       manager->priv->signal_signal_id);
          manager->priv->signal_signal_id = 0;

          g_warn_if_fail (manager->priv->name_owner_signal_id != 0);
          g_signal_handler_disconnect (manager->priv->control_proxy,
                                       manager->priv->name_owner_signal_id);
          manager->priv->name_owner_signal_id = 0;

          g_object_unref (manager->priv->control_proxy);
          manager->priv->control_proxy = NULL;

          goto out;
        }

      process_get_all_result (manager, value, manager->priv->name_owner);
      g_variant_unref (value);
    }

  ret = TRUE;

 out:
  return ret;
}

static void
initable_iface_init (GInitableIface *initable_iface)
{
  initable_iface->init = initable_init;
}

static void
async_initable_iface_init (GAsyncInitableIface *async_initable_iface)
{
  /* for now, just use default: run GInitable code in thread */
}

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

static void
add_interfaces (GDBusObjectManagerClient *manager,
                const gchar       *object_path,
                GVariant          *ifaces_and_properties,
                const gchar       *name_owner)
{
  GDBusObjectProxy *op;
  gboolean added;
  GVariantIter iter;
  const gchar *interface_name;
  GVariant *properties;
  GList *interface_added_signals, *l;
  GDBusProxy *interface_proxy;

  g_return_if_fail (name_owner == NULL || g_dbus_is_unique_name (name_owner));

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

  interface_added_signals = NULL;
  added = FALSE;

  op = g_hash_table_lookup (manager->priv->map_object_path_to_object_proxy, object_path);
  if (op == NULL)
    {
      GType object_proxy_type;
      if (manager->priv->get_proxy_type_func != NULL)
        {
          object_proxy_type = manager->priv->get_proxy_type_func (manager,
                                                                  object_path,
                                                                  NULL,
                                                                  manager->priv->get_proxy_type_user_data);
          g_warn_if_fail (g_type_is_a (object_proxy_type, G_TYPE_DBUS_OBJECT_PROXY));
        }
      else
        {
          object_proxy_type = G_TYPE_DBUS_OBJECT_PROXY;
        }
      op = g_object_new (object_proxy_type,
                         "g-connection", manager->priv->connection,
                         "g-object-path", object_path,
                         NULL);
      added = TRUE;
    }
  g_object_ref (op);

  g_variant_iter_init (&iter, ifaces_and_properties);
  while (g_variant_iter_next (&iter,
                              "{&s@a{sv}}",
                              &interface_name,
                              &properties))
    {
      GError *error;
      GType interface_proxy_type;

      if (manager->priv->get_proxy_type_func != NULL)
        {
          interface_proxy_type = manager->priv->get_proxy_type_func (manager,
                                                                     object_path,
                                                                     interface_name,
                                                                     manager->priv->get_proxy_type_user_data);
          g_warn_if_fail (g_type_is_a (interface_proxy_type, G_TYPE_DBUS_PROXY));
        }
      else
        {
          interface_proxy_type = G_TYPE_DBUS_PROXY;
        }

      /* this is fine - there is no blocking IO because we pass DO_NOT_LOAD_PROPERTIES and
       * DO_NOT_CONNECT_SIGNALS and use a unique name
       */
      error = NULL;
      interface_proxy = g_initable_new (interface_proxy_type,
                                        NULL, /* GCancellable */
                                        &error,
                                        "g-connection", manager->priv->connection,
                                        "g-flags", G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
                                                   G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
                                        "g-name", name_owner,
                                        "g-object-path", object_path,
                                        "g-interface-name", interface_name,
                                        NULL);
      if (interface_proxy == NULL)
        {
          g_warning ("%s: Error constructing proxy for path %s and interface %s: %s",
                     G_STRLOC,
                     object_path,
                     interface_name,
                     error->message);
          g_error_free (error);
        }
      else
        {
          GVariantIter property_iter;
          const gchar *property_name;
          GVariant *property_value;

          /* associate the interface proxy with the object */
          g_dbus_interface_set_object (G_DBUS_INTERFACE (interface_proxy),
                                       G_DBUS_OBJECT (op));

          g_variant_iter_init (&property_iter, properties);
          while (g_variant_iter_next (&property_iter,
                                      "{&sv}",
                                      &property_name,
                                      &property_value))
            {
              g_dbus_proxy_set_cached_property (interface_proxy,
                                                property_name,
                                                property_value);
              g_variant_unref (property_value);
            }

          _g_dbus_object_proxy_add_interface (op, interface_proxy);
          if (!added)
            interface_added_signals = g_list_append (interface_added_signals, g_object_ref (interface_proxy));
          g_object_unref (interface_proxy);
        }
      g_variant_unref (properties);
    }

  if (added)
    {
      g_hash_table_insert (manager->priv->map_object_path_to_object_proxy,
                           g_strdup (object_path),
                           op);
    }

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

  /* now that we don't hold the lock any more, emit signals */
  g_object_ref (manager);
  for (l = interface_added_signals; l != NULL; l = l->next)
    {
      interface_proxy = G_DBUS_PROXY (l->data);
      g_signal_emit_by_name (manager, "interface-added", op, interface_proxy);
      g_object_unref (interface_proxy);
    }
  g_list_free (interface_added_signals);

  if (added)
    g_signal_emit_by_name (manager, "object-added", op);

  g_object_unref (manager);
  g_object_unref (op);
}

static void
remove_interfaces (GDBusObjectManagerClient   *manager,
                   const gchar         *object_path,
                   const gchar *const  *interface_names)
{
  GDBusObjectProxy *op;
  GList *interfaces;
  guint n;
  guint num_interfaces;
  guint num_interfaces_to_remove;

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

  op = g_hash_table_lookup (manager->priv->map_object_path_to_object_proxy, object_path);
  if (op == NULL)
    {
      g_warning ("%s: Processing InterfaceRemoved signal for path %s but no object proxy exists",
                 G_STRLOC,
                 object_path);
      g_mutex_unlock (&manager->priv->lock);
      goto out;
    }

  interfaces = g_dbus_object_get_interfaces (G_DBUS_OBJECT (op));
  num_interfaces = g_list_length (interfaces);
  g_list_free_full (interfaces, g_object_unref);

  num_interfaces_to_remove = g_strv_length ((gchar **) interface_names);

  /* see if we are going to completety remove the object */
  g_object_ref (manager);
  if (num_interfaces_to_remove == num_interfaces)
    {
      g_object_ref (op);
      g_warn_if_fail (g_hash_table_remove (manager->priv->map_object_path_to_object_proxy, object_path));
      g_mutex_unlock (&manager->priv->lock);
      g_signal_emit_by_name (manager, "object-removed", op);
      g_object_unref (op);
    }
  else
    {
      g_object_ref (op);
      g_mutex_unlock (&manager->priv->lock);
      for (n = 0; interface_names != NULL && interface_names[n] != NULL; n++)
        {
          GDBusInterface *interface;
          interface = g_dbus_object_get_interface (G_DBUS_OBJECT (op), interface_names[n]);
          _g_dbus_object_proxy_remove_interface (op, interface_names[n]);
          if (interface != NULL)
            {
              g_signal_emit_by_name (manager, "interface-removed", op, interface);
              g_object_unref (interface);
            }
        }
      g_object_unref (op);
    }
  g_object_unref (manager);
 out:
  ;
}

static void
process_get_all_result (GDBusObjectManagerClient *manager,
                        GVariant          *value,
                        const gchar       *name_owner)
{
  GVariant *arg0;
  const gchar *object_path;
  GVariant *ifaces_and_properties;
  GVariantIter iter;

  g_return_if_fail (name_owner == NULL || g_dbus_is_unique_name (name_owner));

  arg0 = g_variant_get_child_value (value, 0);
  g_variant_iter_init (&iter, arg0);
  while (g_variant_iter_next (&iter,
                              "{&o@a{sa{sv}}}",
                              &object_path,
                              &ifaces_and_properties))
    {
      add_interfaces (manager, object_path, ifaces_and_properties, name_owner);
      g_variant_unref (ifaces_and_properties);
    }
  g_variant_unref (arg0);
}

static void
on_control_proxy_g_signal (GDBusProxy   *proxy,
                           const gchar  *sender_name,
                           const gchar  *signal_name,
                           GVariant     *parameters,
                           gpointer      user_data)
{
  GWeakRef *manager_weak = user_data;
  GDBusObjectManagerClient *manager = NULL;
  const gchar *object_path;

  manager = G_DBUS_OBJECT_MANAGER_CLIENT (g_weak_ref_get (manager_weak));
  if (manager == NULL)
    return;

  //g_debug ("yay, g_signal %s: %s\n", signal_name, g_variant_print (parameters, TRUE));

  if (g_strcmp0 (signal_name, "InterfacesAdded") == 0)
    {
      GVariant *ifaces_and_properties;
      g_variant_get (parameters,
                     "(&o@a{sa{sv}})",
                     &object_path,
                     &ifaces_and_properties);
      add_interfaces (manager, object_path, ifaces_and_properties, manager->priv->name_owner);
      g_variant_unref (ifaces_and_properties);
    }
  else if (g_strcmp0 (signal_name, "InterfacesRemoved") == 0)
    {
      const gchar **ifaces;
      g_variant_get (parameters,
                     "(&o^a&s)",
                     &object_path,
                     &ifaces);
      remove_interfaces (manager, object_path, ifaces);
      g_free (ifaces);
    }

  g_object_unref (manager);
}

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

static const gchar *
g_dbus_object_manager_client_get_object_path (GDBusObjectManager *_manager)
{
  GDBusObjectManagerClient *manager = G_DBUS_OBJECT_MANAGER_CLIENT (_manager);
  return manager->priv->object_path;
}

static GDBusObject *
g_dbus_object_manager_client_get_object (GDBusObjectManager *_manager,
                                         const gchar        *object_path)
{
  GDBusObjectManagerClient *manager = G_DBUS_OBJECT_MANAGER_CLIENT (_manager);
  GDBusObject *ret;

  g_mutex_lock (&manager->priv->lock);
  ret = g_hash_table_lookup (manager->priv->map_object_path_to_object_proxy, object_path);
  if (ret != NULL)
    g_object_ref (ret);
  g_mutex_unlock (&manager->priv->lock);
  return ret;
}

static GDBusInterface *
g_dbus_object_manager_client_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 GList *
g_dbus_object_manager_client_get_objects (GDBusObjectManager *_manager)
{
  GDBusObjectManagerClient *manager = G_DBUS_OBJECT_MANAGER_CLIENT (_manager);
  GList *ret;

  g_return_val_if_fail (G_IS_DBUS_OBJECT_MANAGER_CLIENT (manager), NULL);

  g_mutex_lock (&manager->priv->lock);
  ret = g_hash_table_get_values (manager->priv->map_object_path_to_object_proxy);
  g_list_foreach (ret, (GFunc) g_object_ref, NULL);
  g_mutex_unlock (&manager->priv->lock);

  return ret;
}


static void
dbus_object_manager_interface_init (GDBusObjectManagerIface *iface)
{
  iface->get_object_path = g_dbus_object_manager_client_get_object_path;
  iface->get_objects     = g_dbus_object_manager_client_get_objects;
  iface->get_object      = g_dbus_object_manager_client_get_object;
  iface->get_interface   = g_dbus_object_manager_client_get_interface;
}

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