/*
   Copyright (C) 2005 John McCutchan
   Copyright © 2015 Canonical Limited

   The Gnome Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public License as
   published by the Free Software Foundation; either version 2 of the
   License, or (at your option) any later version.

   The Gnome 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
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public
   License along with the Gnome Library; see the file COPYING.LIB.  If not,
   see <http://www.gnu.org/licenses/>.

   Authors:
     Ryan Lortie <desrt@desrt.ca>
     John McCutchan <john@johnmccutchan.com>
*/

#include "config.h"

#include <stdio.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <glib.h>
#include "inotify-kernel.h"
#include <sys/inotify.h>
#include <glib/glib-unix.h>

#include "glib-private.h"

/* From inotify(7) */
#define MAX_EVENT_SIZE       (sizeof(struct inotify_event) + NAME_MAX + 1)

/* Amount of time to sleep on receipt of uninteresting events */
#define BOREDOM_SLEEP_TIME   (100 * G_TIME_SPAN_MILLISECOND)

/* Define limits on the maximum amount of time and maximum amount of
 * interceding events between FROM/TO that can be merged.
 */
#define MOVE_PAIR_DELAY      (10 * G_TIME_SPAN_MILLISECOND)
#define MOVE_PAIR_DISTANCE   (100)

/* We use the lock from inotify-helper.c
 *
 * We only have to take it on our read callback.
 *
 * The rest of locking is taken care of in inotify-helper.c
 */
G_LOCK_EXTERN (inotify_lock);

static ik_event_t *
ik_event_new (struct inotify_event *kevent,
              gint64                now)
{
  ik_event_t *event = g_new0 (ik_event_t, 1);

  event->wd = kevent->wd;
  event->mask = kevent->mask;
  event->cookie = kevent->cookie;
  event->len = kevent->len;
  event->timestamp = now;
  if (event->len)
    event->name = g_strdup (kevent->name);
  else
    event->name = NULL;

  return event;
}

void
_ik_event_free (ik_event_t *event)
{
  if (event->pair)
    {
      event->pair->pair = NULL;
      _ik_event_free (event->pair);
    }

  g_free (event->name);
  g_free (event);
}

typedef struct
{
  GSource     source;

  GQueue      queue;
  gpointer    fd_tag;
  gint        fd;

  GHashTable *unmatched_moves;
  gboolean    is_bored;
} InotifyKernelSource;

static InotifyKernelSource *inotify_source;

static gint64
ik_source_get_dispatch_time (InotifyKernelSource *iks)
{
  ik_event_t *head;

  head = g_queue_peek_head (&iks->queue);

  /* nothing in the queue: not ready */
  if (!head)
    return -1;

  /* if it's not an unpaired move, it is ready now */
  if (~head->mask & IN_MOVED_FROM || head->pair)
    return 0;

  /* if the queue is too long then it's ready now */
  if (iks->queue.length > MOVE_PAIR_DISTANCE)
    return 0;

  /* otherwise, it's ready after the delay */
  return head->timestamp + MOVE_PAIR_DELAY;
}

static gboolean
ik_source_can_dispatch_now (InotifyKernelSource *iks,
                            gint64               now)
{
  gint64 dispatch_time;

  dispatch_time = ik_source_get_dispatch_time (iks);

  return 0 <= dispatch_time && dispatch_time <= now;
}

static gsize
ik_source_read_some_events (InotifyKernelSource *iks,
                            gchar               *buffer,
                            gsize                buffer_len)
{
  gssize result;

again:
  result = read (iks->fd, buffer, buffer_len);

  if (result < 0)
    {
      if (errno == EINTR)
        goto again;

      if (errno == EAGAIN)
        return 0;

      g_error ("inotify read(): %s", g_strerror (errno));
    }
  else if (result == 0)
    g_error ("inotify unexpectedly hit eof");

  return result;
}

