/*
 * Copyright © 2010 Codethink Limited
 * Copyright © 2011 Canonical Limited
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation; either version 2 of the licence or (at
 * your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
 *
 * Authors: Ryan Lortie <desrt@desrt.ca>
 */

#include "config.h"

#include "gactiongroupexporter.h"

#include "gdbusmethodinvocation.h"
#include "gremoteactiongroup.h"
#include "gdbusintrospection.h"
#include "gdbusconnection.h"
#include "gactiongroup.h"
#include "gdbuserror.h"

/**
 * SECTION:gactiongroupexporter
 * @title: GActionGroup exporter
 * @include: gio/gio.h
 * @short_description: Export GActionGroups on D-Bus
 * @see_also: #GActionGroup, #GDBusActionGroup
 *
 * These functions support exporting a #GActionGroup on D-Bus.
 * The D-Bus interface that is used is a private implementation
 * detail.
 *
 * To access an exported #GActionGroup remotely, use
 * g_dbus_action_group_get() to obtain a #GDBusActionGroup.
 */

static GVariant *
g_action_group_describe_action (GActionGroup *action_group,
                                const gchar  *name)
{
  const GVariantType *type;
  GVariantBuilder builder;
  gboolean enabled;
  GVariant *state;

  g_variant_builder_init (&builder, G_VARIANT_TYPE ("(bgav)"));

  enabled = g_action_group_get_action_enabled (action_group, name);
  g_variant_builder_add (&builder, "b", enabled);

  if ((type = g_action_group_get_action_parameter_type (action_group, name)))
    {
      gchar *str = g_variant_type_dup_string (type);
      g_variant_builder_add (&builder, "g", str);
      g_free (str);
    }
  else
    g_variant_builder_add (&builder, "g", "");

  g_variant_builder_open (&builder, G_VARIANT_TYPE ("av"));
  if ((state = g_action_group_get_action_state (action_group, name)))
    {
      g_variant_builder_add (&builder, "v", state);
      g_variant_unref (state);
    }
  g_variant_builder_close (&builder);

  return g_variant_builder_end (&builder);
}

/* Using XML saves us dozens of relocations vs. using the introspection
 * structure types.  We only need to burn cycles and memory if we
 * actually use the exporter -- not in every single app using GIO.
 *
 * It's also a lot easier to read. :)
 *
 * For documentation of this interface, see
 * https://wiki.gnome.org/Projects/GLib/GApplication/DBusAPI
 */
const char org_gtk_Actions_xml[] =
  "<node>"
  "  <interface name='org.gtk.Actions'>"
  "    <method name='List'>"
  "      <arg type='as' name='list' direction='out'/>"
  "    </method>"
  "    <method name='Describe'>"
  "      <arg type='s' name='action_name' direction='in'/>"
  "      <arg type='(bgav)' name='description' direction='out'/>"
  "    </method>"
  "    <method name='DescribeAll'>"
  "      <arg type='a{s(bgav)}' name='descriptions' direction='out'/>"
  "    </method>"
  "    <method name='Activate'>"
  "      <arg type='s' name='action_name' direction='in'/>"
  "      <arg type='av' name='parameter' direction='in'/>"
  "      <arg type='a{sv}' name='platform_data' direction='in'/>"
  "    </method>"
  "    <method name='SetState'>"
  "      <arg type='s' name='action_name' direction='in'/>"
  "      <arg type='v' name='value' direction='in'/>"
  "      <arg type='a{sv}' name='platform_data' direction='in'/>"
  "    </method>"
  "    <signal name='Changed'>"
  "      <arg type='as' name='removals'/>"
  "      <arg type='a{sb}' name='enable_changes'/>"
  "      <arg type='a{sv}' name='state_changes'/>"
  "      <arg type='a{s(bgav)}' name='additions'/>"
  "    </signal>"
  "  </interface>"
  "</node>";

static GDBusInterfaceInfo *org_gtk_Actions;

