/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
 *
 * Copyright (C) 2008-2010 David Zeuthen <davidz@redhat.com>
 *
 * 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.
 *
 */

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif

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

#include "gudevclient.h"
#include "gudevdevice.h"
#include "gudevmarshal.h"
#include "gudevprivate.h"

/**
 * SECTION:gudevclient
 * @short_description: Query devices and listen to uevents
 *
 * #GUdevClient is used to query information about devices on a Linux
 * system from the Linux kernel and the udev device
 * manager.
 *
 * Device information is retrieved from the kernel (through the
 * <literal>sysfs</literal> filesystem) and the udev daemon (through a
 * <literal>tmpfs</literal> filesystem) and presented through
 * #GUdevDevice objects. This means that no blocking IO ever happens
 * (in both cases, we are essentially just reading data from kernel
 * memory) and as such there are no asynchronous versions of the
 * provided methods.
 *
 * To get #GUdevDevice objects, use
 * g_udev_client_query_by_subsystem(),
 * g_udev_client_query_by_device_number(),
 * g_udev_client_query_by_device_file(),
 * g_udev_client_query_by_sysfs_path(),
 * g_udev_client_query_by_subsystem_and_name()
 * or the #GUdevEnumerator type.
 *
 * To listen to uevents, connect to the #GUdevClient::uevent signal.
 */

struct _GUdevClientPrivate
{
  GSource *watch_source;
  struct udev *udev;
  struct udev_monitor *monitor;

  gchar **subsystems;
};

enum
{
  PROP_0,
  PROP_SUBSYSTEMS,
};

enum
{
  UEVENT_SIGNAL,
  LAST_SIGNAL,
};

static guint signals[LAST_SIGNAL] = { 0 };

G_DEFINE_TYPE (GUdevClient, g_udev_client, G_TYPE_OBJECT)

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

static gboolean
monitor_event (GIOChannel *source,
	       GIOCondition condition,
	       gpointer data)
{
  GUdevClient *client = (GUdevClient *) data;
  GUdevDevice *device;
  struct udev_device *udevice;

  if (client->priv->monitor == NULL)
    goto out;
  udevice = udev_monitor_receive_device (client->priv->monitor);
  if (udevice == NULL)
    goto out;

  device = _g_udev_device_new (udevice);
  udev_device_unref (udevice);
  g_signal_emit (client,
                 signals[UEVENT_SIGNAL],
                 0,
                 g_udev_device_get_action (device),
                 device);
  g_object_unref (device);

 out:
  return TRUE;
}