static gchar *
ik_source_read_all_the_events (InotifyKernelSource *iks,
                               gchar               *buffer,
                               gsize                buffer_len,
                               gsize               *length_out)
{
  gsize n_read;

  n_read = ik_source_read_some_events (iks, buffer, buffer_len);

  /* Check if we might have gotten another event if we had passed in a
   * bigger buffer...
   */
  if (n_read + MAX_EVENT_SIZE > buffer_len)
    {
      gchar *new_buffer;
      guint n_readable;
      gint result;

      /* figure out how many more bytes there are to read */
      result = ioctl (iks->fd, FIONREAD, &n_readable);
      if (result != 0)
        g_error ("inotify ioctl(FIONREAD): %s", g_strerror (errno));

      if (n_readable != 0)
        {
          /* there is in fact more data.  allocate a new buffer, copy
           * the existing data, and then append the remaining.
           */
          new_buffer = g_malloc (n_read + n_readable);
          memcpy (new_buffer, buffer, n_read);
          n_read += ik_source_read_some_events (iks, new_buffer + n_read, n_readable);

          buffer = new_buffer;

          /* There may be new events in the buffer that were added after
           * the FIONREAD was performed, but we can't risk getting into
           * a loop.  We'll get them next time.
           */
        }
    }

  *length_out = n_read;

  return buffer;
}

static gboolean
ik_source_dispatch (GSource     *source,
                    GSourceFunc  func,
                    gpointer     user_data)
{
  InotifyKernelSource *iks = (InotifyKernelSource *) source;
  gboolean (*user_callback) (ik_event_t *event) = (void *) func;
  gboolean interesting = FALSE;
  gint64 now;

  now = g_source_get_time (source);

  if (iks->is_bored || g_source_query_unix_fd (source, iks->fd_tag))
    {
      gchar stack_buffer[4096];
      gsize buffer_len;
      gchar *buffer;
      gsize offset;

      /* We want to read all of the available events.
       *
       * We need to do it in a finite number of steps so that we don't
       * get caught in a loop of read() with another process
       * continuously adding events each time we drain them.
       *
       * In the normal case we will have only a few events in the queue,
       * so start out by reading into a small stack-allocated buffer.
       * Even though we're on a fresh stack frame, there is no need to
       * pointlessly blow up with the size of the worker thread stack
       * with a huge buffer here.
       *
       * If the result is large enough to cause us to suspect that
       * another event may be pending then we allocate a buffer on the
       * heap that can hold all of the events and read (once!) into that
       * buffer.
       */
      buffer = ik_source_read_all_the_events (iks, stack_buffer, sizeof stack_buffer, &buffer_len);

      offset = 0;

      while (offset < buffer_len)
        {
          struct inotify_event *kevent = (struct inotify_event *) (buffer + offset);
          ik_event_t *event;

          event = ik_event_new (kevent, now);

          offset += sizeof (struct inotify_event) + event->len;

          if (event->mask & IN_MOVED_TO)
            {
              ik_event_t *pair;

              pair = g_hash_table_lookup (iks->unmatched_moves, GUINT_TO_POINTER (event->cookie));
              if (pair != NULL)
                {
                  g_assert (!pair->pair);

                  g_hash_table_remove (iks->unmatched_moves, GUINT_TO_POINTER (event->cookie));
                  event->is_second_in_pair = TRUE;
                  event->pair = pair;
                  pair->pair = event;
                  continue;
                }

              interesting = TRUE;
            }

          else if (event->mask & IN_MOVED_FROM)
            {
              gboolean new;

              new = g_hash_table_insert (iks->unmatched_moves, GUINT_TO_POINTER (event->cookie), event);
              if G_UNLIKELY (!new)
                g_warning ("inotify: got IN_MOVED_FROM event with already-pending cookie %#x", event->cookie);

              interesting = TRUE;
            }

          g_queue_push_tail (&iks->queue, event);
        }

      if (buffer_len == 0)
        {
          /* We can end up reading nothing if we arrived here due to a
           * boredom timer but the stream of events stopped meanwhile.
           *
           * In that case, we need to switch back to polling the file
           * descriptor in the usual way.
           */
          g_assert (iks->is_bored);
          interesting = TRUE;
        }

      if (buffer != stack_buffer)
        g_free (buffer);
    }

  while (ik_source_can_dispatch_now (iks, now))
    {
      ik_event_t *event;

      /* callback will free the event */
      event = g_queue_pop_head (&iks->queue);

      if (event->mask & IN_MOVED_FROM && !event->pair)
        g_hash_table_remove (iks->unmatched_moves, GUINT_TO_POINTER (event->cookie));

      G_LOCK (inotify_lock);

      interesting |= (* user_callback) (event);

      G_UNLOCK (inotify_lock);
    }

  /* The queue gets blocked iff we have unmatched moves */
  g_assert ((iks->queue.length > 0) == (g_hash_table_size (iks->unmatched_moves) > 0));

  /* Here's where we decide what will wake us up next.
   *
   * If the last event was interesting then we will wake up on the fd or
   * when the timeout is reached on an unpaired move (if any).
   *
   * If the last event was uninteresting then we will wake up after the
   * shorter of the boredom sleep or any timeout for a unpaired move.
   */
  if (interesting)
    {
      if (iks->is_bored)
        {
          g_source_modify_unix_fd (source, iks->fd_tag, G_IO_IN);
          iks->is_bored = FALSE;
        }

      g_source_set_ready_time (source, ik_source_get_dispatch_time (iks));
    }
  else
    {
      guint64 dispatch_time = ik_source_get_dispatch_time (iks);
      guint64 boredom_time = now + BOREDOM_SLEEP_TIME;

      if (!iks->is_bored)
        {
          g_source_modify_unix_fd (source, iks->fd_tag, 0);
          iks->is_bored = TRUE;
        }

      g_source_set_ready_time (source, MIN (dispatch_time, boredom_time));
    }

  return TRUE;
}

