/* 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 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, write to the
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 * Author: David Zeuthen <davidz@redhat.com>
 */

#include "config.h"

#include "gdbusobject.h"
#include "gdbusobjectproxy.h"
#include "gdbusconnection.h"
#include "gdbusprivate.h"
#include "gdbusutils.h"
#include "gdbusproxy.h"

#include "glibintl.h"

/**
 * SECTION:gdbusobjectproxy
 * @short_description: Client-side D-Bus object
 * @include: gio/gio.h
 *
 * A #GDBusObjectProxy is an object used to represent a remote object
 * with one or more D-Bus interfaces. Normally, you don't instantiate
 * a #GDBusObjectProxy yourself - typically #GDBusObjectManagerClient
 * is used to obtain it.
 *
 * Since: 2.30
 */

struct _GDBusObjectProxyPrivate
{
  GMutex lock;
  GHashTable *map_name_to_iface;
  gchar *object_path;
  GDBusConnection *connection;
};

enum
{
  PROP_0,
  PROP_G_OBJECT_PATH,
  PROP_G_CONNECTION
};

static void dbus_object_interface_init (GDBusObjectIface *iface);

G_DEFINE_TYPE_WITH_CODE (GDBusObjectProxy, g_dbus_object_proxy, G_TYPE_OBJECT,
                         G_IMPLEMENT_INTERFACE (G_TYPE_DBUS_OBJECT, dbus_object_interface_init));

