/* GStreamer
 * Copyright (C) 2004 Wim Taymans <wim@fluendo.com>
 * Copyright (C) 2011 Sebastian Dröge <sebastian.droege@collabora.co.uk>
 *
 * gstiterator.h: Base class for iterating datastructures.
 *
 * This 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.
 *
 * 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

/**
 * SECTION:gstiterator
 * @title: GstIterator
 * @short_description: Object to retrieve multiple elements in a threadsafe
 * way.
 * @see_also: #GstElement, #GstBin
 *
 * A GstIterator is used to retrieve multiple objects from another object in
 * a threadsafe way.
 *
 * Various GStreamer objects provide access to their internal structures using
 * an iterator.
 *
 * Note that if calling a GstIterator function results in your code receiving
 * a refcounted object (with, say, g_value_get_object()), the refcount for that
 * object will not be increased. Your code is responsible for taking a reference
 * if it wants to continue using it later.
 *
 * The basic use pattern of an iterator is as follows:
 * |[<!-- language="C" -->
 *   GstIterator *it = _get_iterator(object);
 *   GValue item = G_VALUE_INIT;
 *   done = FALSE;
 *   while (!done) {
 *     switch (gst_iterator_next (it, &amp;item)) {
 *       case GST_ITERATOR_OK:
 *         ...get/use/change item here...
 *         g_value_reset (&amp;item);
 *         break;
 *       case GST_ITERATOR_RESYNC:
 *         ...rollback changes to items...
 *         gst_iterator_resync (it);
 *         break;
 *       case GST_ITERATOR_ERROR:
 *         ...wrong parameters were given...
 *         done = TRUE;
 *         break;
 *       case GST_ITERATOR_DONE:
 *         done = TRUE;
 *         break;
 *     }
 *   }
 *   g_value_unset (&amp;item);
 *   gst_iterator_free (it);
 * ]|
 */

#include "gst_private.h"
#include <gst/gstiterator.h>

/**
 * gst_iterator_copy:
 * @it: a #GstIterator
 *
 * Copy the iterator and its state.
 *
 * Returns: a new copy of @it.
 */
GstIterator *
gst_iterator_copy (const GstIterator * it)
{
  GstIterator *copy;

  copy = g_slice_copy (it->size, it);
  if (it->copy)
    it->copy (it, copy);

  return copy;
}

G_DEFINE_BOXED_TYPE (GstIterator, gst_iterator,
    (GBoxedCopyFunc) gst_iterator_copy, (GBoxedFreeFunc) gst_iterator_free);

static void
gst_iterator_init (GstIterator * it,
    guint size,
    GType type,
    GMutex * lock,
    guint32 * master_cookie,
    GstIteratorCopyFunction copy,
    GstIteratorNextFunction next,
    GstIteratorItemFunction item,
    GstIteratorResyncFunction resync, GstIteratorFreeFunction free)
{
  it->size = size;
  it->type = type;
  it->lock = lock;
  it->master_cookie = master_cookie;
  it->cookie = *master_cookie;
  it->copy = copy;
  it->next = next;
  it->item = item;
  it->resync = resync;
  it->free = free;
  it->pushed = NULL;
}

/**
 * gst_iterator_new: (skip)
 * @size: the size of the iterator structure
 * @type: #GType of children
 * @lock: pointer to a #GMutex.
 * @master_cookie: pointer to a guint32 that is changed when the items in the
 *    iterator changed.
 * @copy: copy function
 * @next: function to get next item
 * @item: function to call on each item retrieved
 * @resync: function to resync the iterator
 * @free: function to free the iterator
 *
 * Create a new iterator. This function is mainly used for objects
 * implementing the next/resync/free function to iterate a data structure.
 *
 * For each item retrieved, the @item function is called with the lock
 * held. The @free function is called when the iterator is freed.
 *
 * Returns: the new #GstIterator.
 *
 * MT safe.
 */
