/*
 * GStreamer
 *
 *  Copyright 2013 Collabora Ltd
 *   @author: Olivier Crete <olivier.crete@collabora.com>
 *
 * 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 */

/**
 * SECTION:gstinsertbin
 * @short_description: A #GstBin to insertally link filter-like elements.
 *
 * This element is a #GstBin that has a single source and sink pad. It allows
 * the user (the application) to easily add and remove filter-like element
 * (that has a single source and sink pad), to the pipeline while it is running.
 * It features a fully asynchronous API inspired by GLib's GAsyncResult based
 * APIs.
 *
 * Each operation (addition or removal) can take a callback, this callback
 * is guaranteed to be called. Unlike GIO, there is no guarantee about where
 * this callback will be called from, it could be called before the action
 * returns or it could be called later from another thread. The signature of
 * this callback GstInsertBinCallback().
 *
 * Since: 1.2
 */

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

#include "gstinsertbin.h"


GST_DEBUG_CATEGORY_STATIC (insert_bin_debug);
#define GST_CAT_DEFAULT (insert_bin_debug)


static GstStaticPadTemplate gst_insert_bin_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS_ANY);

static GstStaticPadTemplate gst_insert_bin_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS_ANY);

enum
{
  SIG_PREPEND,
  SIG_APPEND,
  SIG_INSERT_BEFORE,
  SIG_INSERT_AFTER,
  SIG_REMOVE,
  LAST_SIGNAL
};

static guint signals[LAST_SIGNAL];

enum
{
  PROP_0,
};

struct _GstInsertBinPrivate
{
  GstPad *srcpad;
  GstPad *sinkpad;

  GQueue change_queue;
};

typedef enum
{
  GST_INSERT_BIN_ACTION_ADD,
  GST_INSERT_BIN_ACTION_REMOVE
} GstInsertBinAction;


typedef enum
{
  DIRECTION_NONE,
  DIRECTION_AFTER,
  DIRECTION_BEFORE
} GstInsertBinDirection;

struct ChangeData
{
  GstElement *element;
  GstInsertBinAction action;
  GstElement *sibling;
  GstInsertBinDirection direction;

  GstInsertBinCallback callback;
  gpointer user_data;
};

static void gst_insert_bin_dispose (GObject * object);


static void gst_insert_bin_do_change (GstInsertBin * self, GstPad * pad);
static GstPadProbeReturn pad_blocked_cb (GstPad * pad, GstPadProbeInfo * info,
    gpointer user_data);

G_DEFINE_TYPE (GstInsertBin, gst_insert_bin, GST_TYPE_BIN);