typedef struct
{
  GActionGroup    *action_group;
  GDBusConnection *connection;
  GMainContext    *context;
  gchar           *object_path;
  GHashTable      *pending_changes;
  GSource         *pending_source;
} GActionGroupExporter;

#define ACTION_ADDED_EVENT             (1u<<0)
#define ACTION_REMOVED_EVENT           (1u<<1)
#define ACTION_STATE_CHANGED_EVENT     (1u<<2)
#define ACTION_ENABLED_CHANGED_EVENT   (1u<<3)

static gboolean
g_action_group_exporter_dispatch_events (gpointer user_data)
{
  GActionGroupExporter *exporter = user_data;
  GVariantBuilder removes;
  GVariantBuilder enabled_changes;
  GVariantBuilder state_changes;
  GVariantBuilder adds;
  GHashTableIter iter;
  gpointer value;
  gpointer key;

  g_variant_builder_init (&removes, G_VARIANT_TYPE_STRING_ARRAY);
  g_variant_builder_init (&enabled_changes, G_VARIANT_TYPE ("a{sb}"));
  g_variant_builder_init (&state_changes, G_VARIANT_TYPE ("a{sv}"));
  g_variant_builder_init (&adds, G_VARIANT_TYPE ("a{s(bgav)}"));

  g_hash_table_iter_init (&iter, exporter->pending_changes);
  while (g_hash_table_iter_next (&iter, &key, &value))
    {
      guint events = GPOINTER_TO_INT (value);
      const gchar *name = key;

      /* Adds and removes are incompatible with enabled or state
       * changes, but we must report at least one event.
       */
      g_assert (((events & (ACTION_ENABLED_CHANGED_EVENT | ACTION_STATE_CHANGED_EVENT)) == 0) !=
                ((events & (ACTION_REMOVED_EVENT | ACTION_ADDED_EVENT)) == 0));

      if (events & ACTION_REMOVED_EVENT)
        g_variant_builder_add (&removes, "s", name);

      if (events & ACTION_ENABLED_CHANGED_EVENT)
        {
          gboolean enabled;

          enabled = g_action_group_get_action_enabled (exporter->action_group, name);
          g_variant_builder_add (&enabled_changes, "{sb}", name, enabled);
        }

      if (events & ACTION_STATE_CHANGED_EVENT)
        {
          GVariant *state;

          state = g_action_group_get_action_state (exporter->action_group, name);
          g_variant_builder_add (&state_changes, "{sv}", name, state);
          g_variant_unref (state);
        }

      if (events & ACTION_ADDED_EVENT)
        {
          GVariant *description;

          description = g_action_group_describe_action (exporter->action_group, name);
          g_variant_builder_add (&adds, "{s@(bgav)}", name, description);
        }
    }

  g_hash_table_remove_all (exporter->pending_changes);

  g_dbus_connection_emit_signal (exporter->connection, NULL, exporter->object_path,
                                 "org.gtk.Actions", "Changed",
                                 g_variant_new ("(asa{sb}a{sv}a{s(bgav)})",
                                                &removes, &enabled_changes,
                                                &state_changes, &adds),
                                 NULL);

  exporter->pending_source = NULL;

  return FALSE;
}

static guint
g_action_group_exporter_get_events (GActionGroupExporter *exporter,
                                    const gchar          *name)
{
  return (gsize) g_hash_table_lookup (exporter->pending_changes, name);
}