GstIterator *
gst_iterator_new (guint size,
    GType type,
    GMutex * lock,
    guint32 * master_cookie,
    GstIteratorCopyFunction copy,
    GstIteratorNextFunction next,
    GstIteratorItemFunction item,
    GstIteratorResyncFunction resync, GstIteratorFreeFunction free)
{
  GstIterator *result;

  g_return_val_if_fail (size >= sizeof (GstIterator), NULL);
  g_return_val_if_fail (g_type_qname (type) != 0, NULL);
  g_return_val_if_fail (master_cookie != NULL, NULL);
  g_return_val_if_fail (next != NULL, NULL);
  g_return_val_if_fail (resync != NULL, NULL);
  g_return_val_if_fail (free != NULL, NULL);

  result = g_slice_alloc0 (size);
  gst_iterator_init (result, size, type, lock, master_cookie, copy, next, item,
      resync, free);

  return result;
}

/*
 * list iterator
 */
typedef struct _GstListIterator
{
  GstIterator iterator;
  GObject *owner;
  GList **orig;
  GList *list;                  /* pointer in list */

  void (*set_value) (GValue * value, gpointer item);
} GstListIterator;

static void
gst_list_iterator_copy (const GstListIterator * it, GstListIterator * copy)
{
  if (copy->owner)
    g_object_ref (copy->owner);
}

static GstIteratorResult
gst_list_iterator_next (GstListIterator * it, GValue * elem)
{
  gpointer data;

  if (it->list == NULL)
    return GST_ITERATOR_DONE;

  data = it->list->data;
  it->list = g_list_next (it->list);

  it->set_value (elem, data);

  return GST_ITERATOR_OK;
}

static void
gst_list_iterator_resync (GstListIterator * it)
{
  it->list = *it->orig;
}

static void
gst_list_iterator_free (GstListIterator * it)
{
  if (it->owner)
    g_object_unref (it->owner);
}

/**
 * gst_iterator_new_list: (skip)
 * @type: #GType of elements
 * @lock: pointer to a #GMutex protecting the list.
 * @master_cookie: pointer to a guint32 that is incremented when the list
 *     is changed.
 * @list: pointer to the list
 * @owner: object owning the list
 * @item: function to call on each item retrieved
 *
 * Create a new iterator designed for iterating @list.
 *
 * The list you iterate is usually part of a data structure @owner and is
 * protected with @lock.
 *
 * The iterator will use @lock to retrieve the next item of the list and it
 * will then call the @item function before releasing @lock again.
 *
 * When a concurrent update to the list is performed, usually by @owner while
 * holding @lock, @master_cookie will be updated. The iterator implementation
 * will notice the update of the cookie and will return %GST_ITERATOR_RESYNC to
 * the user of the iterator in the next call to gst_iterator_next().
 *
 * Returns: the new #GstIterator for @list.
 *
 * MT safe.
 */
GstIterator *
gst_iterator_new_list (GType type,
    GMutex * lock, guint32 * master_cookie, GList ** list, GObject * owner,
    GstIteratorItemFunction item)
{
  GstListIterator *result;
  gpointer set_value;

  if (g_type_is_a (type, G_TYPE_OBJECT)) {
    set_value = g_value_set_object;
  } else if (g_type_is_a (type, G_TYPE_BOXED)) {
    set_value = g_value_set_boxed;
  } else if (g_type_is_a (type, G_TYPE_POINTER)) {
    set_value = g_value_set_pointer;
  } else if (g_type_is_a (type, G_TYPE_STRING)) {
    set_value = g_value_set_string;
  } else {
    g_critical ("List iterators can only be created for lists containing "
        "instances of GObject, boxed types, pointer types and strings");
    return NULL;
  }

  /* no need to lock, nothing can change here */
  result = (GstListIterator *) gst_iterator_new (sizeof (GstListIterator),
      type,
      lock,
      master_cookie,
      (GstIteratorCopyFunction) gst_list_iterator_copy,
      (GstIteratorNextFunction) gst_list_iterator_next,
      (GstIteratorItemFunction) item,
      (GstIteratorResyncFunction) gst_list_iterator_resync,
      (GstIteratorFreeFunction) gst_list_iterator_free);

  result->owner = owner ? g_object_ref (owner) : NULL;
  result->orig = list;
  result->list = *list;
  result->set_value = set_value;

  return GST_ITERATOR (result);
}