static void
gst_insert_bin_class_init (GstInsertBinClass * klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  GstElementClass *gstelement_class = (GstElementClass *) klass;

  GST_DEBUG_CATEGORY_INIT (insert_bin_debug, "insertbin", 0, "Insert Bin");

  g_type_class_add_private (klass, sizeof (GstInsertBinPrivate));

  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&gst_insert_bin_src_template));
  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&gst_insert_bin_sink_template));
  gst_element_class_set_static_metadata (gstelement_class, "Insert Bin",
      "Generic/Bin/Filter",
      "Auto-links filter style elements insertally",
      "Olivier Crete <olivier.crete@collabora.com>");

  gobject_class->dispose = gst_insert_bin_dispose;

  /**
   * GstInsertBin::prepend:
   * @element: the #GstElement to add
   * @callback: the callback to call when the element has been added or not, or
   *  %NULL
   * @user_data: The data to pass to the callback
   * @user_data2: The user data of the signal (ignored)
   *
   * This action signal adds the filter like element before any other element
   * in the bin.
   *
   * Same as gst_insert_bin_prepend()
   */
  signals[SIG_PREPEND] = g_signal_new_class_handler ("prepend",
      G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
      G_CALLBACK (gst_insert_bin_prepend),
      NULL, NULL, NULL,
      G_TYPE_NONE, 3, GST_TYPE_ELEMENT, G_TYPE_POINTER, G_TYPE_POINTER);

  /**
   * GstInsertBin::append:
   * @element: the #GstElement to add
   * @callback: the callback to call when the element has been added or not, or
   *  %NULL
   * @user_data: The data to pass to the callback
   * @user_data2: The user data of the signal (ignored)
   *
   * This action signal adds the filter like element after any other element
   * in the bin.
   *
   * Same as gst_insert_bin_append()
   */
  signals[SIG_APPEND] = g_signal_new_class_handler ("append",
      G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
      G_CALLBACK (gst_insert_bin_append),
      NULL, NULL, NULL,
      G_TYPE_NONE, 3, GST_TYPE_ELEMENT, G_TYPE_POINTER, G_TYPE_POINTER);

  /**
   * GstInsertBin::insert-before:
   * @element: the #GstElement to add
   * @sibling: the #GstElement to add @element before
   * @callback: the callback to call when the element has been added or not, or
   *  %NULL
   * @user_data: The data to pass to the callback
   * @user_data2: The user data of the signal (ignored)
   *
   * This action signal adds the filter like element before the @sibling
   * element in the bin.
   *
   * Same as gst_insert_bin_insert_before()
   */
  signals[SIG_INSERT_BEFORE] = g_signal_new_class_handler ("insert-before",
      G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
      G_CALLBACK (gst_insert_bin_insert_before),
      NULL, NULL, NULL,
      G_TYPE_NONE, 4, GST_TYPE_ELEMENT, GST_TYPE_ELEMENT,
      G_TYPE_POINTER, G_TYPE_POINTER);

  /**
   * GstInsertBin::insert-after:
   * @element: the #GstElement to add
   * @sibling: the #GstElement to add @element after
   * @callback: the callback to call when the element has been added or not, or
   *  %NULL
   * @user_data: The data to pass to the callback
   * @user_data2: The user data of the signal (ignored)
   *
   * This action signal adds the filter like element after the @sibling
   * element in the bin.
   * element in the bin.
   *
   * Same as gst_insert_bin_insert_after()
   */
  signals[SIG_INSERT_AFTER] = g_signal_new_class_handler ("insert-after",
      G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
      G_CALLBACK (gst_insert_bin_insert_after),
      NULL, NULL, NULL,
      G_TYPE_NONE, 4, GST_TYPE_ELEMENT, GST_TYPE_ELEMENT,
      G_TYPE_POINTER, G_TYPE_POINTER);


  /**
   * GstInsertBin::remove:
   * @element: the #GstElement to remove
   * @callback: the callback to call when the element has been removed or not,
   * or %NULL
   * @user_data: The data to pass to the callback
   * @user_data2: The user data of the signal (ignored)
   *
   * This action signal removed the filter like element from the bin.
   *
   * Same as gst_insert_bin_remove()
   */
  signals[SIG_REMOVE] = g_signal_new_class_handler ("remove",
      G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
      G_CALLBACK (gst_insert_bin_remove),
      NULL, NULL, NULL,
      G_TYPE_NONE, 3, GST_TYPE_ELEMENT, G_TYPE_POINTER, G_TYPE_POINTER);
}

static void
change_data_free (struct ChangeData *data)
{
  gst_object_unref (data->element);
  if (data->sibling)
    gst_object_unref (data->sibling);
  g_slice_free (struct ChangeData, data);
}


static void
gst_insert_bin_change_data_complete (GstInsertBin * self,
    struct ChangeData *data, gboolean success)
{
  if (data->callback)
    data->callback (self, data->element, success, data->user_data);

  change_data_free (data);
}

