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

#include "config.h"

#include "gmenuexporter.h"

#include "gdbusmethodinvocation.h"
#include "gdbusintrospection.h"
#include "gdbusnamewatching.h"
#include "gdbuserror.h"

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

/* {{{1 D-Bus Interface description */

/* For documentation of this interface, see
 * https://wiki.gnome.org/Projects/GLib/GApplication/DBusAPI
 */

static GDBusInterfaceInfo *
org_gtk_Menus_get_interface (void)
{
  static GDBusInterfaceInfo *interface_info;

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

      info = g_dbus_node_info_new_for_xml ("<node>"
                                           "  <interface name='org.gtk.Menus'>"
                                           "    <method name='Start'>"
                                           "      <arg type='au' name='groups' direction='in'/>"
                                           "      <arg type='a(uuaa{sv})' name='content' direction='out'/>"
                                           "    </method>"
                                           "    <method name='End'>"
                                           "      <arg type='au' name='groups' direction='in'/>"
                                           "    </method>"
                                           "    <signal name='Changed'>"
                                           "      arg type='a(uuuuaa{sv})' name='changes'/>"
                                           "    </signal>"
                                           "  </interface>"
                                           "</node>", &error);
      if (info == NULL)
        g_error ("%s\n", error->message);
      interface_info = g_dbus_node_info_lookup_interface (info, "org.gtk.Menus");
      g_assert (interface_info != NULL);
      g_dbus_interface_info_ref (interface_info);
      g_dbus_node_info_unref (info);
    }

  return interface_info;
}

/* {{{1 Forward declarations */
typedef struct _GMenuExporterMenu                           GMenuExporterMenu;
typedef struct _GMenuExporterLink                           GMenuExporterLink;
typedef struct _GMenuExporterGroup                          GMenuExporterGroup;
typedef struct _GMenuExporterRemote                         GMenuExporterRemote;
typedef struct _GMenuExporterWatch                          GMenuExporterWatch;
typedef struct _GMenuExporter                               GMenuExporter;

static gboolean                 g_menu_exporter_group_is_subscribed    (GMenuExporterGroup *group);
static guint                    g_menu_exporter_group_get_id           (GMenuExporterGroup *group);
static GMenuExporter *          g_menu_exporter_group_get_exporter     (GMenuExporterGroup *group);
static GMenuExporterMenu *      g_menu_exporter_group_add_menu         (GMenuExporterGroup *group,
                                                                        GMenuModel         *model);
static void                     g_menu_exporter_group_remove_menu      (GMenuExporterGroup *group,
                                                                        guint               id);

static GMenuExporterGroup *     g_menu_exporter_create_group           (GMenuExporter      *exporter);
static GMenuExporterGroup *     g_menu_exporter_lookup_group           (GMenuExporter      *exporter,
                                                                        guint               group_id);
static void                     g_menu_exporter_report                 (GMenuExporter      *exporter,
                                                                        GVariant           *report);
static void                     g_menu_exporter_remove_group           (GMenuExporter      *exporter,
                                                                        guint               id);

/* {{{1 GMenuExporterLink, GMenuExporterMenu */

struct _GMenuExporterMenu
{
  GMenuExporterGroup *group;
  guint               id;

  GMenuModel *model;
  gulong      handler_id;
  GSequence  *item_links;
};

struct _GMenuExporterLink
{
  gchar             *name;
  GMenuExporterMenu *menu;
  GMenuExporterLink *next;
};

static void
g_menu_exporter_menu_free (GMenuExporterMenu *menu)
{
  g_menu_exporter_group_remove_menu (menu->group, menu->id);

  if (menu->handler_id != 0)
    g_signal_handler_disconnect (menu->model, menu->handler_id);

  if (menu->item_links != NULL)
    g_sequence_free (menu->item_links);

  g_object_unref (menu->model);

  g_slice_free (GMenuExporterMenu, menu);
}

static void
g_menu_exporter_link_free (gpointer data)
{
  GMenuExporterLink *link = data;

  while (link != NULL)
    {
      GMenuExporterLink *tmp = link;
      link = tmp->next;

      g_menu_exporter_menu_free (tmp->menu);
      g_free (tmp->name);

      g_slice_free (GMenuExporterLink, tmp);
    }
}