static void
gst_iterator_pop (GstIterator * it)
{
  if (it->pushed) {
    gst_iterator_free (it->pushed);
    it->pushed = NULL;
  }
}

/**
 * gst_iterator_next:
 * @it: The #GstIterator to iterate
 * @elem: (out caller-allocates): pointer to hold next element
 *
 * Get the next item from the iterator in @elem.
 *
 * Only when this function returns %GST_ITERATOR_OK, @elem will contain a valid
 * value. @elem must have been initialized to the type of the iterator or
 * initialized to zeroes with g_value_unset(). The caller is responsible for
 * unsetting or resetting @elem with g_value_unset() or g_value_reset()
 * after usage.
 *
 * When this function returns %GST_ITERATOR_DONE, no more elements can be
 * retrieved from @it.
 *
 * A return value of %GST_ITERATOR_RESYNC indicates that the element list was
 * concurrently updated. The user of @it should call gst_iterator_resync() to
 * get the newly updated list.
 *
 * A return value of %GST_ITERATOR_ERROR indicates an unrecoverable fatal error.
 *
 * Returns: The result of the iteration. Unset @elem after usage.
 *
 * MT safe.
 */
GstIteratorResult
gst_iterator_next (GstIterator * it, GValue * elem)
{
  GstIteratorResult result;

  g_return_val_if_fail (it != NULL, GST_ITERATOR_ERROR);
  g_return_val_if_fail (elem != NULL, GST_ITERATOR_ERROR);
  g_return_val_if_fail (G_VALUE_TYPE (elem) == G_TYPE_INVALID
      || G_VALUE_HOLDS (elem, it->type), GST_ITERATOR_ERROR);

  if (G_VALUE_TYPE (elem) == G_TYPE_INVALID)
    g_value_init (elem, it->type);

restart:
  if (it->pushed) {
    result = gst_iterator_next (it->pushed, elem);
    if (result == GST_ITERATOR_DONE) {
      /* we are done with this iterator, pop it and
       * fallthrough iterating the main iterator again. */
      gst_iterator_pop (it);
    } else {
      return result;
    }
  }

  if (G_LIKELY (it->lock))
    g_mutex_lock (it->lock);

  if (G_UNLIKELY (*it->master_cookie != it->cookie)) {
    result = GST_ITERATOR_RESYNC;
    goto done;
  }

  result = it->next (it, elem);
  if (result == GST_ITERATOR_OK && it->item) {
    GstIteratorItem itemres;

    itemres = it->item (it, elem);
    switch (itemres) {
      case GST_ITERATOR_ITEM_SKIP:
        if (G_LIKELY (it->lock))
          g_mutex_unlock (it->lock);
        g_value_reset (elem);
        goto restart;
      case GST_ITERATOR_ITEM_END:
        result = GST_ITERATOR_DONE;
        g_value_reset (elem);
        break;
      case GST_ITERATOR_ITEM_PASS:
        break;
    }
  }

done:
  if (G_LIKELY (it->lock))
    g_mutex_unlock (it->lock);

  return result;
}

/**
 * gst_iterator_resync:
 * @it: The #GstIterator to resync
 *
 * Resync the iterator. this function is mostly called
 * after gst_iterator_next() returned %GST_ITERATOR_RESYNC.
 *
 * When an iterator was pushed on @it, it will automatically be popped again
 * with this function.
 *
 * MT safe.
 */
void
gst_iterator_resync (GstIterator * it)
{
  g_return_if_fail (it != NULL);

  gst_iterator_pop (it);

  if (G_LIKELY (it->lock))
    g_mutex_lock (it->lock);
  it->resync (it);
  it->cookie = *it->master_cookie;
  if (G_LIKELY (it->lock))
    g_mutex_unlock (it->lock);
}

/**
 * gst_iterator_free:
 * @it: The #GstIterator to free
 *
 * Free the iterator.
 *
 * MT safe.
 */