static void
gst_insert_bin_init (GstInsertBin * self)
{
  GstProxyPad *internal;

  self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GST_TYPE_INSERT_BIN,
      GstInsertBinPrivate);

  g_queue_init (&self->priv->change_queue);

  self->priv->sinkpad = gst_ghost_pad_new_no_target_from_template ("sink",
      gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (self),
          "sink"));
  gst_element_add_pad (GST_ELEMENT (self), self->priv->sinkpad);

  internal = gst_proxy_pad_get_internal (GST_PROXY_PAD (self->priv->sinkpad));
  self->priv->srcpad = gst_ghost_pad_new_from_template ("src",
      GST_PAD (internal),
      gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (self), "src"));
  gst_object_unref (internal);
  gst_element_add_pad (GST_ELEMENT (self), self->priv->srcpad);
}

static void
gst_insert_bin_dispose (GObject * object)
{
  GstInsertBin *self = GST_INSERT_BIN (object);
  struct ChangeData *data;

  while ((data = g_queue_pop_head (&self->priv->change_queue)))
    gst_insert_bin_change_data_complete (self, data, FALSE);

  gst_ghost_pad_set_target (GST_GHOST_PAD (self->priv->srcpad), NULL);
  gst_ghost_pad_set_target (GST_GHOST_PAD (self->priv->sinkpad), NULL);

  G_OBJECT_CLASS (gst_insert_bin_parent_class)->dispose (object);
}

static gboolean
validate_element (GstInsertBin * self, GstElement * element)
{
  gboolean valid = TRUE;

  GST_OBJECT_LOCK (element);
  if (element->numsrcpads != 1 || element->numsinkpads != 1) {
    GST_WARNING_OBJECT (self,
        "Element does not have a single src and sink pad");
    valid = FALSE;
  }

  if (GST_OBJECT_PARENT (element) != NULL) {
    GST_WARNING_OBJECT (self, "Element already has a parent");
    valid = FALSE;
  }
  GST_OBJECT_UNLOCK (element);

  return valid;
}

static GstPad *
get_single_pad (GstElement * element, GstPadDirection direction)
{
  GstPad *pad = NULL;

  GST_OBJECT_LOCK (element);
  if (direction == GST_PAD_SRC) {
    if (element->numsrcpads == 1)
      pad = element->srcpads->data;
  } else {
    if (element->numsinkpads == 1)
      pad = element->sinkpads->data;
  }

  if (pad)
    gst_object_ref (pad);
  GST_OBJECT_UNLOCK (element);

  return pad;
}

static gboolean
is_right_direction_for_block (GstPad * pad)
{
  gboolean right_direction;

  GST_OBJECT_LOCK (pad);
  switch (pad->mode) {
    case GST_PAD_MODE_NONE:
      right_direction = TRUE;
      break;
    case GST_PAD_MODE_PUSH:
      right_direction = (pad->direction == GST_PAD_SRC);
      break;
    case GST_PAD_MODE_PULL:
      right_direction = (pad->direction == GST_PAD_SINK);
      break;
    default:
      right_direction = FALSE;
      g_assert_not_reached ();
  }
  GST_OBJECT_UNLOCK (pad);

  return right_direction;
}