static GMenuExporterLink *
g_menu_exporter_menu_create_links (GMenuExporterMenu *menu,
                                   gint               position)
{
  GMenuExporterLink *list = NULL;
  GMenuLinkIter *iter;
  const char *name;
  GMenuModel *model;

  iter = g_menu_model_iterate_item_links (menu->model, position);

  while (g_menu_link_iter_get_next (iter, &name, &model))
    {
      GMenuExporterGroup *group;
      GMenuExporterLink *tmp;

      /* keep sections in the same group, but create new groups
       * otherwise
       */
      if (!g_str_equal (name, "section"))
        group = g_menu_exporter_create_group (g_menu_exporter_group_get_exporter (menu->group));
      else
        group = menu->group;

      tmp = g_slice_new (GMenuExporterLink);
      tmp->name = g_strconcat (":", name, NULL);
      tmp->menu = g_menu_exporter_group_add_menu (group, model);
      tmp->next = list;
      list = tmp;

      g_object_unref (model);
    }

  g_object_unref (iter);

  return list;
}

static GVariant *
g_menu_exporter_menu_describe_item (GMenuExporterMenu *menu,
                                    gint               position)
{
  GMenuAttributeIter *attr_iter;
  GVariantBuilder builder;
  GSequenceIter *iter;
  GMenuExporterLink *link;
  const char *name;
  GVariant *value;

  g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);

  attr_iter = g_menu_model_iterate_item_attributes (menu->model, position);
  while (g_menu_attribute_iter_get_next (attr_iter, &name, &value))
    {
      g_variant_builder_add (&builder, "{sv}", name, value);
      g_variant_unref (value);
    }
  g_object_unref (attr_iter);

  iter = g_sequence_get_iter_at_pos (menu->item_links, position);
  for (link = g_sequence_get (iter); link; link = link->next)
    g_variant_builder_add (&builder, "{sv}", link->name,
                           g_variant_new ("(uu)", g_menu_exporter_group_get_id (link->menu->group), link->menu->id));

  return g_variant_builder_end (&builder);
}

static GVariant *
g_menu_exporter_menu_list (GMenuExporterMenu *menu)
{
  GVariantBuilder builder;
  gint i, n;

  g_variant_builder_init (&builder, G_VARIANT_TYPE ("aa{sv}"));

  n = g_sequence_get_length (menu->item_links);
  for (i = 0; i < n; i++)
    g_variant_builder_add_value (&builder, g_menu_exporter_menu_describe_item (menu, i));

  return g_variant_builder_end (&builder);
}

static void
g_menu_exporter_menu_items_changed (GMenuModel *model,
                                    gint        position,
                                    gint        removed,
                                    gint        added,
                                    gpointer    user_data)
{
  GMenuExporterMenu *menu = user_data;
  GSequenceIter *point;
  gint i;

  g_assert (menu->model == model);
  g_assert (menu->item_links != NULL);
  g_assert (position + removed <= g_sequence_get_length (menu->item_links));

  point = g_sequence_get_iter_at_pos (menu->item_links, position + removed);
  g_sequence_remove_range (g_sequence_get_iter_at_pos (menu->item_links, position), point);

  for (i = position; i < position + added; i++)
    g_sequence_insert_before (point, g_menu_exporter_menu_create_links (menu, i));

  if (g_menu_exporter_group_is_subscribed (menu->group))
    {
      GVariantBuilder builder;

      g_variant_builder_init (&builder, G_VARIANT_TYPE ("(uuuuaa{sv})"));
      g_variant_builder_add (&builder, "u", g_menu_exporter_group_get_id (menu->group));
      g_variant_builder_add (&builder, "u", menu->id);
      g_variant_builder_add (&builder, "u", position);
      g_variant_builder_add (&builder, "u", removed);

      g_variant_builder_open (&builder, G_VARIANT_TYPE ("aa{sv}"));
      for (i = position; i < position + added; i++)
        g_variant_builder_add_value (&builder, g_menu_exporter_menu_describe_item (menu, i));
      g_variant_builder_close (&builder);

      g_menu_exporter_report (g_menu_exporter_group_get_exporter (menu->group), g_variant_builder_end (&builder));
    }
}

static void
g_menu_exporter_menu_prepare (GMenuExporterMenu *menu)
{
  gint n_items;

  g_assert (menu->item_links == NULL);

  if (g_menu_model_is_mutable (menu->model))
    menu->handler_id = g_signal_connect (menu->model, "items-changed",
                                         G_CALLBACK (g_menu_exporter_menu_items_changed), menu);

  menu->item_links = g_sequence_new (g_menu_exporter_link_free);

  n_items = g_menu_model_get_n_items (menu->model);
  if (n_items)
    g_menu_exporter_menu_items_changed (menu->model, 0, 0, n_items, menu);
}

