/*
 * Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#define _GNU_SOURCE /* for RTLD_NEXT in dlfcn.h */

#include <glib.h>
#include <glib/gtypes.h>
#include <glib-object.h>

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

/*
 * This purpose of this library is to override libgudev to return
 * arbitrary results for selected devices, generally for the purposes
 * of testing. Adding the library file to LD_PRELOAD is the general
 * way to accomplish this. The arbitrary results to return are
 * specified in the environment variable GUDEV_PRELOAD as follows:
 *
 * FAKEGUDEV_DEVICES=device_file=/dev/pts/1:subsystem=tty:name=pts/1:\
 * parent=/dev/pts:property_DEVICE_PROPERTY=123
 *
 * Multiple devices may be specified; each device_file entry starts a
 * new device.  The "parent" property on a device specifies a device
 * path that will be looked up with
 * g_udev_client_query_by_device_file() to find a parent device. This
 * may be a real device that the real libgudev will return a device
 * for, or it may be another fake device handled by this library.
 *
 * Unspecified properties/attributes will be returned as NULL.
 *
 * No mechanism currently exists to escape : and = characters in property names.
 *
 * Setting the environment variable FAKEGUDEV_BLOCK_REAL causes this
 * library to prevent real devices from being iterated over with
 * g_udev_query_by_subsystem().
 */

struct GUdevClient;
typedef struct GUdevClient GUdevClient;

typedef struct _FakeGUdevDevice
{
  GObject             parent;

  /*< private >*/
  GHashTable *properties;
  GUdevClient *client;
  const gchar **propkeys;
} FakeGUdevDevice;

typedef struct _FakeGUdevDeviceClass
{
  GObjectClass parent_class;
} FakeGUdevDeviceClass;

GType g_udev_device_get_type (void) G_GNUC_CONST;


#define FAKE_G_UDEV_TYPE_DEVICE         (fake_g_udev_device_get_type ())
#define FAKE_G_UDEV_DEVICE(o)           \
   (G_TYPE_CHECK_INSTANCE_CAST ((o), FAKE_G_UDEV_TYPE_DEVICE, FakeGUdevDevice))

G_DEFINE_TYPE (FakeGUdevDevice, fake_g_udev_device, G_TYPE_OBJECT)

/* Map from device paths (/dev/pts/1) to FakeGUdevDevice objects */
static GHashTable *devices_by_path;

/* Map from sysfs paths (/sys/devices/blah) to FakeGUdevDevice objects */
static GHashTable *devices_by_syspath;

/* Map which acts as a set of FakeGUdevDevice objects */
static GHashTable *devices_by_ptr;

/* Prevent subsystem query from listing devices */
static gboolean block_real = FALSE;

static const char *k_env_devices = "FAKEGUDEV_DEVICES";
static const char *k_env_block_real = "FAKEGUDEV_BLOCK_REAL";
static const char *k_delims = ":=";
static const char *k_prop_device_file = "device_file";
static const char *k_prop_devtype = "devtype";
static const char *k_prop_driver = "driver";
static const char *k_prop_name = "name";
static const char *k_prop_parent = "parent";
static const char *k_prop_subsystem = "subsystem";
static const char *k_prop_sysfs_path = "sysfs_path";
static const char *k_property_prefix = "property_";
static const char *k_sysfs_attr_prefix = "sysfs_attr_";

static const char *k_func_q_device_file = "g_udev_client_query_by_device_file";
static const char *k_func_q_sysfs_path = "g_udev_client_query_by_sysfs_path";
static const char *k_func_q_by_subsystem = "g_udev_client_query_by_subsystem";
static const char *k_func_q_by_subsystem_and_name =
    "g_udev_client_query_by_subsystem_and_name";
static const char *k_func_get_device_file = "g_udev_device_get_device_file";
static const char *k_func_get_devtype = "g_udev_device_get_devtype";
static const char *k_func_get_driver = "g_udev_device_get_driver";
static const char *k_func_get_name = "g_udev_device_get_name";
static const char *k_func_get_parent = "g_udev_device_get_parent";
static const char *k_func_get_property = "g_udev_device_get_property";
static const char *k_func_get_property_keys = "g_udev_device_get_property_keys";
static const char *k_func_get_subsystem = "g_udev_device_get_subsystem";
static const char *k_func_get_sysfs_path = "g_udev_device_get_sysfs_path";
static const char *k_func_get_sysfs_attr = "g_udev_device_get_sysfs_attr";