static void
gst_insert_bin_block_pad_unlock (GstInsertBin * self)
{
  struct ChangeData *data;
  GstPad *pad;
  GstPadProbeType probetype;

again:

  data = g_queue_peek_head (&self->priv->change_queue);
  if (!data) {
    GST_OBJECT_UNLOCK (self);
    return;
  }

  if (data->action == GST_INSERT_BIN_ACTION_ADD &&
      !validate_element (self, data->element))
    goto error;

  if (data->action == GST_INSERT_BIN_ACTION_ADD) {
    if (data->sibling) {
      if (data->direction == DIRECTION_BEFORE)
        pad = get_single_pad (data->sibling, GST_PAD_SINK);
      else
        pad = get_single_pad (data->sibling, GST_PAD_SRC);
    } else {
      if (data->direction == DIRECTION_BEFORE)
        pad = (GstPad *)
            gst_proxy_pad_get_internal (GST_PROXY_PAD (self->priv->srcpad));
      else
        pad = (GstPad *)
            gst_proxy_pad_get_internal (GST_PROXY_PAD (self->priv->sinkpad));
    }

    if (!pad) {
      GST_WARNING_OBJECT (self, "Can not obtain a sibling pad to block"
          " before adding");
      goto error;
    }

    if (!is_right_direction_for_block (pad)) {
      GstPad *peer = gst_pad_get_peer (pad);

      if (peer) {
        gst_object_unref (pad);
        pad = peer;
      }
    }
  } else {
    GstPad *element_pad;

    element_pad = get_single_pad (data->element, GST_PAD_SINK);
    if (!element_pad) {
      GST_WARNING_OBJECT (self, "Can not obtain the element's sink pad");
      goto error;
    }

    if (!is_right_direction_for_block (element_pad)) {
      pad = gst_pad_get_peer (element_pad);
    } else {
      gst_object_unref (element_pad);

      element_pad = get_single_pad (data->element, GST_PAD_SRC);
      if (!element_pad) {
        GST_WARNING_OBJECT (self, "Can not obtain the element's src pad");
        goto error;
      }

      pad = gst_pad_get_peer (element_pad);
    }
    gst_object_unref (element_pad);

    if (!pad) {
      GST_WARNING_OBJECT (self, "Can not obtain a sibling pad for removing");
      goto error;
    }
  }

  if (GST_PAD_IS_SRC (pad))
    probetype = GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM;
  else
    probetype = GST_PAD_PROBE_TYPE_BLOCK_UPSTREAM;

  GST_OBJECT_UNLOCK (self);
  gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_IDLE | probetype, pad_blocked_cb,
      self, NULL);
  gst_object_unref (pad);
  return;

error:
  g_queue_pop_head (&self->priv->change_queue);
  gst_insert_bin_change_data_complete (self, data, FALSE);
  goto again;
}

static GstPadProbeReturn
wait_and_drop_eos_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
{
  GstPad *peer;

  if (GST_EVENT_TYPE (GST_PAD_PROBE_INFO_EVENT (info)) != GST_EVENT_EOS)
    return GST_PAD_PROBE_PASS;

  peer = gst_pad_get_peer (pad);
  if (peer) {
    gst_pad_unlink (pad, peer);
    gst_object_unref (peer);
  }

  return GST_PAD_PROBE_DROP;
}