static void
g_action_group_exporter_set_events (GActionGroupExporter *exporter,
                                    const gchar          *name,
                                    guint                 events)
{
  gboolean have_events;
  gboolean is_queued;

  if (events != 0)
    g_hash_table_insert (exporter->pending_changes, g_strdup (name), GINT_TO_POINTER (events));
  else
    g_hash_table_remove (exporter->pending_changes, name);

  have_events = g_hash_table_size (exporter->pending_changes) > 0;
  is_queued = exporter->pending_source != NULL;

  if (have_events && !is_queued)
    {
      GSource *source;

      source = g_idle_source_new ();
      exporter->pending_source = source;
      g_source_set_callback (source, g_action_group_exporter_dispatch_events, exporter, NULL);
      g_source_set_name (source, "[gio] g_action_group_exporter_dispatch_events");
      g_source_attach (source, exporter->context);
      g_source_unref (source);
    }

  if (!have_events && is_queued)
    {
      g_source_destroy (exporter->pending_source);
      exporter->pending_source = NULL;
    }
}

static void
g_action_group_exporter_action_added (GActionGroup *action_group,
                                      const gchar  *action_name,
                                      gpointer      user_data)
{
  GActionGroupExporter *exporter = user_data;
  guint event_mask;

  event_mask = g_action_group_exporter_get_events (exporter, action_name);

  /* The action is new, so we should not have any pending
   * enabled-changed or state-changed signals for it.
   */
  g_assert (~event_mask & (ACTION_STATE_CHANGED_EVENT |
                           ACTION_ENABLED_CHANGED_EVENT));

  event_mask |= ACTION_ADDED_EVENT;

  g_action_group_exporter_set_events (exporter, action_name, event_mask);
}

static void
g_action_group_exporter_action_removed (GActionGroup *action_group,
                                        const gchar  *action_name,
                                        gpointer      user_data)
{
  GActionGroupExporter *exporter = user_data;
  guint event_mask;

  event_mask = g_action_group_exporter_get_events (exporter, action_name);

  /* If the add event for this is still queued then just cancel it since
   * it's gone now.
   *
   * If the event was freshly added, there should not have been any
   * enabled or state changed events.
   */
  if (event_mask & ACTION_ADDED_EVENT)
    {
      g_assert (~event_mask & ~(ACTION_STATE_CHANGED_EVENT | ACTION_ENABLED_CHANGED_EVENT));
      event_mask &= ~ACTION_ADDED_EVENT;
    }

  /* Otherwise, queue a remove event.  Drop any state or enabled changes
   * that were queued before the remove. */
  else
    {
      event_mask |= ACTION_REMOVED_EVENT;
      event_mask &= ~(ACTION_STATE_CHANGED_EVENT | ACTION_ENABLED_CHANGED_EVENT);
    }

  g_action_group_exporter_set_events (exporter, action_name, event_mask);
}

static void
g_action_group_exporter_action_state_changed (GActionGroup *action_group,
                                              const gchar  *action_name,
                                              GVariant     *value,
                                              gpointer      user_data)
{
  GActionGroupExporter *exporter = user_data;
  guint event_mask;

  event_mask = g_action_group_exporter_get_events (exporter, action_name);

  /* If it was removed, it must have been added back.  Otherwise, why
   * are we hearing about changes?
   */
  g_assert (~event_mask & ACTION_REMOVED_EVENT ||
            event_mask & ACTION_ADDED_EVENT);

  /* If it is freshly added, don't also bother with the state change
   * signal since the updated state will be sent as part of the pending
   * add message.
   */
  if (~event_mask & ACTION_ADDED_EVENT)
    event_mask |= ACTION_STATE_CHANGED_EVENT;

  g_action_group_exporter_set_events (exporter, action_name, event_mask);
}

static void
g_action_group_exporter_action_enabled_changed (GActionGroup *action_group,
                                                const gchar  *action_name,
                                                gboolean      enabled,
                                                gpointer      user_data)
{
  GActionGroupExporter *exporter = user_data;
  guint event_mask;

  event_mask = g_action_group_exporter_get_events (exporter, action_name);

  /* Reasoning as above. */
  g_assert (~event_mask & ACTION_REMOVED_EVENT ||
            event_mask & ACTION_ADDED_EVENT);

  if (~event_mask & ACTION_ADDED_EVENT)
    event_mask |= ACTION_ENABLED_CHANGED_EVENT;

  g_action_group_exporter_set_events (exporter, action_name, event_mask);
}