void
gst_iterator_free (GstIterator * it)
{
  g_return_if_fail (it != NULL);

  gst_iterator_pop (it);

  it->free (it);

  g_slice_free1 (it->size, it);
}

/**
 * gst_iterator_push:
 * @it: The #GstIterator to use
 * @other: The #GstIterator to push
 *
 * Pushes @other iterator onto @it. All calls performed on @it are
 * forwarded to @other. If @other returns %GST_ITERATOR_DONE, it is
 * popped again and calls are handled by @it again.
 *
 * This function is mainly used by objects implementing the iterator
 * next function to recurse into substructures.
 *
 * When gst_iterator_resync() is called on @it, @other will automatically be
 * popped.
 *
 * MT safe.
 */
void
gst_iterator_push (GstIterator * it, GstIterator * other)
{
  g_return_if_fail (it != NULL);
  g_return_if_fail (other != NULL);

  it->pushed = other;
}

typedef struct _GstIteratorFilter
{
  GstIterator iterator;
  GstIterator *slave;

  GMutex *master_lock;
  GCompareFunc func;
  GValue user_data;
  gboolean have_user_data;
} GstIteratorFilter;

static GstIteratorResult
filter_next (GstIteratorFilter * it, GValue * elem)
{
  GstIteratorResult result = GST_ITERATOR_ERROR;
  gboolean done = FALSE;
  GValue item = { 0, };

  while (G_LIKELY (!done)) {
    result = gst_iterator_next (it->slave, &item);
    switch (result) {
      case GST_ITERATOR_OK:
        if (G_LIKELY (it->master_lock))
          g_mutex_unlock (it->master_lock);
        if (it->func (&item, &it->user_data) == 0) {
          g_value_copy (&item, elem);
          done = TRUE;
        }
        g_value_reset (&item);
        if (G_LIKELY (it->master_lock))
          g_mutex_lock (it->master_lock);
        break;
      case GST_ITERATOR_RESYNC:
      case GST_ITERATOR_DONE:
        done = TRUE;
        break;
      default:
        g_assert_not_reached ();
        break;
    }
  }
  g_value_unset (&item);
  return result;
}

static void
filter_copy (const GstIteratorFilter * it, GstIteratorFilter * copy)
{
  copy->slave = gst_iterator_copy (it->slave);
  copy->master_lock = copy->slave->lock ? copy->slave->lock : it->master_lock;
  copy->slave->lock = NULL;

  if (it->have_user_data) {
    memset (&copy->user_data, 0, sizeof (copy->user_data));
    g_value_init (&copy->user_data, G_VALUE_TYPE (&it->user_data));
    g_value_copy (&it->user_data, &copy->user_data);
  }
}

static void
filter_resync (GstIteratorFilter * it)
{
  gst_iterator_resync (it->slave);
}

static void
filter_free (GstIteratorFilter * it)
{
  if (it->have_user_data)
    g_value_unset (&it->user_data);
  gst_iterator_free (it->slave);
}

/**
 * gst_iterator_filter:
 * @it: The #GstIterator to filter
 * @func: (scope call): the compare function to select elements
 * @user_data: (closure): user data passed to the compare function
 *
 * Create a new iterator from an existing iterator. The new iterator
 * will only return those elements that match the given compare function @func.
 * The first parameter that is passed to @func is the #GValue of the current
 * iterator element and the second parameter is @user_data. @func should
 * return 0 for elements that should be included in the filtered iterator.
 *
 * When this iterator is freed, @it will also be freed.
 *
 * Returns: (transfer full): a new #GstIterator.
 *
 * MT safe.
 */