static void
gst_insert_bin_do_change (GstInsertBin * self, GstPad * pad)
{
  struct ChangeData *data;

  GST_OBJECT_LOCK (self);

  if (!is_right_direction_for_block (pad)) {
    GST_WARNING_OBJECT (self, "Block pad does not have the expected direction");
    goto next;
  }

  while ((data = g_queue_pop_head (&self->priv->change_queue)) != NULL) {
    GstPad *peer = NULL;
    GstPad *other_peer = NULL;

    GST_OBJECT_UNLOCK (self);


    if (data->action == GST_INSERT_BIN_ACTION_ADD &&
        !validate_element (self, data->element))
      goto error;

    peer = gst_pad_get_peer (pad);

    if (peer == NULL) {
      GST_WARNING_OBJECT (self, "Blocked pad has no peer");
      goto error;
    }

    if (data->action == GST_INSERT_BIN_ACTION_ADD) {
      GstPad *srcpad = NULL, *sinkpad = NULL;
      GstPad *peersrcpad, *peersinkpad;

      /* First let's make sure we have the right pad */
      if (data->sibling) {
        GstElement *parent = NULL;
        GstPad *siblingpad;

        if ((gst_pad_get_direction (pad) == GST_PAD_SRC &&
                data->direction == DIRECTION_BEFORE) ||
            (gst_pad_get_direction (pad) == GST_PAD_SINK &&
                data->direction == DIRECTION_AFTER))
          siblingpad = peer;
        else
          siblingpad = pad;

        parent = gst_pad_get_parent_element (siblingpad);
        if (parent != NULL)
          gst_object_unref (parent);

        if (parent != data->sibling)
          goto retry;
      } else {
        GstObject *parent;
        GstPad *ghost;
        GstPad *proxypad;

        if (data->direction == DIRECTION_BEFORE) {
          ghost = self->priv->srcpad;
          if (gst_pad_get_direction (pad) == GST_PAD_SINK)
            proxypad = pad;
          else
            proxypad = peer;
        } else {
          ghost = self->priv->sinkpad;
          if (gst_pad_get_direction (pad) == GST_PAD_SINK)
            proxypad = peer;
          else
            proxypad = pad;
        }

        if (!GST_IS_PROXY_PAD (proxypad))
          goto retry;
        parent = gst_pad_get_parent (proxypad);
        if (!parent)
          goto retry;
        gst_object_unref (parent);
        if (GST_PAD_CAST (parent) != ghost)
          goto retry;
      }

      if (gst_pad_get_direction (pad) == GST_PAD_SRC) {
        peersrcpad = pad;
        peersinkpad = peer;
      } else {
        peersrcpad = peer;
        peersinkpad = pad;
      }

      if (GST_IS_PROXY_PAD (peersrcpad)) {
        GstObject *parent = gst_pad_get_parent (peersrcpad);

        if (GST_PAD_CAST (parent) == self->priv->sinkpad)
          peersrcpad = NULL;

        if (parent)
          gst_object_unref (parent);
      }

      if (GST_IS_PROXY_PAD (peersinkpad)) {
        GstObject *parent = gst_pad_get_parent (peersinkpad);

        if (GST_PAD_CAST (parent) == self->priv->srcpad)
          peersinkpad = NULL;

        if (parent)
          gst_object_unref (parent);
      }

      if (peersinkpad && peersrcpad) {
        gst_pad_unlink (peersrcpad, peersinkpad);
      } else {
        if (!peersinkpad)
          gst_ghost_pad_set_target (GST_GHOST_PAD (self->priv->srcpad), NULL);
        if (!peersrcpad)
          gst_ghost_pad_set_target (GST_GHOST_PAD (self->priv->sinkpad), NULL);
      }

      srcpad = get_single_pad (data->element, GST_PAD_SRC);
      sinkpad = get_single_pad (data->element, GST_PAD_SINK);

      if (srcpad == NULL || sinkpad == NULL) {
        GST_WARNING_OBJECT (self, "Can not get element src or sink pad");
        goto error;
      }

      if (!gst_bin_add (GST_BIN (self), data->element)) {
        GST_WARNING_OBJECT (self, "Can not add element to bin");
        goto error;
      }

      if (peersrcpad) {
        if (GST_PAD_LINK_FAILED (gst_pad_link (peersrcpad, sinkpad))) {
          GST_WARNING_OBJECT (self, "Can not link sibling's %s:%s pad"
              " to element's %s:%s pad", GST_DEBUG_PAD_NAME (peersrcpad),
              GST_DEBUG_PAD_NAME (sinkpad));
          goto error;
        }
      } else {
        if (!gst_ghost_pad_set_target (GST_GHOST_PAD (self->priv->sinkpad),
                sinkpad)) {
          GST_WARNING_OBJECT (self, "Can not set %s:%s as target for %s:%s",
              GST_DEBUG_PAD_NAME (sinkpad),
              GST_DEBUG_PAD_NAME (self->priv->sinkpad));
          goto error;
        }
      }

      if (peersinkpad) {
        if (GST_PAD_LINK_FAILED (gst_pad_link (srcpad, peersinkpad))) {
          GST_WARNING_OBJECT (self, "Can not link element's %s:%s pad"
              " to sibling's %s:%s pad", GST_DEBUG_PAD_NAME (srcpad),
              GST_DEBUG_PAD_NAME (peersinkpad));
          goto error;
        }
      } else {
        if (!gst_ghost_pad_set_target (GST_GHOST_PAD (self->priv->srcpad),
                srcpad)) {
          GST_WARNING_OBJECT (self, "Can not set %s:%s as target for %s:%s",
              GST_DEBUG_PAD_NAME (srcpad),
              GST_DEBUG_PAD_NAME (self->priv->srcpad));
          goto error;
        }
      }

      gst_object_unref (srcpad);
      gst_object_unref (sinkpad);

      if (!gst_element_sync_state_with_parent (data->element)) {
        GST_WARNING_OBJECT (self, "Can not sync element's state with parent");
        goto error;
      }
    } else {
      GstElement *parent = NULL;
      GstPad *other_pad;
      GstCaps *caps = NULL, *peercaps = NULL;
      gboolean can_intersect;
      gboolean success;

      parent = gst_pad_get_parent_element (peer);
      if (parent != NULL)
        gst_object_unref (parent);

      if (parent != data->element)
        goto retry;

      if (gst_pad_get_direction (peer) == GST_PAD_SRC)
        other_pad = get_single_pad (data->element, GST_PAD_SINK);
      else
        other_pad = get_single_pad (data->element, GST_PAD_SRC);

      if (!other_pad) {
        GST_WARNING_OBJECT (self, "Can not get element's other pad");
        goto error;
      }

      other_peer = gst_pad_get_peer (other_pad);
      gst_object_unref (other_pad);

      if (!other_peer) {
        GST_WARNING_OBJECT (self, "Can not get element's other peer");
        goto error;
      }

      /* Get the negotiated caps for the source pad peer,
       * because renegotiation while the pipeline is playing doesn't work
       * that fast.
       */
      if (gst_pad_get_direction (pad) == GST_PAD_SRC)
        caps = gst_pad_get_current_caps (pad);
      else
        peercaps = gst_pad_get_current_caps (other_peer);
      if (!caps)
        caps = gst_pad_query_caps (pad, NULL);
      if (!peercaps)
        peercaps = gst_pad_query_caps (other_peer, NULL);
      can_intersect = gst_caps_can_intersect (caps, peercaps);
      gst_caps_unref (caps);
      gst_caps_unref (peercaps);

      if (!can_intersect) {
        GST_WARNING_OBJECT (self, "Pads are incompatible without the element");
        goto error;
      }

      if (gst_pad_get_direction (other_peer) == GST_PAD_SRC &&
          gst_pad_is_active (other_peer)) {
        gulong probe_id;

        probe_id = gst_pad_add_probe (other_peer,
            GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
            wait_and_drop_eos_cb, NULL, NULL);
        gst_pad_send_event (peer, gst_event_new_eos ());
        gst_pad_remove_probe (other_peer, probe_id);
      }

      gst_element_set_locked_state (data->element, TRUE);
      gst_element_set_state (data->element, GST_STATE_NULL);
      if (!gst_bin_remove (GST_BIN (self), data->element)) {
        GST_WARNING_OBJECT (self, "Element removal rejected");
        goto error;
      }
      gst_element_set_locked_state (data->element, FALSE);

      if (gst_pad_get_direction (pad) == GST_PAD_SRC)
        success = GST_PAD_LINK_SUCCESSFUL (gst_pad_link_full (pad, other_peer,
                GST_PAD_LINK_CHECK_HIERARCHY |
                GST_PAD_LINK_CHECK_TEMPLATE_CAPS));
      else
        success = GST_PAD_LINK_SUCCESSFUL (gst_pad_link_full (other_peer, pad,
                GST_PAD_LINK_CHECK_HIERARCHY |
                GST_PAD_LINK_CHECK_TEMPLATE_CAPS));
      gst_object_unref (other_peer);
      other_peer = NULL;

      if (!success) {
        GST_ERROR_OBJECT (self, "Could not re-link after the element's"
            " removal");
        goto error;
      }
    }


    gst_insert_bin_change_data_complete (self, data, TRUE);
    gst_object_unref (peer);

    GST_OBJECT_LOCK (self);
    continue;
  done:
    if (other_peer != NULL)
      gst_object_unref (other_peer);

    if (peer != NULL)
      gst_object_unref (peer);
    break;
  retry:
    GST_OBJECT_LOCK (self);
    g_queue_push_head (&self->priv->change_queue, data);
    goto done;
  error:
    /* Handle error */
    gst_insert_bin_change_data_complete (self, data, FALSE);
    GST_OBJECT_LOCK (self);
    goto done;
  }

next:
  gst_insert_bin_block_pad_unlock (self);
}