static GMenuExporterMenu *
g_menu_exporter_menu_new (GMenuExporterGroup *group,
                          guint               id,
                          GMenuModel         *model)
{
  GMenuExporterMenu *menu;

  menu = g_slice_new0 (GMenuExporterMenu);
  menu->group = group;
  menu->id = id;
  menu->model = g_object_ref (model);

  return menu;
}

/* {{{1 GMenuExporterGroup */

struct _GMenuExporterGroup
{
  GMenuExporter *exporter;
  guint          id;

  GHashTable *menus;
  guint       next_menu_id;
  gboolean    prepared;

  gint subscribed;
};

static void
g_menu_exporter_group_check_if_useless (GMenuExporterGroup *group)
{
  if (g_hash_table_size (group->menus) == 0 && group->subscribed == 0)
    {
      g_menu_exporter_remove_group (group->exporter, group->id);

      g_hash_table_unref (group->menus);

      g_slice_free (GMenuExporterGroup, group);
    }
}

static void
g_menu_exporter_group_subscribe (GMenuExporterGroup *group,
                                 GVariantBuilder    *builder)
{
  GHashTableIter iter;
  gpointer key, val;

  if (!group->prepared)
    {
      GMenuExporterMenu *menu;

      /* set this first, so that any menus created during the
       * preparation of the first menu also end up in the prepared
       * state.
       * */
      group->prepared = TRUE;

      menu = g_hash_table_lookup (group->menus, 0);

      /* If the group was created by a subscription and does not yet
       * exist, it won't have a root menu...
       *
       * That menu will be prepared if it is ever added (due to
       * group->prepared == TRUE).
       */
      if (menu)
        g_menu_exporter_menu_prepare (menu);
    }

  group->subscribed++;

  g_hash_table_iter_init (&iter, group->menus);
  while (g_hash_table_iter_next (&iter, &key, &val))
    {
      guint id = GPOINTER_TO_INT (key);
      GMenuExporterMenu *menu = val;

      if (g_sequence_get_length (menu->item_links))
        {
          g_variant_builder_open (builder, G_VARIANT_TYPE ("(uuaa{sv})"));
          g_variant_builder_add (builder, "u", group->id);
          g_variant_builder_add (builder, "u", id);
          g_variant_builder_add_value (builder, g_menu_exporter_menu_list (menu));
          g_variant_builder_close (builder);
        }
    }
}

static void
g_menu_exporter_group_unsubscribe (GMenuExporterGroup *group,
                                   gint                count)
{
  g_assert (group->subscribed >= count);

  group->subscribed -= count;

  g_menu_exporter_group_check_if_useless (group);
}

static GMenuExporter *
g_menu_exporter_group_get_exporter (GMenuExporterGroup *group)
{
  return group->exporter;
}

static gboolean
g_menu_exporter_group_is_subscribed (GMenuExporterGroup *group)
{
  return group->subscribed > 0;
}

static guint
g_menu_exporter_group_get_id (GMenuExporterGroup *group)
{
  return group->id;
}

static void
g_menu_exporter_group_remove_menu (GMenuExporterGroup *group,
                                   guint               id)
{
  g_hash_table_remove (group->menus, GINT_TO_POINTER (id));

  g_menu_exporter_group_check_if_useless (group);
}

static GMenuExporterMenu *
g_menu_exporter_group_add_menu (GMenuExporterGroup *group,
                                GMenuModel         *model)
{
  GMenuExporterMenu *menu;
  guint id;

  id = group->next_menu_id++;
  menu = g_menu_exporter_menu_new (group, id, model);
  g_hash_table_insert (group->menus, GINT_TO_POINTER (id), menu);

  if (group->prepared)
    g_menu_exporter_menu_prepare (menu);

  return menu;
}

static GMenuExporterGroup *
g_menu_exporter_group_new (GMenuExporter *exporter,
                           guint          id)
{
  GMenuExporterGroup *group;

  group = g_slice_new0 (GMenuExporterGroup);
  group->menus = g_hash_table_new (NULL, NULL);
  group->exporter = exporter;
  group->id = id;

  return group;
}

/* {{{1 GMenuExporterRemote */

struct _GMenuExporterRemote
{
  GMenuExporter *exporter;
  GHashTable    *watches;
  guint          watch_id;
};