/* TODO(njw): set up a _fini() routine to free allocated memory */

static void
g_udev_preload_init ()
{
  const char *orig_ev;
  char *ev, *saveptr, *name, *value;
  FakeGUdevDevice *device;

  /* global tables */
  devices_by_path = g_hash_table_new (g_str_hash, g_str_equal);
  devices_by_syspath = g_hash_table_new (g_str_hash, g_str_equal);
  devices_by_ptr = g_hash_table_new (NULL, NULL);

  orig_ev = getenv (k_env_devices);
  if (orig_ev == NULL)
    orig_ev = "";
  ev = g_strdup (orig_ev);

  name = strtok_r (ev, k_delims, &saveptr);
  value = strtok_r (NULL, k_delims, &saveptr);
  device = NULL;

  while (name != NULL && value != NULL) {
    if (strcmp (name, k_prop_device_file) == 0) {
      device = FAKE_G_UDEV_DEVICE (g_object_new (FAKE_G_UDEV_TYPE_DEVICE,
                                                 NULL));
      g_hash_table_insert (devices_by_path, g_strdup (value), device);
      g_hash_table_insert (devices_by_ptr, device, NULL);
    }
    if (device != NULL) {
      g_hash_table_insert (device->properties, g_strdup (name),
                           g_strdup (value));

      if (strcmp (name, k_prop_sysfs_path) == 0)
        g_hash_table_insert (devices_by_syspath, g_strdup (value), device);
    }

    name = strtok_r (NULL, k_delims, &saveptr);
    value = strtok_r (NULL, k_delims, &saveptr);
  }
  g_free (ev);

  if (getenv (k_env_block_real))
    block_real = TRUE;
}

GList *
g_udev_client_query_by_subsystem (GUdevClient *client, const gchar *subsystem)
{
  static GList* (*realfunc)();
  GHashTableIter iter;
  gpointer key, value;
  GList *list, *reallist;

  if (devices_by_path == NULL)
    g_udev_preload_init ();

  list = NULL;
  g_hash_table_iter_init (&iter, devices_by_path);
  while (g_hash_table_iter_next (&iter, &key, &value)) {
    FakeGUdevDevice *device = value;
    gchar *dev_subsystem =
        (gchar *)g_hash_table_lookup (device->properties, k_prop_subsystem);
    if (strcmp (subsystem, dev_subsystem) == 0)
      list = g_list_append (list, device);
  }

  if (!block_real) {
    if (realfunc == NULL)
      realfunc = (GList *(*)()) dlsym (RTLD_NEXT, k_func_q_by_subsystem);
    reallist = realfunc (client, subsystem);
    list = g_list_concat (list, reallist);
    g_list_free (reallist);
  }

  return list;
}

/*
 * This is our hook. We look for a particular device path
 * and return a special pointer.
 */
FakeGUdevDevice*
g_udev_client_query_by_device_file (GUdevClient *client,
                                    const gchar *device_file)
{
  static FakeGUdevDevice* (*realfunc)();
  FakeGUdevDevice *device;

  if (devices_by_path == NULL)
    g_udev_preload_init ();

  if (g_hash_table_lookup_extended (devices_by_path, device_file, NULL,
                                    (gpointer *)&device)) {
    /* Stash the client pointer for later use in _get_parent() */
    device->client = client;
    return g_object_ref (device);
  }

  if (realfunc == NULL)
    realfunc = (FakeGUdevDevice *(*)()) dlsym (RTLD_NEXT, k_func_q_device_file);
  return realfunc (client, device_file);
}

FakeGUdevDevice*
g_udev_client_query_by_sysfs_path (GUdevClient *client,
                                    const gchar *sysfs_path)
{
  static FakeGUdevDevice* (*realfunc)();
  FakeGUdevDevice *device;

  if (devices_by_path == NULL)
    g_udev_preload_init ();

  if (g_hash_table_lookup_extended (devices_by_syspath, sysfs_path, NULL,
                                    (gpointer *)&device)) {
    /* Stash the client pointer for later use in _get_parent() */
    device->client = client;
    return g_object_ref (device);
  }

  if (realfunc == NULL)
    realfunc = (FakeGUdevDevice *(*)()) dlsym (RTLD_NEXT, k_func_q_sysfs_path);
  return realfunc (client, sysfs_path);
}