GstIterator *
gst_iterator_filter (GstIterator * it, GCompareFunc func,
    const GValue * user_data)
{
  GstIteratorFilter *result;

  g_return_val_if_fail (it != NULL, NULL);
  g_return_val_if_fail (func != NULL, NULL);

  result = (GstIteratorFilter *) gst_iterator_new (sizeof (GstIteratorFilter),
      it->type, it->lock, it->master_cookie,
      (GstIteratorCopyFunction) filter_copy,
      (GstIteratorNextFunction) filter_next,
      (GstIteratorItemFunction) NULL,
      (GstIteratorResyncFunction) filter_resync,
      (GstIteratorFreeFunction) filter_free);

  result->master_lock = it->lock;
  it->lock = NULL;
  result->func = func;
  if (user_data) {
    g_value_init (&result->user_data, G_VALUE_TYPE (user_data));
    g_value_copy (user_data, &result->user_data);
    result->have_user_data = TRUE;
  } else {
    result->have_user_data = FALSE;
  }
  result->slave = it;

  return GST_ITERATOR (result);
}

/**
 * gst_iterator_fold:
 * @it: The #GstIterator to fold over
 * @func: (scope call): the fold function
 * @ret: the seed value passed to the fold function
 * @user_data: (closure): user data passed to the fold function
 *
 * Folds @func over the elements of @iter. That is to say, @func will be called
 * as @func (object, @ret, @user_data) for each object in @it. The normal use
 * of this procedure is to accumulate the results of operating on the objects in
 * @ret.
 *
 * This procedure can be used (and is used internally) to implement the
 * gst_iterator_foreach() and gst_iterator_find_custom() operations.
 *
 * The fold will proceed as long as @func returns %TRUE. When the iterator has no
 * more arguments, %GST_ITERATOR_DONE will be returned. If @func returns %FALSE,
 * the fold will stop, and %GST_ITERATOR_OK will be returned. Errors or resyncs
 * will cause fold to return %GST_ITERATOR_ERROR or %GST_ITERATOR_RESYNC as
 * appropriate.
 *
 * The iterator will not be freed.
 *
 * Returns: A #GstIteratorResult, as described above.
 *
 * MT safe.
 */
GstIteratorResult
gst_iterator_fold (GstIterator * it, GstIteratorFoldFunction func,
    GValue * ret, gpointer user_data)
{
  GValue item = { 0, };
  GstIteratorResult result;

  g_return_val_if_fail (it != NULL, GST_ITERATOR_ERROR);

  while (1) {
    result = gst_iterator_next (it, &item);
    switch (result) {
      case GST_ITERATOR_OK:
        if (!func (&item, ret, user_data))
          goto fold_done;

        g_value_reset (&item);
        break;
      case GST_ITERATOR_RESYNC:
      case GST_ITERATOR_ERROR:
        goto fold_done;
      case GST_ITERATOR_DONE:
        goto fold_done;
    }
  }

fold_done:

#if GLIB_CHECK_VERSION (2, 48, 0)
  g_value_unset (&item);
#else
  if (item.g_type != 0)
    g_value_unset (&item);
#endif

  return result;
}

typedef struct
{
  GstIteratorForeachFunction func;
  gpointer user_data;
} ForeachFoldData;

static gboolean
foreach_fold_func (const GValue * item, GValue * unused, ForeachFoldData * data)
{
  data->func (item, data->user_data);
  return TRUE;
}

/**
 * gst_iterator_foreach:
 * @it: The #GstIterator to iterate
 * @func: (scope call): the function to call for each element.
 * @user_data: (closure): user data passed to the function
 *
 * Iterate over all element of @it and call the given function @func for
 * each element.
 *
 * Returns: the result call to gst_iterator_fold(). The iterator will not be
 * freed.
 *
 * MT safe.
 */
GstIteratorResult
gst_iterator_foreach (GstIterator * it, GstIteratorForeachFunction func,
    gpointer user_data)
{
  ForeachFoldData data;

  data.func = func;
  data.user_data = user_data;

  return gst_iterator_fold (it, (GstIteratorFoldFunction) foreach_fold_func,
      NULL, &data);
}

typedef struct
{
  GCompareFunc func;
  gpointer user_data;
  gboolean found;
} FindCustomFoldData;

static gboolean
find_custom_fold_func (const GValue * item, GValue * ret,
    FindCustomFoldData * data)
{
  if (data->func (item, data->user_data) == 0) {
    data->found = TRUE;
    g_value_copy (item, ret);
    return FALSE;
  } else {
    return TRUE;
  }
}