static void
g_menu_exporter_remote_subscribe (GMenuExporterRemote *remote,
                                  guint                group_id,
                                  GVariantBuilder     *builder)
{
  GMenuExporterGroup *group;
  guint count;

  count = (gsize) g_hash_table_lookup (remote->watches, GINT_TO_POINTER (group_id));
  g_hash_table_insert (remote->watches, GINT_TO_POINTER (group_id), GINT_TO_POINTER (count + 1));

  /* Group will be created (as empty/unsubscribed if it does not exist) */
  group = g_menu_exporter_lookup_group (remote->exporter, group_id);
  g_menu_exporter_group_subscribe (group, builder);
}

static void
g_menu_exporter_remote_unsubscribe (GMenuExporterRemote *remote,
                                    guint                group_id)
{
  GMenuExporterGroup *group;
  guint count;

  count = (gsize) g_hash_table_lookup (remote->watches, GINT_TO_POINTER (group_id));

  if (count == 0)
    return;

  if (count != 1)
    g_hash_table_insert (remote->watches, GINT_TO_POINTER (group_id), GINT_TO_POINTER (count - 1));
  else
    g_hash_table_remove (remote->watches, GINT_TO_POINTER (group_id));

  group = g_menu_exporter_lookup_group (remote->exporter, group_id);
  g_menu_exporter_group_unsubscribe (group, 1);
}

static gboolean
g_menu_exporter_remote_has_subscriptions (GMenuExporterRemote *remote)
{
  return g_hash_table_size (remote->watches) != 0;
}

static void
g_menu_exporter_remote_free (gpointer data)
{
  GMenuExporterRemote *remote = data;
  GHashTableIter iter;
  gpointer key, val;

  g_hash_table_iter_init (&iter, remote->watches);
  while (g_hash_table_iter_next (&iter, &key, &val))
    {
      GMenuExporterGroup *group;

      group = g_menu_exporter_lookup_group (remote->exporter, GPOINTER_TO_INT (key));
      g_menu_exporter_group_unsubscribe (group, GPOINTER_TO_INT (val));
    }

  g_bus_unwatch_name (remote->watch_id);
  g_hash_table_unref (remote->watches);

  g_slice_free (GMenuExporterRemote, remote);
}

static GMenuExporterRemote *
g_menu_exporter_remote_new (GMenuExporter *exporter,
                            guint          watch_id)
{
  GMenuExporterRemote *remote;

  remote = g_slice_new0 (GMenuExporterRemote);
  remote->exporter = exporter;
  remote->watches = g_hash_table_new (NULL, NULL);
  remote->watch_id = watch_id;

  return remote;
}

/* {{{1 GMenuExporter */

struct _GMenuExporter
{
  GDBusConnection *connection;
  gchar *object_path;
  guint registration_id;
  GHashTable *groups;
  guint next_group_id;

  GMenuExporterMenu *root;
  GHashTable *remotes;
};

static void
g_menu_exporter_name_vanished (GDBusConnection *connection,
                               const gchar     *name,
                               gpointer         user_data)
{
  GMenuExporter *exporter = user_data;

  /* connection == NULL when we get called because the connection closed */
  g_assert (exporter->connection == connection || connection == NULL);

  g_hash_table_remove (exporter->remotes, name);
}

static GVariant *
g_menu_exporter_subscribe (GMenuExporter *exporter,
                           const gchar   *sender,
                           GVariant      *group_ids)
{
  GMenuExporterRemote *remote;
  GVariantBuilder builder;
  GVariantIter iter;
  guint32 id;

  remote = g_hash_table_lookup (exporter->remotes, sender);

  if (remote == NULL)
    {
      guint watch_id;

      watch_id = g_bus_watch_name_on_connection (exporter->connection, sender, G_BUS_NAME_WATCHER_FLAGS_NONE,
                                                 NULL, g_menu_exporter_name_vanished, exporter, NULL);
      remote = g_menu_exporter_remote_new (exporter, watch_id);
      g_hash_table_insert (exporter->remotes, g_strdup (sender), remote);
    }

  g_variant_builder_init (&builder, G_VARIANT_TYPE ("(a(uuaa{sv}))"));

  g_variant_builder_open (&builder, G_VARIANT_TYPE ("a(uuaa{sv})"));

  g_variant_iter_init (&iter, group_ids);
  while (g_variant_iter_next (&iter, "u", &id))
    g_menu_exporter_remote_subscribe (remote, id, &builder);

  g_variant_builder_close (&builder);

  return g_variant_builder_end (&builder);
}

