#include <gio/gio.h>
#include <stdlib.h>
#include <string.h>

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

static GDBusNodeInfo *introspection_data = NULL;
static GDBusInterfaceInfo *manager_interface_info = NULL;
static GDBusInterfaceInfo *block_interface_info = NULL;
static GDBusInterfaceInfo *partition_interface_info = NULL;

/* Introspection data for the service we are exporting */
static const gchar introspection_xml[] =
  "<node>"
  "  <interface name='org.gtk.GDBus.Example.Manager'>"
  "    <method name='Hello'>"
  "      <arg type='s' name='greeting' direction='in'/>"
  "      <arg type='s' name='response' direction='out'/>"
  "    </method>"
  "  </interface>"
  "  <interface name='org.gtk.GDBus.Example.Block'>"
  "    <method name='Hello'>"
  "      <arg type='s' name='greeting' direction='in'/>"
  "      <arg type='s' name='response' direction='out'/>"
  "    </method>"
  "    <property type='i' name='Major' access='read'/>"
  "    <property type='i' name='Minor' access='read'/>"
  "    <property type='s' name='Notes' access='readwrite'/>"
  "  </interface>"
  "  <interface name='org.gtk.GDBus.Example.Partition'>"
  "    <method name='Hello'>"
  "      <arg type='s' name='greeting' direction='in'/>"
  "      <arg type='s' name='response' direction='out'/>"
  "    </method>"
  "    <property type='i' name='PartitionNumber' access='read'/>"
  "    <property type='s' name='Notes' access='readwrite'/>"
  "  </interface>"
  "</node>";

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

static void
manager_method_call (GDBusConnection       *connection,
                     const gchar           *sender,
                     const gchar           *object_path,
                     const gchar           *interface_name,
                     const gchar           *method_name,
                     GVariant              *parameters,
                     GDBusMethodInvocation *invocation,
                     gpointer               user_data)
{
  const gchar *greeting;
  gchar *response;

  g_assert_cmpstr (interface_name, ==, "org.gtk.GDBus.Example.Manager");
  g_assert_cmpstr (method_name, ==, "Hello");

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

  response = g_strdup_printf ("Method %s.%s with user_data '%s' on object path %s called with arg '%s'",
                              interface_name,
                              method_name,
                              (const gchar *) user_data,
                              object_path,
                              greeting);
  g_dbus_method_invocation_return_value (invocation,
                                         g_variant_new ("(s)", response));
  g_free (response);
}

const GDBusInterfaceVTable manager_vtable =
{
  manager_method_call,
  NULL,                 /* get_property */
  NULL,                 /* set_property */
  { 0 }
};

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

static void
block_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)
{
  g_assert_cmpstr (interface_name, ==, "org.gtk.GDBus.Example.Block");

  if (g_strcmp0 (method_name, "Hello") == 0)
    {
      const gchar *greeting;
      gchar *response;

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

      response = g_strdup_printf ("Method %s.%s with user_data '%s' on object path %s called with arg '%s'",
                                  interface_name,
                                  method_name,
                                  (const gchar *) user_data,
                                  object_path,
                                  greeting);
      g_dbus_method_invocation_return_value (invocation,
                                             g_variant_new ("(s)", response));
      g_free (response);
    }
  else if (g_strcmp0 (method_name, "DoStuff") == 0)
    {
      g_dbus_method_invocation_return_dbus_error (invocation,
                                                  "org.gtk.GDBus.TestSubtree.Error.Failed",
                                                  "This method intentionally always fails");
    }
  else
    {
      g_assert_not_reached ();
    }
}

static GVariant *
block_get_property (GDBusConnection  *connection,
                    const gchar      *sender,
                    const gchar      *object_path,
                    const gchar      *interface_name,
                    const gchar      *property_name,
                    GError          **error,
                    gpointer          user_data)
{
  GVariant *ret;
  const gchar *node;
  gint major;
  gint minor;

  node = strrchr (object_path, '/') + 1;
  if (g_str_has_prefix (node, "sda"))
    major = 8;
  else
    major = 9;
  if (strlen (node) == 4)
    minor = node[3] - '0';
  else
    minor = 0;

  ret = NULL;
  if (g_strcmp0 (property_name, "Major") == 0)
    {
      ret = g_variant_new_int32 (major);
    }
  else if (g_strcmp0 (property_name, "Minor") == 0)
    {
      ret = g_variant_new_int32 (minor);
    }
  else if (g_strcmp0 (property_name, "Notes") == 0)
    {
      g_set_error (error,
                   G_IO_ERROR,
                   G_IO_ERROR_FAILED,
                   "Hello %s. I thought I said reading this property "
                   "always results in an error. kthxbye",
                   sender);
    }
  else
    {
      g_assert_not_reached ();
    }

  return ret;
}

static gboolean
block_set_property (GDBusConnection  *connection,
                    const gchar      *sender,
                    const gchar      *object_path,
                    const gchar      *interface_name,
                    const gchar      *property_name,
                    GVariant         *value,
                    GError          **error,
                    gpointer          user_data)
{
  /* TODO */
  g_assert_not_reached ();
}

const GDBusInterfaceVTable block_vtable =
{
  block_method_call,
  block_get_property,
  block_set_property,
  { 0 }
};

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