static GstPadProbeReturn
pad_blocked_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
{
  GstInsertBin *self = GST_INSERT_BIN (user_data);

  g_assert (GST_PAD_PROBE_INFO_TYPE (info) &
      (GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_IDLE));

  gst_insert_bin_do_change (self, pad);

  return GST_PAD_PROBE_REMOVE;
}

static void
gst_insert_bin_add_operation (GstInsertBin * self,
    GstElement * element, GstInsertBinAction action, GstElement * sibling,
    GstInsertBinDirection direction, GstInsertBinCallback callback,
    gpointer user_data)
{
  struct ChangeData *data = g_slice_new (struct ChangeData);
  gboolean block_pad;

  data->element = element;
  data->action = action;
  data->sibling = sibling;
  if (data->sibling)
    gst_object_ref (data->sibling);
  data->direction = direction;
  data->callback = callback;
  data->user_data = user_data;

  GST_OBJECT_LOCK (self);
  block_pad = g_queue_is_empty (&self->priv->change_queue);
  g_queue_push_tail (&self->priv->change_queue, data);

  if (block_pad)
    gst_insert_bin_block_pad_unlock (self);
  else
    GST_OBJECT_UNLOCK (self);
}

static void
gst_insert_bin_add (GstInsertBin * self, GstElement * element,
    GstElement * sibling, GstInsertBinDirection direction,
    GstInsertBinCallback callback, gpointer user_data)
{
  gst_object_ref_sink (element);

  if (!validate_element (self, element))
    goto reject;

  if (sibling) {
    gboolean is_parent;

    GST_OBJECT_LOCK (sibling);
    is_parent = (GST_OBJECT_PARENT (sibling) == GST_OBJECT_CAST (self));
    GST_OBJECT_UNLOCK (sibling);

    if (!is_parent)
      goto reject;
  }


  gst_insert_bin_add_operation (self, element, GST_INSERT_BIN_ACTION_ADD,
      sibling, direction, callback, user_data);
  return;

reject:
  if (callback)
    callback (self, element, FALSE, user_data);
  gst_object_unref (element);
}