static InotifyKernelSource *
ik_source_new (gboolean (* callback) (ik_event_t *event))
{
  static GSourceFuncs source_funcs = {
    NULL, NULL,
    ik_source_dispatch
    /* should have a finalize, but it will never happen */
  };
  InotifyKernelSource *iks;
  GSource *source;

  source = g_source_new (&source_funcs, sizeof (InotifyKernelSource));
  iks = (InotifyKernelSource *) source;

  g_source_set_name (source, "inotify kernel source");

  iks->unmatched_moves = g_hash_table_new (NULL, NULL);
  iks->fd = inotify_init1 (IN_CLOEXEC);

  if (iks->fd < 0)
    iks->fd = inotify_init ();

  if (iks->fd >= 0)
    {
      GError *error = NULL;

      g_unix_set_fd_nonblocking (iks->fd, TRUE, &error);
      g_assert_no_error (error);

      iks->fd_tag = g_source_add_unix_fd (source, iks->fd, G_IO_IN);
    }

  g_source_set_callback (source, (GSourceFunc) callback, NULL, NULL);

  g_source_attach (source, GLIB_PRIVATE_CALL (g_get_worker_context) ());

  return iks;
}

gboolean
_ik_startup (gboolean (*cb)(ik_event_t *event))
{
  if (g_once_init_enter (&inotify_source))
    g_once_init_leave (&inotify_source, ik_source_new (cb));

  return inotify_source->fd >= 0;
}

gint32
_ik_watch (const char *path,
           guint32     mask,
           int        *err)
{
  gint32 wd = -1;

  g_assert (path != NULL);
  g_assert (inotify_source && inotify_source->fd >= 0);

  wd = inotify_add_watch (inotify_source->fd, path, mask);

  if (wd < 0)
    {
      int e = errno;
      /* FIXME: debug msg failed to add watch */
      if (err)
        *err = e;
      return wd;
    }

  g_assert (wd >= 0);
  return wd;
}

int
_ik_ignore (const char *path,
            gint32      wd)
{
  g_assert (wd >= 0);
  g_assert (inotify_source && inotify_source->fd >= 0);

  if (inotify_rm_watch (inotify_source->fd, wd) < 0)
    {
      /* int e = errno; */
      /* failed to rm watch */
      return -1;
    }

  return 0;
}