static void
partition_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)
{
  const gchar *greeting;
  gchar *response;

  g_assert_cmpstr (interface_name, ==, "org.gtk.GDBus.Example.Partition");
  g_assert_cmpstr (method_name, ==, "Hello");

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

  response = g_strdup_printf ("Method %s.%s with user_data '%s' on object path %s called with arg '%s'",
                              interface_name,
                              method_name,
                              (const gchar *) user_data,
                              object_path,
                              greeting);
  g_dbus_method_invocation_return_value (invocation,
                                         g_variant_new ("(s)", response));
  g_free (response);
}

const GDBusInterfaceVTable partition_vtable =
{
  partition_method_call,
  NULL,
  NULL,
  { 0 }
};

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

static gchar **
subtree_enumerate (GDBusConnection       *connection,
                   const gchar           *sender,
                   const gchar           *object_path,
                   gpointer               user_data)
{
  gchar **nodes;
  GPtrArray *p;

  p = g_ptr_array_new ();
  g_ptr_array_add (p, g_strdup ("sda"));
  g_ptr_array_add (p, g_strdup ("sda1"));
  g_ptr_array_add (p, g_strdup ("sda2"));
  g_ptr_array_add (p, g_strdup ("sda3"));
  g_ptr_array_add (p, g_strdup ("sdb"));
  g_ptr_array_add (p, g_strdup ("sdb1"));
  g_ptr_array_add (p, g_strdup ("sdc"));
  g_ptr_array_add (p, g_strdup ("sdc1"));
  g_ptr_array_add (p, NULL);
  nodes = (gchar **) g_ptr_array_free (p, FALSE);

  return nodes;
}

static GDBusInterfaceInfo **
subtree_introspect (GDBusConnection       *connection,
                    const gchar           *sender,
                    const gchar           *object_path,
                    const gchar           *node,
                    gpointer               user_data)
{
  GPtrArray *p;

  p = g_ptr_array_new ();
  if (node == NULL)
    {
      g_ptr_array_add (p, g_dbus_interface_info_ref (manager_interface_info));
    }
  else
    {
      g_ptr_array_add (p, g_dbus_interface_info_ref (block_interface_info));
      if (strlen (node) == 4)
        g_ptr_array_add (p,
                         g_dbus_interface_info_ref (partition_interface_info));
    }

  g_ptr_array_add (p, NULL);

  return (GDBusInterfaceInfo **) g_ptr_array_free (p, FALSE);
}

static const GDBusInterfaceVTable *
subtree_dispatch (GDBusConnection             *connection,
                  const gchar                 *sender,
                  const gchar                 *object_path,
                  const gchar                 *interface_name,
                  const gchar                 *node,
                  gpointer                    *out_user_data,
                  gpointer                     user_data)
{
  const GDBusInterfaceVTable *vtable_to_return;
  gpointer user_data_to_return;

  if (g_strcmp0 (interface_name, "org.gtk.GDBus.Example.Manager") == 0)
    {
      user_data_to_return = "The Root";
      vtable_to_return = &manager_vtable;
    }
  else
    {
      if (strlen (node) == 4)
        user_data_to_return = "A partition";
      else
        user_data_to_return = "A block device";

      if (g_strcmp0 (interface_name, "org.gtk.GDBus.Example.Block") == 0)
        vtable_to_return = &block_vtable;
      else if (g_strcmp0 (interface_name, "org.gtk.GDBus.Example.Partition") == 0)
        vtable_to_return = &partition_vtable;
      else
        g_assert_not_reached ();
    }

  *out_user_data = user_data_to_return;

  return vtable_to_return;
}

const GDBusSubtreeVTable subtree_vtable =
{
  subtree_enumerate,
  subtree_introspect,
  subtree_dispatch,
  { 0 }
};

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

static void
on_bus_acquired (GDBusConnection *connection,
                 const gchar     *name,
                 gpointer         user_data)
{
  guint registration_id;

  registration_id = g_dbus_connection_register_subtree (connection,
                                                        "/org/gtk/GDBus/TestSubtree/Devices",
                                                        &subtree_vtable,
                                                        G_DBUS_SUBTREE_FLAGS_NONE,
                                                        NULL,  /* user_data */
                                                        NULL,  /* user_data_free_func */
                                                        NULL); /* GError** */
  g_assert (registration_id > 0);
}

static void
on_name_acquired (GDBusConnection *connection,
                  const gchar     *name,
                  gpointer         user_data)
{
}

static void
on_name_lost (GDBusConnection *connection,
              const gchar     *name,
              gpointer         user_data)
{
  exit (1);
}

int
main (int argc, char *argv[])
{
  guint owner_id;
  GMainLoop *loop;

  /* We are lazy here - we don't want to manually provide
   * the introspection data structures - so we just build
   * them from XML.
   */
  introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
  g_assert (introspection_data != NULL);

  manager_interface_info = g_dbus_node_info_lookup_interface (introspection_data, "org.gtk.GDBus.Example.Manager");
  block_interface_info = g_dbus_node_info_lookup_interface (introspection_data, "org.gtk.GDBus.Example.Block");
  partition_interface_info = g_dbus_node_info_lookup_interface (introspection_data, "org.gtk.GDBus.Example.Partition");
  g_assert (manager_interface_info != NULL);
  g_assert (block_interface_info != NULL);
  g_assert (partition_interface_info != NULL);

  owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
                             "org.gtk.GDBus.TestSubtree",
                             G_BUS_NAME_OWNER_FLAGS_NONE,
                             on_bus_acquired,
                             on_name_acquired,
                             on_name_lost,
                             NULL,
                             NULL);

  loop = g_main_loop_new (NULL, FALSE);
  g_main_loop_run (loop);

  g_bus_unown_name (owner_id);

  g_dbus_node_info_unref (introspection_data);

  return 0;
}