static void
org_gtk_Actions_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)
{
  GActionGroupExporter *exporter = user_data;
  GVariant *result = NULL;

  if (g_str_equal (method_name, "List"))
    {
      gchar **list;

      list = g_action_group_list_actions (exporter->action_group);
      result = g_variant_new ("(^as)", list);
      g_strfreev (list);
    }

  else if (g_str_equal (method_name, "Describe"))
    {
      const gchar *name;
      GVariant *desc;

      g_variant_get (parameters, "(&s)", &name);

      if (!g_action_group_has_action (exporter->action_group, name))
        {
          g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
                                                 "The named action ('%s') does not exist.", name);
          return;
        }

      desc = g_action_group_describe_action (exporter->action_group, name);
      result = g_variant_new ("(@(bgav))", desc);
    }

  else if (g_str_equal (method_name, "DescribeAll"))
    {
      GVariantBuilder builder;
      gchar **list;
      gint i;

      list = g_action_group_list_actions (exporter->action_group);
      g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{s(bgav)}"));
      for (i = 0; list[i]; i++)
        {
          const gchar *name = list[i];
          GVariant *description;

          description = g_action_group_describe_action (exporter->action_group, name);
          g_variant_builder_add (&builder, "{s@(bgav)}", name, description);
        }
      result = g_variant_new ("(a{s(bgav)})", &builder);
      g_strfreev (list);
    }

  else if (g_str_equal (method_name, "Activate"))
    {
      GVariant *parameter = NULL;
      GVariant *platform_data;
      GVariantIter *iter;
      const gchar *name;

      g_variant_get (parameters, "(&sav@a{sv})", &name, &iter, &platform_data);
      g_variant_iter_next (iter, "v", &parameter);
      g_variant_iter_free (iter);

      if (G_IS_REMOTE_ACTION_GROUP (exporter->action_group))
        g_remote_action_group_activate_action_full (G_REMOTE_ACTION_GROUP (exporter->action_group),
                                                    name, parameter, platform_data);
      else
        g_action_group_activate_action (exporter->action_group, name, parameter);

      if (parameter)
        g_variant_unref (parameter);

      g_variant_unref (platform_data);
    }

  else if (g_str_equal (method_name, "SetState"))
    {
      GVariant *platform_data;
      const gchar *name;
      GVariant *state;

      g_variant_get (parameters, "(&sv@a{sv})", &name, &state, &platform_data);

      if (G_IS_REMOTE_ACTION_GROUP (exporter->action_group))
        g_remote_action_group_change_action_state_full (G_REMOTE_ACTION_GROUP (exporter->action_group),
                                                        name, state, platform_data);
      else
        g_action_group_change_action_state (exporter->action_group, name, state);

      g_variant_unref (platform_data);
      g_variant_unref (state);
    }

  else
    g_assert_not_reached ();

  g_dbus_method_invocation_return_value (invocation, result);
}

static void
g_action_group_exporter_free (gpointer user_data)
{
  GActionGroupExporter *exporter = user_data;

  g_signal_handlers_disconnect_by_func (exporter->action_group,
                                        g_action_group_exporter_action_added, exporter);
  g_signal_handlers_disconnect_by_func (exporter->action_group,
                                        g_action_group_exporter_action_enabled_changed, exporter);
  g_signal_handlers_disconnect_by_func (exporter->action_group,
                                        g_action_group_exporter_action_state_changed, exporter);
  g_signal_handlers_disconnect_by_func (exporter->action_group,
                                        g_action_group_exporter_action_removed, exporter);

  g_hash_table_unref (exporter->pending_changes);
  if (exporter->pending_source)
    g_source_destroy (exporter->pending_source);

  g_main_context_unref (exporter->context);
  g_object_unref (exporter->connection);
  g_object_unref (exporter->action_group);
  g_free (exporter->object_path);

  g_slice_free (GActionGroupExporter, exporter);
}