static void
g_dbus_object_proxy_finalize (GObject *object)
{
  GDBusObjectProxy *proxy = G_DBUS_OBJECT_PROXY (object);

  g_hash_table_unref (proxy->priv->map_name_to_iface);

  g_clear_object (&proxy->priv->connection);

  g_free (proxy->priv->object_path);

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

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

static void
g_dbus_object_proxy_get_property (GObject    *object,
                                  guint       prop_id,
                                  GValue     *value,
                                  GParamSpec *pspec)
{
  GDBusObjectProxy *proxy = G_DBUS_OBJECT_PROXY (object);

  switch (prop_id)
    {
    case PROP_G_OBJECT_PATH:
      g_mutex_lock (&proxy->priv->lock);
      g_value_set_string (value, proxy->priv->object_path);
      g_mutex_unlock (&proxy->priv->lock);
      break;

    case PROP_G_CONNECTION:
      g_value_set_object (value, g_dbus_object_proxy_get_connection (proxy));
      break;

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

static void
g_dbus_object_proxy_set_property (GObject       *object,
                                  guint          prop_id,
                                  const GValue  *value,
                                  GParamSpec    *pspec)
{
  GDBusObjectProxy *proxy = G_DBUS_OBJECT_PROXY (object);

  switch (prop_id)
    {
    case PROP_G_OBJECT_PATH:
      g_mutex_lock (&proxy->priv->lock);
      proxy->priv->object_path = g_value_dup_string (value);
      g_mutex_unlock (&proxy->priv->lock);
      break;

    case PROP_G_CONNECTION:
      g_mutex_lock (&proxy->priv->lock);
      proxy->priv->connection = g_value_dup_object (value);
      g_mutex_unlock (&proxy->priv->lock);
      break;

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

static void
g_dbus_object_proxy_class_init (GDBusObjectProxyClass *klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);

  gobject_class->finalize     = g_dbus_object_proxy_finalize;
  gobject_class->set_property = g_dbus_object_proxy_set_property;
  gobject_class->get_property = g_dbus_object_proxy_get_property;

  /**
   * GDBusObjectProxy:g-object-path:
   *
   * The object path of the proxy.
   *
   * Since: 2.30
   */
  g_object_class_install_property (gobject_class,
                                   PROP_G_OBJECT_PATH,
                                   g_param_spec_string ("g-object-path",
                                                        "Object Path",
                                                        "The object path of the proxy",
                                                        NULL,
                                                        G_PARAM_READWRITE |
                                                        G_PARAM_CONSTRUCT_ONLY |
                                                        G_PARAM_STATIC_STRINGS));

  /**
   * GDBusObjectProxy:g-connection:
   *
   * The connection of the proxy.
   *
   * Since: 2.30
   */
  g_object_class_install_property (gobject_class,
                                   PROP_G_CONNECTION,
                                   g_param_spec_object ("g-connection",
                                                        "Connection",
                                                        "The connection of the proxy",
                                                        G_TYPE_DBUS_CONNECTION,
                                                        G_PARAM_READWRITE |
                                                        G_PARAM_CONSTRUCT_ONLY |
                                                        G_PARAM_STATIC_STRINGS));

  g_type_class_add_private (klass, sizeof (GDBusObjectProxyPrivate));
}

static void
g_dbus_object_proxy_init (GDBusObjectProxy *proxy)
{
  proxy->priv = G_TYPE_INSTANCE_GET_PRIVATE (proxy,
                                             G_TYPE_DBUS_OBJECT_PROXY,
                                             GDBusObjectProxyPrivate);
  g_mutex_init (&proxy->priv->lock);
  proxy->priv->map_name_to_iface = g_hash_table_new_full (g_str_hash,
                                                          g_str_equal,
                                                          g_free,
                                                          (GDestroyNotify) g_object_unref);
}

static const gchar *
g_dbus_object_proxy_get_object_path (GDBusObject *object)
{
  GDBusObjectProxy *proxy = G_DBUS_OBJECT_PROXY (object);
  const gchar *ret;
  g_mutex_lock (&proxy->priv->lock);
  ret = proxy->priv->object_path;
  g_mutex_unlock (&proxy->priv->lock);
  return ret;
}

/**
 * g_dbus_object_proxy_get_connection:
 * @proxy: a #GDBusObjectProxy
 *
 * Gets the connection that @proxy is for.
 *
 * Returns: (transfer none): A #GDBusConnection. Do not free, the
 *   object is owned by @proxy.
 *
 * Since: 2.30
 */
GDBusConnection *
g_dbus_object_proxy_get_connection (GDBusObjectProxy *proxy)
{
  GDBusConnection *ret;
  g_return_val_if_fail (G_IS_DBUS_OBJECT_PROXY (proxy), NULL);
  g_mutex_lock (&proxy->priv->lock);
  ret = proxy->priv->connection;
  g_mutex_unlock (&proxy->priv->lock);
  return ret;
}

static GDBusInterface *
g_dbus_object_proxy_get_interface (GDBusObject *object,
                                   const gchar *interface_name)
{
  GDBusObjectProxy *proxy = G_DBUS_OBJECT_PROXY (object);
  GDBusProxy *ret;

  g_return_val_if_fail (G_IS_DBUS_OBJECT_PROXY (proxy), NULL);
  g_return_val_if_fail (g_dbus_is_interface_name (interface_name), NULL);

  g_mutex_lock (&proxy->priv->lock);
  ret = g_hash_table_lookup (proxy->priv->map_name_to_iface, interface_name);
  if (ret != NULL)
    g_object_ref (ret);
  g_mutex_unlock (&proxy->priv->lock);

  return (GDBusInterface *) ret; /* TODO: proper cast */
}

static GList *
g_dbus_object_proxy_get_interfaces (GDBusObject *object)
{
  GDBusObjectProxy *proxy = G_DBUS_OBJECT_PROXY (object);
  GList *ret;

  g_return_val_if_fail (G_IS_DBUS_OBJECT_PROXY (proxy), NULL);

  ret = NULL;

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

  return ret;
}

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

/**
 * g_dbus_object_proxy_new:
 * @connection: a #GDBusConnection
 * @object_path: the object path
 *
 * Creates a new #GDBusObjectProxy for the given connection and
 * object path.
 *
 * Returns: a new #GDBusObjectProxy
 *
 * Since: 2.30
 */
GDBusObjectProxy *
g_dbus_object_proxy_new (GDBusConnection *connection,
                         const gchar     *object_path)
{
  g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
  g_return_val_if_fail (g_variant_is_object_path (object_path), NULL);
  return G_DBUS_OBJECT_PROXY (g_object_new (G_TYPE_DBUS_OBJECT_PROXY,
                                            "g-object-path", object_path,
                                            "g-connection", connection,
                                            NULL));
}

void
_g_dbus_object_proxy_add_interface (GDBusObjectProxy *proxy,
                                    GDBusProxy       *interface_proxy)
{
  const gchar *interface_name;
  GDBusProxy *interface_proxy_to_remove;

  g_return_if_fail (G_IS_DBUS_OBJECT_PROXY (proxy));
  g_return_if_fail (G_IS_DBUS_PROXY (interface_proxy));

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

  interface_name = g_dbus_proxy_get_interface_name (interface_proxy);
  interface_proxy_to_remove = g_hash_table_lookup (proxy->priv->map_name_to_iface, interface_name);
  if (interface_proxy_to_remove != NULL)
    {
      g_object_ref (interface_proxy_to_remove);
      g_warn_if_fail (g_hash_table_remove (proxy->priv->map_name_to_iface, interface_name));
    }
  g_hash_table_insert (proxy->priv->map_name_to_iface,
                       g_strdup (interface_name),
                       g_object_ref (interface_proxy));
  g_object_ref (interface_proxy);

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

  if (interface_proxy_to_remove != NULL)
    {
      g_signal_emit_by_name (proxy, "interface-removed", interface_proxy_to_remove);
      g_object_unref (interface_proxy_to_remove);
    }

  g_signal_emit_by_name (proxy, "interface-added", interface_proxy);
  g_object_unref (interface_proxy);
}

void
_g_dbus_object_proxy_remove_interface (GDBusObjectProxy *proxy,
                                       const gchar      *interface_name)
{
  GDBusProxy *interface_proxy;

  g_return_if_fail (G_IS_DBUS_OBJECT_PROXY (proxy));
  g_return_if_fail (g_dbus_is_interface_name (interface_name));

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

  interface_proxy = g_hash_table_lookup (proxy->priv->map_name_to_iface, interface_name);
  if (interface_proxy != NULL)
    {
      g_object_ref (interface_proxy);
      g_warn_if_fail (g_hash_table_remove (proxy->priv->map_name_to_iface, interface_name));
      g_mutex_unlock (&proxy->priv->lock);
      g_signal_emit_by_name (proxy, "interface-removed", interface_proxy);
      g_object_unref (interface_proxy);
    }
  else
    {
      g_mutex_unlock (&proxy->priv->lock);
    }
}

static void
dbus_object_interface_init (GDBusObjectIface *iface)
{
  iface->get_object_path       = g_dbus_object_proxy_get_object_path;
  iface->get_interfaces        = g_dbus_object_proxy_get_interfaces;
  iface->get_interface         = g_dbus_object_proxy_get_interface;
}