/**
 * gst_insert_bin_prepend:
 * @element: the #GstElement to add
 * @callback: (scope async): the callback to call when the element has been
 *  added or not, or %NULL
 * @user_data: The data to pass to the callback
 *
 * This action signal adds the filter like element before any other element
 * in the bin.
 *
 * Same as the #GstInsertBin::prepend signal.
 *
 * Since: 1.2
 */

void
gst_insert_bin_prepend (GstInsertBin * self, GstElement * element,
    GstInsertBinCallback callback, gpointer user_data)
{
  g_return_if_fail (GST_IS_ELEMENT (element));

  gst_insert_bin_add (self, element, NULL, DIRECTION_AFTER,
      callback, user_data);
}

/**
 * gst_insert_bin_append:
 * @element: the #GstElement to add
 * @callback: (scope async): the callback to call when the element has been
 *  added or not, or %NULL
 * @user_data: The data to pass to the callback
 *
 * This action signal adds the filter like element after any other element
 * in the bin.
 *
 * Same as the #GstInsertBin::append signal.
 *
 * Since: 1.2
 */

void
gst_insert_bin_append (GstInsertBin * self, GstElement * element,
    GstInsertBinCallback callback, gpointer user_data)
{
  g_return_if_fail (GST_IS_ELEMENT (element));

  gst_insert_bin_add (self, element, NULL, DIRECTION_BEFORE,
      callback, user_data);
}