FakeGUdevDevice *
g_udev_client_query_by_subsystem_and_name (GUdevClient *client,
                                           const gchar *subsystem,
                                           const gchar *name)
{
  static FakeGUdevDevice* (*realfunc)();
  GHashTableIter iter;
  gpointer key, value;

  if (devices_by_path == NULL)
    g_udev_preload_init ();

  g_hash_table_iter_init (&iter, devices_by_path);
  while (g_hash_table_iter_next (&iter, &key, &value)) {
    FakeGUdevDevice *device = value;
    gchar *dev_subsystem =
        (gchar *)g_hash_table_lookup (device->properties, k_prop_subsystem);
    gchar *dev_name =
        (gchar *)g_hash_table_lookup (device->properties, k_prop_name);
    if (dev_subsystem && dev_name &&
        (strcmp (subsystem, dev_subsystem) == 0) &&
        (strcmp (name, dev_name) == 0)) {
      device->client = client;
      return g_object_ref (device);
    }
  }

  if (realfunc == NULL)
    realfunc = (FakeGUdevDevice *(*)()) dlsym (RTLD_NEXT,
                                               k_func_q_by_subsystem_and_name);
  return realfunc (client, subsystem, name);
}


/*
 * Our device data is a glib hash table with string keys and values;
 * the keys and values are owned by the hash table.
 */

/*
 * For g_udev_device_*() functions, the general drill is to check if
 * the device is "ours", and if not, delegate to the real library
 * method.
 */
const gchar *
g_udev_device_get_device_file (FakeGUdevDevice *device)
{
  static const gchar* (*realfunc)();

  if (devices_by_ptr == NULL)
    g_udev_preload_init ();

  if (g_hash_table_lookup_extended (devices_by_ptr, device, NULL, NULL))
    return (gchar *)g_hash_table_lookup (device->properties,
                                         k_prop_device_file);

  if (realfunc == NULL)
    realfunc = (const gchar *(*)()) dlsym (RTLD_NEXT, k_func_get_device_file);
  return realfunc (device);
}

const gchar *
g_udev_device_get_devtype (FakeGUdevDevice *device)
{
  static const gchar* (*realfunc)();

  if (devices_by_ptr == NULL)
    g_udev_preload_init ();

  if (g_hash_table_lookup_extended (devices_by_ptr, device, NULL, NULL))
    return (gchar *)g_hash_table_lookup (device->properties, k_prop_devtype);

  if (realfunc == NULL)
    realfunc = (const gchar *(*)()) dlsym (RTLD_NEXT, k_func_get_devtype);
  return realfunc (device);
}

const gchar *
g_udev_device_get_driver (FakeGUdevDevice *device)
{
  static const gchar* (*realfunc)();

  if (devices_by_ptr == NULL)
    g_udev_preload_init ();

  if (g_hash_table_lookup_extended (devices_by_ptr, device, NULL, NULL))
    return (gchar *)g_hash_table_lookup (device->properties, k_prop_driver);

  if (realfunc == NULL)
    realfunc = (const gchar *(*)()) dlsym (RTLD_NEXT, k_func_get_driver);
  return realfunc (device);
}

const gchar *
g_udev_device_get_name (FakeGUdevDevice *device)
{
  static const gchar* (*realfunc)();

  if (devices_by_ptr == NULL)
    g_udev_preload_init ();

  if (g_hash_table_lookup_extended (devices_by_ptr, device, NULL, NULL))
    return (gchar *)g_hash_table_lookup (device->properties, k_prop_name);

  if (realfunc == NULL)
    realfunc = (const gchar *(*)()) dlsym (RTLD_NEXT, k_func_get_name);
  return realfunc (device);
}

const FakeGUdevDevice *
g_udev_device_get_parent (FakeGUdevDevice *device)
{
  static const FakeGUdevDevice* (*realfunc)();

  if (devices_by_ptr == NULL)
    g_udev_preload_init ();

  if (g_hash_table_lookup_extended (devices_by_ptr, device, NULL, NULL)) {
    gchar *parent = (gchar *)g_hash_table_lookup (device->properties,
                                                  k_prop_parent);
    if (parent == NULL)
      return NULL;
    return g_udev_client_query_by_device_file (device->client, parent);
  }

  if (realfunc == NULL)
    realfunc = (const FakeGUdevDevice *(*)()) dlsym (RTLD_NEXT,
                                                     k_func_get_parent);
  return realfunc (device);

  return NULL;
}