static void
g_menu_exporter_unsubscribe (GMenuExporter *exporter,
                             const gchar   *sender,
                             GVariant      *group_ids)
{
  GMenuExporterRemote *remote;
  GVariantIter iter;
  guint32 id;

  remote = g_hash_table_lookup (exporter->remotes, sender);

  if (remote == NULL)
    return;

  g_variant_iter_init (&iter, group_ids);
  while (g_variant_iter_next (&iter, "u", &id))
    g_menu_exporter_remote_unsubscribe (remote, id);

  if (!g_menu_exporter_remote_has_subscriptions (remote))
    g_hash_table_remove (exporter->remotes, sender);
}

static void
g_menu_exporter_report (GMenuExporter *exporter,
                        GVariant      *report)
{
  GVariantBuilder builder;

  g_variant_builder_init (&builder, G_VARIANT_TYPE_TUPLE);
  g_variant_builder_open (&builder, G_VARIANT_TYPE_ARRAY);
  g_variant_builder_add_value (&builder, report);
  g_variant_builder_close (&builder);

  g_dbus_connection_emit_signal (exporter->connection,
                                 NULL,
                                 exporter->object_path,
                                 "org.gtk.Menus", "Changed",
                                 g_variant_builder_end (&builder),
                                 NULL);
}

static void
g_menu_exporter_remove_group (GMenuExporter *exporter,
                              guint          id)
{
  g_hash_table_remove (exporter->groups, GINT_TO_POINTER (id));
}

static GMenuExporterGroup *
g_menu_exporter_lookup_group (GMenuExporter *exporter,
                              guint          group_id)
{
  GMenuExporterGroup *group;

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

  if (group == NULL)
    {
      group = g_menu_exporter_group_new (exporter, group_id);
      g_hash_table_insert (exporter->groups, GINT_TO_POINTER (group_id), group);
    }

  return group;
}

static GMenuExporterGroup *
g_menu_exporter_create_group (GMenuExporter *exporter)
{
  GMenuExporterGroup *group;
  guint id;

  id = exporter->next_group_id++;
  group = g_menu_exporter_group_new (exporter, id);
  g_hash_table_insert (exporter->groups, GINT_TO_POINTER (id), group);

  return group;
}

static void
g_menu_exporter_free (gpointer user_data)
{
  GMenuExporter *exporter = user_data;

  g_menu_exporter_menu_free (exporter->root);
  g_hash_table_unref (exporter->remotes);
  g_hash_table_unref (exporter->groups);
  g_object_unref (exporter->connection);
  g_free (exporter->object_path);

  g_slice_free (GMenuExporter, exporter);
}

static void
g_menu_exporter_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)
{
  GMenuExporter *exporter = user_data;
  GVariant *group_ids;

  group_ids = g_variant_get_child_value (parameters, 0);

  if (g_str_equal (method_name, "Start"))
    g_dbus_method_invocation_return_value (invocation, g_menu_exporter_subscribe (exporter, sender, group_ids));

  else if (g_str_equal (method_name, "End"))
    {
      g_menu_exporter_unsubscribe (exporter, sender, group_ids);
      g_dbus_method_invocation_return_value (invocation, NULL);
    }

  else
    g_assert_not_reached ();

  g_variant_unref (group_ids);
}

/* {{{1 Public API */

/**
 * g_dbus_connection_export_menu_model:
 * @connection: a #GDBusConnection
 * @object_path: a D-Bus object path
 * @menu: a #GMenuModel
 * @error: return location for an error, or %NULL
 *
 * Exports @menu on @connection at @object_path.
 *
 * The implemented D-Bus API should be considered private.
 * It is subject to change in the future.
 *
 * An object path can only have one menu model 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 menu model using
 * g_dbus_connection_unexport_menu_model() with the return value of
 * this function.
 *
 * Returns: the ID of the export (never zero), or 0 in case of failure
 *
 * Since: 2.32
 */
guint
g_dbus_connection_export_menu_model (GDBusConnection  *connection,
                                     const gchar      *object_path,
                                     GMenuModel       *menu,
                                     GError          **error)
{
  const GDBusInterfaceVTable vtable = {
    g_menu_exporter_method_call,
  };
  GMenuExporter *exporter;
  guint id;

  exporter = g_slice_new0 (GMenuExporter);

  id = g_dbus_connection_register_object (connection, object_path, org_gtk_Menus_get_interface (),
                                          &vtable, exporter, g_menu_exporter_free, error);

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

  exporter->connection = g_object_ref (connection);
  exporter->object_path = g_strdup (object_path);
  exporter->groups = g_hash_table_new (NULL, NULL);
  exporter->remotes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_menu_exporter_remote_free);
  exporter->root = g_menu_exporter_group_add_menu (g_menu_exporter_create_group (exporter), menu);

  return id;
}

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

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