/**
 * g_dbus_connection_export_action_group:
 * @connection: a #GDBusConnection
 * @object_path: a D-Bus object path
 * @action_group: a #GActionGroup
 * @error: a pointer to a %NULL #GError, or %NULL
 *
 * Exports @action_group on @connection at @object_path.
 *
 * The implemented D-Bus API should be considered private.  It is
 * subject to change in the future.
 *
 * A given object path can only have one action group exported on it.
 * If this constraint is violated, the export will fail and 0 will be
 * returned (with @error set accordingly).
 *
 * You can unexport the action group using
 * g_dbus_connection_unexport_action_group() with the return value of
 * this function.
 *
 * The thread default main context is taken at the time of this call.
 * All incoming action activations and state change requests are
 * reported from this context.  Any changes on the action group that
 * cause it to emit signals must also come from this same context.
 * Since incoming action activations and state change requests are
 * rather likely to cause changes on the action group, this effectively
 * limits a given action group to being exported from only one main
 * context.
 *
 * Returns: the ID of the export (never zero), or 0 in case of failure
 *
 * Since: 2.32
 **/
guint
g_dbus_connection_export_action_group (GDBusConnection  *connection,
                                       const gchar      *object_path,
                                       GActionGroup     *action_group,
                                       GError          **error)
{
  const GDBusInterfaceVTable vtable = {
    org_gtk_Actions_method_call
  };
  GActionGroupExporter *exporter;
  guint id;

  if G_UNLIKELY (org_gtk_Actions == NULL)
    {
      GError *error = NULL;
      GDBusNodeInfo *info;

      info = g_dbus_node_info_new_for_xml (org_gtk_Actions_xml, &error);
      if G_UNLIKELY (info == NULL)
        g_error ("%s", error->message);
      org_gtk_Actions = g_dbus_node_info_lookup_interface (info, "org.gtk.Actions");
      g_assert (org_gtk_Actions != NULL);
      g_dbus_interface_info_ref (org_gtk_Actions);
      g_dbus_node_info_unref (info);
    }

  exporter = g_slice_new (GActionGroupExporter);
  id = g_dbus_connection_register_object (connection, object_path, org_gtk_Actions, &vtable,
                                          exporter, g_action_group_exporter_free, error);

  if (id == 0)
    {
      g_slice_free (GActionGroupExporter, exporter);
      return 0;
    }

  exporter->context = g_main_context_ref_thread_default ();
  exporter->pending_changes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
  exporter->pending_source = NULL;
  exporter->action_group = g_object_ref (action_group);
  exporter->connection = g_object_ref (connection);
  exporter->object_path = g_strdup (object_path);

  g_signal_connect (action_group, "action-added",
                    G_CALLBACK (g_action_group_exporter_action_added), exporter);
  g_signal_connect (action_group, "action-removed",
                    G_CALLBACK (g_action_group_exporter_action_removed), exporter);
  g_signal_connect (action_group, "action-state-changed",
                    G_CALLBACK (g_action_group_exporter_action_state_changed), exporter);
  g_signal_connect (action_group, "action-enabled-changed",
                    G_CALLBACK (g_action_group_exporter_action_enabled_changed), exporter);

  return id;
}

/**
 * g_dbus_connection_unexport_action_group:
 * @connection: a #GDBusConnection
 * @export_id: the ID from g_dbus_connection_export_action_group()
 *
 * Reverses the effect of a previous call to
 * g_dbus_connection_export_action_group().
 *
 * It is an error to call this function with an ID that wasn't returned
 * from g_dbus_connection_export_action_group() or to call it with the
 * same ID more than once.
 *
 * Since: 2.32
 **/
void
g_dbus_connection_unexport_action_group (GDBusConnection *connection,
                                         guint            export_id)
{
  g_dbus_connection_unregister_object (connection, export_id);
}