const gchar *
g_udev_device_get_property (FakeGUdevDevice *device,
                            const gchar *key)
{
  static const gchar* (*realfunc)();

  if (devices_by_ptr == NULL)
    g_udev_preload_init ();

  if (g_hash_table_lookup_extended (devices_by_ptr, device, NULL, NULL)) {
    gchar *propkey = g_strconcat (k_property_prefix, key, NULL);
    const gchar *result = (gchar *)g_hash_table_lookup (device->properties,
                                                        propkey);
    g_free (propkey);
    return result;
  }

  if (realfunc == NULL)
    realfunc = (const gchar *(*)()) dlsym (RTLD_NEXT, k_func_get_property);
  return realfunc (device, key);
}

/*
 * All of the g_udev_device_get_property_as_SOMETYPE () functions call
 * g_udev_device_get_property() and then operate on the result, so we
 * ideally shouldn't need to implement them ourselves, as the real
 * udev will start by calling into our version of
 * g_udev_device_get_property().
 *
 * However, that doesn't work. The _as_SOMETYPE () functions validate
 * the device pointer first (via G_TYPE_CHECK_INSTANCE_TYPE), which
 * segfaults on our non-GObject device pointers. We'd have to fake
 * that out more thoroughly in order to pass.
 */
gboolean
g_udev_device_get_property_as_boolean (FakeGUdevDevice *device,
                                       const gchar *key)
{
  static gboolean (*realfunc)();

  if (devices_by_ptr == NULL)
    g_udev_preload_init ();

  if (g_hash_table_lookup_extended (devices_by_ptr, device, NULL, NULL)) {
    gchar *propkey = g_strconcat (k_property_prefix, key, NULL);
    const gchar *result = (gchar *)g_hash_table_lookup (device->properties,
                                                        propkey);
    g_free (propkey);

    if (result &&
        (strcmp (result, "1") == 0 || g_ascii_strcasecmp (result, "true") == 0))
      return TRUE;
    else
      return FALSE;
  }

  if (realfunc == NULL)
    realfunc = (gboolean (*)()) dlsym (RTLD_NEXT, k_func_get_property);
  return realfunc (device, key);
}

gint
g_udev_device_get_property_as_int (FakeGUdevDevice *device,
                                   const gchar *key)
{
  static gint (*realfunc)();

  if (devices_by_ptr == NULL)
    g_udev_preload_init ();

  if (g_hash_table_lookup_extended (devices_by_ptr, device, NULL, NULL)) {
    gchar *propkey = g_strconcat (k_property_prefix, key, NULL);
    const gchar *result = (gchar *)g_hash_table_lookup (device->properties,
                                                        propkey);
    g_free (propkey);

    return strtol (result, NULL, 0);
  }

  if (realfunc == NULL)
    realfunc = (gint (*)()) dlsym (RTLD_NEXT, k_func_get_property);
  return realfunc (device, key);
}

#if 0
/* Not implemented yet */
guint64 g_udev_device_get_property_as_uint64 (FakeGUdevDevice *device,
                                              const gchar  *key);
gdouble g_udev_device_get_property_as_double (FakeGUdevDevice *device,
                                              const gchar  *key);

const gchar* const *g_udev_device_get_property_as_strv (FakeGUdevDevice *device,
                                                        const gchar  *key);

#endif

const gchar * const *
g_udev_device_get_property_keys (FakeGUdevDevice *device)
{
  static const gchar* const* (*realfunc)();

  if (devices_by_ptr == NULL)
    g_udev_preload_init ();

  if (g_hash_table_lookup_extended (devices_by_ptr, device, NULL, NULL)) {
    const gchar **keys;
    if (device->propkeys)
      return device->propkeys;

    GList *keylist = g_hash_table_get_keys(device->properties);
    GList *key, *prop, *proplist = NULL;
    guint propcount = 0;
    for (key = keylist; key != NULL ; key = key->next) {
      if (strncmp ((char *)key->data, k_property_prefix,
                   strlen (k_property_prefix)) == 0) {
        proplist = g_list_prepend (proplist, key->data +
                                   strlen (k_property_prefix));
        propcount++;
      }
    }
    keys = g_malloc ((propcount + 1) * sizeof(*keys));
    keys[propcount] = NULL;
    for (prop = proplist; prop != NULL ; prop = prop->next)
      keys[--propcount] = g_strdup (prop->data);
    g_list_free (proplist);

    device->propkeys = keys;

    return keys;
  }

  if (realfunc == NULL)
    realfunc = (const gchar * const*(*)()) dlsym (RTLD_NEXT,
                                                  k_func_get_property_keys);
  return realfunc (device);
}