/**
 * gst_iterator_find_custom:
 * @it: The #GstIterator to iterate
 * @func: (scope call): the compare function to use
 * @elem: (out): pointer to a #GValue where to store the result
 * @user_data: (closure): user data passed to the compare function
 *
 * Find the first element in @it that matches the compare function @func.
 * @func should return 0 when the element is found. The first parameter
 * to @func will be the current element of the iterator and the
 * second parameter will be @user_data.
 * The result will be stored in @elem if a result is found.
 *
 * The iterator will not be freed.
 *
 * This function will return %FALSE if an error happened to the iterator
 * or if the element wasn't found.
 *
 * Returns: Returns %TRUE if the element was found, else %FALSE.
 *
 * MT safe.
 */
gboolean
gst_iterator_find_custom (GstIterator * it, GCompareFunc func,
    GValue * elem, gpointer user_data)
{
  GstIteratorResult res;
  FindCustomFoldData data;

  g_return_val_if_fail (G_VALUE_TYPE (elem) == G_TYPE_INVALID
      || G_VALUE_HOLDS (elem, it->type), GST_ITERATOR_ERROR);

  if (G_VALUE_TYPE (elem) == G_TYPE_INVALID)
    g_value_init (elem, it->type);

  data.func = func;
  data.user_data = user_data;
  data.found = FALSE;

  do {
    res =
        gst_iterator_fold (it, (GstIteratorFoldFunction) find_custom_fold_func,
        elem, &data);
    if (res == GST_ITERATOR_RESYNC)
      gst_iterator_resync (it);
  } while (res == GST_ITERATOR_RESYNC);

  if (!data.found)
    g_value_unset (elem);

  return data.found;
}

typedef struct
{
  GstIterator parent;
  GValue object;
  gboolean visited;
  gboolean empty;
} GstSingleObjectIterator;

static guint32 _single_object_dummy_cookie = 0;

static void
gst_single_object_iterator_copy (const GstSingleObjectIterator * it,
    GstSingleObjectIterator * copy)
{
  if (!it->empty) {
    memset (&copy->object, 0, sizeof (copy->object));
    g_value_init (&copy->object, it->parent.type);
    g_value_copy (&it->object, &copy->object);
  }
}

static GstIteratorResult
gst_single_object_iterator_next (GstSingleObjectIterator * it, GValue * result)
{
  if (it->visited || it->empty)
    return GST_ITERATOR_DONE;

  g_value_copy (&it->object, result);
  it->visited = TRUE;

  return GST_ITERATOR_OK;
}

static void
gst_single_object_iterator_resync (GstSingleObjectIterator * it)
{
  it->visited = FALSE;
}

static void
gst_single_object_iterator_free (GstSingleObjectIterator * it)
{
  if (!it->empty)
    g_value_unset (&it->object);
}

/**
 * gst_iterator_new_single:
 * @type: #GType of the passed object
 * @object: object that this iterator should return
 *
 * This #GstIterator is a convenient iterator for the common
 * case where a #GstIterator needs to be returned but only
 * a single object has to be considered. This happens often
 * for the #GstPadIterIntLinkFunction.
 *
 * Returns: the new #GstIterator for @object.
 */
GstIterator *
gst_iterator_new_single (GType type, const GValue * object)
{
  GstSingleObjectIterator *result;

  result = (GstSingleObjectIterator *)
      gst_iterator_new (sizeof (GstSingleObjectIterator),
      type, NULL, &_single_object_dummy_cookie,
      (GstIteratorCopyFunction) gst_single_object_iterator_copy,
      (GstIteratorNextFunction) gst_single_object_iterator_next,
      (GstIteratorItemFunction) NULL,
      (GstIteratorResyncFunction) gst_single_object_iterator_resync,
      (GstIteratorFreeFunction) gst_single_object_iterator_free);

  if (object) {
    g_value_init (&result->object, type);
    g_value_copy (object, &result->object);
    result->empty = FALSE;
  } else {
    result->empty = TRUE;
  }
  result->visited = FALSE;

  return GST_ITERATOR (result);
}