static void
g_udev_client_finalize (GObject *object)
{
  GUdevClient *client = G_UDEV_CLIENT (object);

  if (client->priv->watch_source != NULL)
    {
      g_source_destroy (client->priv->watch_source);
      client->priv->watch_source = NULL;
    }

  if (client->priv->monitor != NULL)
    {
      udev_monitor_unref (client->priv->monitor);
      client->priv->monitor = NULL;
    }

  if (client->priv->udev != NULL)
    {
      udev_unref (client->priv->udev);
      client->priv->udev = NULL;
    }

  g_strfreev (client->priv->subsystems);

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

static void
g_udev_client_set_property (GObject      *object,
                            guint         prop_id,
                            const GValue *value,
                            GParamSpec   *pspec)
{
  GUdevClient *client = G_UDEV_CLIENT (object);

  switch (prop_id)
    {
    case PROP_SUBSYSTEMS:
      if (client->priv->subsystems != NULL)
        g_strfreev (client->priv->subsystems);
      client->priv->subsystems = g_strdupv (g_value_get_boxed (value));
      break;

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

static void
g_udev_client_get_property (GObject     *object,
                            guint        prop_id,
                            GValue      *value,
                            GParamSpec  *pspec)
{
  GUdevClient *client = G_UDEV_CLIENT (object);

  switch (prop_id)
    {
    case PROP_SUBSYSTEMS:
      g_value_set_boxed (value, client->priv->subsystems);
      break;

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

static void
g_udev_client_constructed (GObject *object)
{
  GUdevClient *client = G_UDEV_CLIENT (object);
  GIOChannel *channel;
  guint n;

  client->priv->udev = udev_new ();

  /* connect to event source */
  client->priv->monitor = udev_monitor_new_from_netlink (client->priv->udev, "udev");

  //g_debug ("ss = %p", client->priv->subsystems);

  if (client->priv->subsystems != NULL)
    {
      /* install subsystem filters to only wake up for certain events */
      for (n = 0; client->priv->subsystems[n] != NULL; n++)
        {
          gchar *subsystem;
          gchar *devtype;
          gchar *s;

          subsystem = g_strdup (client->priv->subsystems[n]);
          devtype = NULL;

          //g_debug ("s = '%s'", subsystem);

          s = strstr (subsystem, "/");
          if (s != NULL)
            {
              devtype = s + 1;
              *s = '\0';
            }

          if (client->priv->monitor != NULL)
              udev_monitor_filter_add_match_subsystem_devtype (client->priv->monitor, subsystem, devtype);

          g_free (subsystem);
        }

      /* listen to events, and buffer them */
      if (client->priv->monitor != NULL)
        {
          udev_monitor_enable_receiving (client->priv->monitor);
          channel = g_io_channel_unix_new (udev_monitor_get_fd (client->priv->monitor));
          client->priv->watch_source = g_io_create_watch (channel, G_IO_IN);
          g_io_channel_unref (channel);
          g_source_set_callback (client->priv->watch_source, (GSourceFunc) monitor_event, client, NULL);
          g_source_attach (client->priv->watch_source, g_main_context_get_thread_default ());
          g_source_unref (client->priv->watch_source);
        }
      else
        {
          client->priv->watch_source = NULL;
        }
    }

  if (G_OBJECT_CLASS (g_udev_client_parent_class)->constructed != NULL)
    G_OBJECT_CLASS (g_udev_client_parent_class)->constructed (object);
}


static void
g_udev_client_class_init (GUdevClientClass *klass)
{
  GObjectClass *gobject_class = (GObjectClass *) klass;

  gobject_class->constructed  = g_udev_client_constructed;
  gobject_class->set_property = g_udev_client_set_property;
  gobject_class->get_property = g_udev_client_get_property;
  gobject_class->finalize     = g_udev_client_finalize;

  /**
   * GUdevClient:subsystems:
   *
   * The subsystems to listen for uevents on.
   *
   * To listen for only a specific DEVTYPE for a given SUBSYSTEM, use
   * "subsystem/devtype". For example, to only listen for uevents
   * where SUBSYSTEM is usb and DEVTYPE is usb_interface, use
   * "usb/usb_interface".
   *
   * If this property is %NULL, then no events will be reported. If
   * it's the empty array, events from all subsystems will be
   * reported.
   */
  g_object_class_install_property (gobject_class,
                                   PROP_SUBSYSTEMS,
                                   g_param_spec_boxed ("subsystems",
                                                       "The subsystems to listen for changes on",
                                                       "The subsystems to listen for changes on",
                                                       G_TYPE_STRV,
                                                       G_PARAM_CONSTRUCT_ONLY |
                                                       G_PARAM_READWRITE));

  /**
   * GUdevClient::uevent:
   * @client: The #GUdevClient receiving the event.
   * @action: The action for the uevent e.g. "add", "remove", "change", "move", etc.
   * @device: Details about the #GUdevDevice the event is for.
   *
   * Emitted when @client receives an uevent.
   *
   * This signal is emitted in the
   * <link linkend="g-main-context-push-thread-default">thread-default main loop</link>
   * of the thread that @client was created in.
   */
  signals[UEVENT_SIGNAL] = g_signal_new ("uevent",
                                         G_TYPE_FROM_CLASS (klass),
                                         G_SIGNAL_RUN_LAST,
                                         G_STRUCT_OFFSET (GUdevClientClass, uevent),
                                         NULL,
                                         NULL,
                                         g_udev_marshal_VOID__STRING_OBJECT,
                                         G_TYPE_NONE,
                                         2,
                                         G_TYPE_STRING,
                                         G_UDEV_TYPE_DEVICE);

  g_type_class_add_private (klass, sizeof (GUdevClientPrivate));
}

static void
g_udev_client_init (GUdevClient *client)
{
  client->priv = G_TYPE_INSTANCE_GET_PRIVATE (client,
                                              G_UDEV_TYPE_CLIENT,
                                              GUdevClientPrivate);
}

/**
 * g_udev_client_new:
 * @subsystems: (array zero-terminated=1) (element-type utf8) (transfer none) (allow-none): A %NULL terminated string array of subsystems to listen for uevents on, %NULL to not listen on uevents at all, or an empty array to listen to uevents on all subsystems. See the documentation for the #GUdevClient:subsystems property for details on this parameter.
 *
 * Constructs a #GUdevClient object that can be used to query
 * information about devices. Connect to the #GUdevClient::uevent
 * signal to listen for uevents. Note that signals are emitted in the
 * <link linkend="g-main-context-push-thread-default">thread-default main loop</link>
 * of the thread that you call this constructor from.
 *
 * Returns: A new #GUdevClient object. Free with g_object_unref().
 */
GUdevClient *
g_udev_client_new (const gchar * const *subsystems)
{
  return G_UDEV_CLIENT (g_object_new (G_UDEV_TYPE_CLIENT, "subsystems", subsystems, NULL));
}

/**
 * g_udev_client_query_by_subsystem:
 * @client: A #GUdevClient.
 * @subsystem: (allow-none): The subsystem to get devices for or %NULL to get all devices.
 *
 * Gets all devices belonging to @subsystem.
 *
 * Returns: (element-type GUdevDevice) (transfer full): A list of #GUdevDevice objects. The caller should free the result by using g_object_unref() on each element in the list and then g_list_free() on the list.
 */
GList *
g_udev_client_query_by_subsystem (GUdevClient  *client,
                                  const gchar  *subsystem)
{
  struct udev_enumerate *enumerate;
  struct udev_list_entry *l, *devices;
  GList *ret;

  g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);

  ret = NULL;

  /* prepare a device scan */
  enumerate = udev_enumerate_new (client->priv->udev);

  /* filter for subsystem */
  if (subsystem != NULL)
    udev_enumerate_add_match_subsystem (enumerate, subsystem);
  /* retrieve the list */
  udev_enumerate_scan_devices (enumerate);

  /* add devices to the list */
  devices = udev_enumerate_get_list_entry (enumerate);
  for (l = devices; l != NULL; l = udev_list_entry_get_next (l))
    {
      struct udev_device *udevice;
      GUdevDevice *device;

      udevice = udev_device_new_from_syspath (udev_enumerate_get_udev (enumerate),
                                              udev_list_entry_get_name (l));
      if (udevice == NULL)
        continue;
      device = _g_udev_device_new (udevice);
      udev_device_unref (udevice);
      ret = g_list_prepend (ret, device);
    }
  udev_enumerate_unref (enumerate);

  ret = g_list_reverse (ret);

  return ret;
}

/**
 * g_udev_client_query_by_device_number:
 * @client: A #GUdevClient.
 * @type: A value from the #GUdevDeviceType enumeration.
 * @number: A device number.
 *
 * Looks up a device for a type and device number.
 *
 * Returns: (transfer full): A #GUdevDevice object or %NULL if the device was not found. Free with g_object_unref().
 */
GUdevDevice *
g_udev_client_query_by_device_number (GUdevClient      *client,
                                      GUdevDeviceType   type,
                                      GUdevDeviceNumber number)
{
  struct udev_device *udevice;
  GUdevDevice *device;

  g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);

  device = NULL;
  udevice = udev_device_new_from_devnum (client->priv->udev, type, number);

  if (udevice == NULL)
    goto out;

  device = _g_udev_device_new (udevice);
  udev_device_unref (udevice);

 out:
  return device;
}

/**
 * g_udev_client_query_by_device_file:
 * @client: A #GUdevClient.
 * @device_file: A device file.
 *
 * Looks up a device for a device file.
 *
 * Returns: (transfer full): A #GUdevDevice object or %NULL if the device was not found. Free with g_object_unref().
 */
GUdevDevice *
g_udev_client_query_by_device_file (GUdevClient  *client,
                                    const gchar  *device_file)
{
  struct stat stat_buf;
  GUdevDevice *device;

  g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
  g_return_val_if_fail (device_file != NULL, NULL);

  device = NULL;

  if (stat (device_file, &stat_buf) != 0)
    goto out;

  if (stat_buf.st_rdev == 0)
    goto out;

  if (S_ISBLK (stat_buf.st_mode))
    device = g_udev_client_query_by_device_number (client, G_UDEV_DEVICE_TYPE_BLOCK, stat_buf.st_rdev);
  else if (S_ISCHR (stat_buf.st_mode))
    device = g_udev_client_query_by_device_number (client, G_UDEV_DEVICE_TYPE_CHAR, stat_buf.st_rdev);

 out:
  return device;
}

/**
 * g_udev_client_query_by_sysfs_path:
 * @client: A #GUdevClient.
 * @sysfs_path: A sysfs path.
 *
 * Looks up a device for a sysfs path.
 */
GUdevDevice *
g_udev_client_query_by_sysfs_path (GUdevClient  *client,
                                   const gchar  *sysfs_path)
{
  struct udev_device *udevice;
  GUdevDevice *device;

  g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
  g_return_val_if_fail (sysfs_path != NULL, NULL);

  device = NULL;
  udevice = udev_device_new_from_syspath (client->priv->udev, sysfs_path);
  if (udevice == NULL)
    goto out;

  device = _g_udev_device_new (udevice);
  udev_device_unref (udevice);

 out:
  return device;
}

/**
 * g_udev_client_query_by_subsystem_and_name:
 * @client: A #GUdevClient.
 * @subsystem: A subsystem name.
 * @name: The name of the device.
 *
 * Looks up a device for a subsystem and name.
 *
 * Returns: (transfer full): A #GUdevDevice object or %NULL if the device was not found. Free with g_object_unref().
 */
GUdevDevice *
g_udev_client_query_by_subsystem_and_name (GUdevClient  *client,
                                           const gchar  *subsystem,
                                           const gchar  *name)
{
  struct udev_device *udevice;
  GUdevDevice *device;

  g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
  g_return_val_if_fail (subsystem != NULL, NULL);
  g_return_val_if_fail (name != NULL, NULL);

  device = NULL;
  udevice = udev_device_new_from_subsystem_sysname (client->priv->udev, subsystem, name);
  if (udevice == NULL)
    goto out;

  device = _g_udev_device_new (udevice);
  udev_device_unref (udevice);

 out:
  return device;
}

struct udev *
_g_udev_client_get_udev (GUdevClient *client)
{
  g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
  return client->priv->udev;
}