const gchar *
g_udev_device_get_subsystem (FakeGUdevDevice *device)
{
  static const gchar* (*realfunc)();

  if (devices_by_ptr == NULL)
    g_udev_preload_init ();

  if (g_hash_table_lookup_extended (devices_by_ptr, device, NULL, NULL))
    return (gchar *)g_hash_table_lookup (device->properties, k_prop_subsystem);

  if (realfunc == NULL)
    realfunc = (const gchar *(*)()) dlsym (RTLD_NEXT, k_func_get_subsystem);
  return realfunc (device);
}

const gchar *
g_udev_device_get_sysfs_attr (FakeGUdevDevice *device, const gchar *name)
{
  static const gchar* (*realfunc)();

  if (devices_by_ptr == NULL)
    g_udev_preload_init ();

  if (g_hash_table_lookup_extended (devices_by_ptr, device, NULL, NULL)) {
    gchar *attrkey = g_strconcat (k_sysfs_attr_prefix, name, NULL);
    const gchar *result = (gchar *)g_hash_table_lookup (device->properties,
                                                        attrkey);
    g_free (attrkey);
    return result;
  }

  if (realfunc == NULL)
    realfunc = (const gchar *(*)()) dlsym (RTLD_NEXT, k_func_get_sysfs_attr);
  return realfunc (device, name);
}

/*
 * The get_sysfs_attr_as_SOMETYPE() functions have the same problem as
 * the get_property_as_SOMETYPE() functions described above.
 */

const gchar *
g_udev_device_get_sysfs_path (FakeGUdevDevice *device)
{
  static const gchar* (*realfunc)();

  if (devices_by_ptr == NULL)
    g_udev_preload_init ();

  if (g_hash_table_lookup_extended (devices_by_ptr, device, NULL, NULL)) {
    return (gchar *)g_hash_table_lookup (device->properties, k_prop_sysfs_path);
  }

  if (realfunc == NULL)
    realfunc = (const gchar *(*)()) dlsym (RTLD_NEXT, k_func_get_sysfs_path);
  return realfunc (device);
}

#if 0
/* Not implemented yet */
const gchar *g_udev_device_get_number (FakeGUdevDevice *device);
const gchar *g_udev_device_get_action (FakeGUdevDevice *device);
guint64 g_udev_device_get_seqnum (FakeGUdevDevice *device);
FakeGUdevDeviceType g_udev_device_get_device_type (FakeGUdevDevice *device);
FakeGUdevDeviceNumber g_udev_device_get_device_number (FakeGUdevDevice *device);
const gchar * const *
g_udev_device_get_device_file_symlinks (FakeGUdevDevice *device);
FakeGUdevDevice *
g_udev_device_get_parent_with_subsystem (FakeGUdevDevice *device,
                                         const gchar *subsystem,
                                         const gchar *devtype);
const gchar * const *g_udev_device_get_tags (FakeGUdevDevice *device);
gboolean g_udev_device_get_is_initialized (FakeGUdevDevice *device);
guint64 g_udev_device_get_usec_since_initialized (FakeGUdevDevice *device);
gboolean g_udev_device_has_property (FakeGUdevDevice *device, const gchar *key);
#endif


static void
fake_g_udev_device_init (FakeGUdevDevice *device)
{
  device->properties = g_hash_table_new_full (g_str_hash, g_str_equal,
                                              g_free, g_free);
  device->propkeys = NULL;
  device->client = NULL;
}

static void
fake_g_udev_device_finalize (GObject *object)
{
  FakeGUdevDevice *device = FAKE_G_UDEV_DEVICE (object);

  g_hash_table_unref (device->properties);
}

static void
fake_g_udev_device_class_init (FakeGUdevDeviceClass *klass)
{
  GObjectClass *gobject_class = (GObjectClass *) klass;

  gobject_class->finalize = fake_g_udev_device_finalize;
}