/**
 * gst_insert_bin_insert_before:
 * @element: the #GstElement to add
 * @sibling: the #GstElement to add @element before
 * @callback: (scope async): the callback to call when the element has been
 *  added or not, or %NULL
 * @user_data: The data to pass to the callback
 *
 * This action signal adds the filter like element before the @sibling
 * element in the bin.
 *
 * Same as the #GstInsertBin::insert-before signal.
 *
 * Since: 1.2
 */
void
gst_insert_bin_insert_before (GstInsertBin * self, GstElement * element,
    GstElement * sibling, GstInsertBinCallback callback, gpointer user_data)
{
  g_return_if_fail (GST_IS_ELEMENT (element));
  g_return_if_fail (GST_IS_ELEMENT (sibling));

  gst_insert_bin_add (self, element, sibling, DIRECTION_BEFORE,
      callback, user_data);
}

/**
 * gst_insert_bin_insert_after:
 * @element: the #GstElement to add
 * @sibling: the #GstElement to add @element after
 * @callback: (scope async): the callback to call when the element has been
 *  added or not, or %NULL
 * @user_data: The data to pass to the callback
 *
 * This action signal adds the filter like element after the @sibling
 * element in the bin.
 *
 * Same as the #GstInsertBin::insert-after signal.
 *
 * Since: 1.2
 */
void
gst_insert_bin_insert_after (GstInsertBin * self, GstElement * element,
    GstElement * sibling, GstInsertBinCallback callback, gpointer user_data)
{
  g_return_if_fail (GST_IS_ELEMENT (element));
  g_return_if_fail (GST_IS_ELEMENT (sibling));

  gst_insert_bin_add (self, element, sibling, DIRECTION_AFTER,
      callback, user_data);
}

/**
 * gst_insert_bin_remove:
 * @element: the #GstElement to remove
 * @callback: (scope async): the callback to call when the element has been
 *  removed or not, or %NULL
 * @user_data: The data to pass to the callback
 *
 * This action signal removed the filter like element from the bin.
 *
 * Same as the #GstInsertBin::remove signal.
 *
 * Since: 1.2
 */

void
gst_insert_bin_remove (GstInsertBin * self, GstElement * element,
    GstInsertBinCallback callback, gpointer user_data)
{
  GstObject *parent;

  g_return_if_fail (GST_IS_ELEMENT (element));

  parent = gst_element_get_parent (element);

  if (parent) {
    gboolean is_parent;

    is_parent = (parent == GST_OBJECT_CAST (self));
    gst_object_unref (parent);

    if (!is_parent) {
      if (callback)
        callback (self, element, FALSE, user_data);
      return;
    }
  } else {
    GList *item;
    struct ChangeData *data = NULL;

    GST_OBJECT_LOCK (self);
    for (item = self->priv->change_queue.head; item; item = item->next) {
      data = item->data;

      if (data->element == element) {
        if (data->action == GST_INSERT_BIN_ACTION_ADD)
          g_queue_delete_link (&self->priv->change_queue, item);
        break;
      }
      data = NULL;
    }
    GST_OBJECT_UNLOCK (self);

    if (data) {
      gst_object_ref (element);
      gst_insert_bin_change_data_complete (self, data, TRUE);
      if (callback)
        callback (self, element, TRUE, user_data);
      gst_object_unref (element);
    } else {
      if (callback)
        callback (self, element, FALSE, user_data);
    }
    return;
  }

  gst_object_ref (element);

  gst_insert_bin_add_operation (self, element, GST_INSERT_BIN_ACTION_REMOVE,
      NULL, FALSE, callback, user_data);
}

/**
 * gst_insert_bin_new:
 * @name: (allow-none): The name of the new #GstInsertBin element (or %NULL)
 *
 * Creates a new #GstInsertBin
 *
 * Returns: The new #GstInsertBin
 *
 * Since: 1.2
 */

GstElement *
gst_insert_bin_new (const gchar * name)
{
  if (name)
    return g_object_new (GST_TYPE_INSERT_BIN, "name", name, NULL);
  else
    return g_object_new (GST_TYPE_INSERT_BIN, NULL);
}
