/* GStreamer
 * Copyright (C) 2013 Rdio <ingestions@rdio.com>
 * Copyright (C) 2013 David Schleef <ds@schleef.org>
 *
 * 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 Street, Suite 500,
 * Boston, MA 02110-1335, USA.
 */
/**
 * SECTION:element-gstwatchdog
 *
 * The watchdog element watches buffers and events flowing through
 * a pipeline.  If no buffers are seen for a configurable amount of
 * time, a error message is sent to the bus.
 *
 * To use this element, insert it into a pipeline as you would an
 * identity element.  Once activated, any pause in the flow of
 * buffers through the element will cause an element error.  The
 * maximum allowed pause is determined by the timeout property.
 *
 * This element is currently intended for transcoding pipelines,
 * although may be useful in other contexts.
 *
 * <refsect2>
 * <title>Example launch line</title>
 * |[
 * gst-launch -v fakesrc ! watchdog ! fakesink
 * ]|
 * </refsect2>
 */

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

#include <gst/gst.h>
#include <gst/base/gstbasetransform.h>
#include "gstwatchdog.h"

GST_DEBUG_CATEGORY_STATIC (gst_watchdog_debug_category);
#define GST_CAT_DEFAULT gst_watchdog_debug_category

/* prototypes */

static void gst_watchdog_set_property (GObject * object,
    guint property_id, const GValue * value, GParamSpec * pspec);
static void gst_watchdog_get_property (GObject * object,
    guint property_id, GValue * value, GParamSpec * pspec);

static gboolean gst_watchdog_start (GstBaseTransform * trans);
static gboolean gst_watchdog_stop (GstBaseTransform * trans);
static gboolean gst_watchdog_sink_event (GstBaseTransform * trans,
    GstEvent * event);
static gboolean gst_watchdog_src_event (GstBaseTransform * trans,
    GstEvent * event);
static GstFlowReturn gst_watchdog_transform_ip (GstBaseTransform * trans,
    GstBuffer * buf);
static void gst_watchdog_feed (GstWatchdog * watchdog, gpointer mini_object,
    gboolean force);

static GstStateChangeReturn
gst_watchdog_change_state (GstElement * element, GstStateChange transition);

enum
{
  PROP_0,
  PROP_TIMEOUT
};

/* class initialization */

G_DEFINE_TYPE_WITH_CODE (GstWatchdog, gst_watchdog, GST_TYPE_BASE_TRANSFORM,
    GST_DEBUG_CATEGORY_INIT (gst_watchdog_debug_category, "watchdog", 0,
        "debug category for watchdog element"));

static void
gst_watchdog_class_init (GstWatchdogClass * klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  GstBaseTransformClass *base_transform_class =
      GST_BASE_TRANSFORM_CLASS (klass);

  GstElementClass *gstelement_klass = (GstElementClass *) klass;

  gst_element_class_add_pad_template (GST_ELEMENT_CLASS (klass),
      gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
          gst_caps_new_any ()));
  gst_element_class_add_pad_template (GST_ELEMENT_CLASS (klass),
      gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
          gst_caps_new_any ()));

  gst_element_class_set_static_metadata (GST_ELEMENT_CLASS (klass),
      "Watchdog", "Generic", "Watches for pauses in stream buffers",
      "David Schleef <ds@schleef.org>");

  gstelement_klass->change_state =
      GST_DEBUG_FUNCPTR (gst_watchdog_change_state);
  gobject_class->set_property = gst_watchdog_set_property;
  gobject_class->get_property = gst_watchdog_get_property;
  base_transform_class->start = GST_DEBUG_FUNCPTR (gst_watchdog_start);
  base_transform_class->stop = GST_DEBUG_FUNCPTR (gst_watchdog_stop);
  base_transform_class->sink_event =
      GST_DEBUG_FUNCPTR (gst_watchdog_sink_event);
  base_transform_class->src_event = GST_DEBUG_FUNCPTR (gst_watchdog_src_event);
  base_transform_class->transform_ip =
      GST_DEBUG_FUNCPTR (gst_watchdog_transform_ip);

  g_object_class_install_property (gobject_class, PROP_TIMEOUT,
      g_param_spec_int ("timeout", "Timeout", "Timeout (in ms) after "
          "which an element error is sent to the bus if no buffers are "
          "received. 0 means disabled.", 0, G_MAXINT, 1000,
          G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

}

static void
gst_watchdog_init (GstWatchdog * watchdog)
{
}

void
gst_watchdog_set_property (GObject * object, guint property_id,
    const GValue * value, GParamSpec * pspec)
{
  GstWatchdog *watchdog = GST_WATCHDOG (object);

  GST_DEBUG_OBJECT (watchdog, "set_property");

  switch (property_id) {
    case PROP_TIMEOUT:
      GST_OBJECT_LOCK (watchdog);
      watchdog->timeout = g_value_get_int (value);
      gst_watchdog_feed (watchdog, NULL, FALSE);
      GST_OBJECT_UNLOCK (watchdog);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
  }
}

void
gst_watchdog_get_property (GObject * object, guint property_id,
    GValue * value, GParamSpec * pspec)
{
  GstWatchdog *watchdog = GST_WATCHDOG (object);

  GST_DEBUG_OBJECT (watchdog, "get_property");

  switch (property_id) {
    case PROP_TIMEOUT:
      g_value_set_int (value, watchdog->timeout);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
  }
}

static gpointer
gst_watchdog_thread (gpointer user_data)
{
  GstWatchdog *watchdog = GST_WATCHDOG (user_data);

  GST_DEBUG_OBJECT (watchdog, "thread starting");

  g_main_loop_run (watchdog->main_loop);

  GST_DEBUG_OBJECT (watchdog, "thread exiting");

  return NULL;
}

static gboolean
gst_watchdog_trigger (gpointer ptr)
{
  GstWatchdog *watchdog = GST_WATCHDOG (ptr);

  GST_DEBUG_OBJECT (watchdog, "watchdog triggered");

  GST_ELEMENT_ERROR (watchdog, STREAM, FAILED, ("Watchdog triggered"),
      ("Watchdog triggered"));

  return FALSE;
}

static gboolean
gst_watchdog_quit_mainloop (gpointer ptr)
{
  GstWatchdog *watchdog = GST_WATCHDOG (ptr);

  GST_DEBUG_OBJECT (watchdog, "watchdog quit");

  g_main_loop_quit (watchdog->main_loop);

  return FALSE;
}

/*  Call with OBJECT_LOCK taken */
static void
gst_watchdog_feed (GstWatchdog * watchdog, gpointer mini_object, gboolean force)
{
  if (watchdog->source) {
    if (watchdog->waiting_for_flush_start) {
      if (mini_object && GST_IS_EVENT (mini_object) &&
          GST_EVENT_TYPE (mini_object) == GST_EVENT_FLUSH_START) {
        watchdog->waiting_for_flush_start = FALSE;
        watchdog->waiting_for_flush_stop = TRUE;
      }

      force = TRUE;
    } else if (watchdog->waiting_for_flush_stop) {
      if (mini_object && GST_IS_EVENT (mini_object) &&
          GST_EVENT_TYPE (mini_object) == GST_EVENT_FLUSH_STOP) {
        watchdog->waiting_for_flush_stop = FALSE;
        watchdog->waiting_for_a_buffer = TRUE;
      }

      force = TRUE;
    } else if (watchdog->waiting_for_a_buffer) {
      if (mini_object && GST_IS_BUFFER (mini_object)) {
        watchdog->waiting_for_a_buffer = FALSE;
        GST_DEBUG_OBJECT (watchdog, "Got a buffer \\o/");
      } else {
        GST_DEBUG_OBJECT (watchdog, "Waiting for a buffer and did not get it,"
            " keep trying even in PAUSED state");
        force = TRUE;
      }
    }
    g_source_destroy (watchdog->source);
    g_source_unref (watchdog->source);
    watchdog->source = NULL;

  }

  if (watchdog->timeout == 0) {
    GST_LOG_OBJECT (watchdog, "Timeout is 0 => nothing to do");
  } else if (watchdog->main_context == NULL) {
    GST_LOG_OBJECT (watchdog, "No maincontext => nothing to do");
  } else if ((GST_STATE (watchdog) != GST_STATE_PLAYING) && force == FALSE) {
    GST_LOG_OBJECT (watchdog,
        "Not in playing and force is FALSE => Nothing to do");
  } else {
    watchdog->source = g_timeout_source_new (watchdog->timeout);
    g_source_set_callback (watchdog->source, gst_watchdog_trigger,
        gst_object_ref (watchdog), gst_object_unref);
    g_source_attach (watchdog->source, watchdog->main_context);
  }
}

static gboolean
gst_watchdog_start (GstBaseTransform * trans)
{
  GstWatchdog *watchdog = GST_WATCHDOG (trans);

  GST_DEBUG_OBJECT (watchdog, "start");
  GST_OBJECT_LOCK (watchdog);

  watchdog->main_context = g_main_context_new ();
  watchdog->main_loop = g_main_loop_new (watchdog->main_context, TRUE);
  watchdog->thread = g_thread_new ("watchdog", gst_watchdog_thread, watchdog);

  GST_OBJECT_UNLOCK (watchdog);
  return TRUE;
}

static gboolean
gst_watchdog_stop (GstBaseTransform * trans)
{
  GstWatchdog *watchdog = GST_WATCHDOG (trans);
  GSource *quit_source;

  GST_DEBUG_OBJECT (watchdog, "stop");
  GST_OBJECT_LOCK (watchdog);

  if (watchdog->source) {
    g_source_destroy (watchdog->source);
    g_source_unref (watchdog->source);
    watchdog->source = NULL;
  }

  /* dispatch an idle event that trigger g_main_loop_quit to avoid race
   * between g_main_loop_run and g_main_loop_quit */
  quit_source = g_idle_source_new ();
  g_source_set_callback (quit_source, gst_watchdog_quit_mainloop, watchdog,
      NULL);
  g_source_attach (quit_source, watchdog->main_context);
  g_source_unref (quit_source);

  g_thread_join (watchdog->thread);
  watchdog->thread = NULL;

  g_main_loop_unref (watchdog->main_loop);
  watchdog->main_loop = NULL;

  g_main_context_unref (watchdog->main_context);
  watchdog->main_context = NULL;

  GST_OBJECT_UNLOCK (watchdog);
  return TRUE;
}

static gboolean
gst_watchdog_sink_event (GstBaseTransform * trans, GstEvent * event)
{
  GstWatchdog *watchdog = GST_WATCHDOG (trans);

  GST_DEBUG_OBJECT (watchdog, "sink_event");

  GST_OBJECT_LOCK (watchdog);
  gst_watchdog_feed (watchdog, event, FALSE);
  GST_OBJECT_UNLOCK (watchdog);

  return
      GST_BASE_TRANSFORM_CLASS (gst_watchdog_parent_class)->sink_event (trans,
      event);
}

static gboolean
gst_watchdog_src_event (GstBaseTransform * trans, GstEvent * event)
{
  gboolean force = FALSE;
  GstWatchdog *watchdog = GST_WATCHDOG (trans);

  GST_DEBUG_OBJECT (watchdog, "src_event");

  GST_OBJECT_LOCK (watchdog);
  if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
    GstSeekFlags flags;

    gst_event_parse_seek (event, NULL, NULL, &flags, NULL, NULL, NULL, NULL);

    if (flags & GST_SEEK_FLAG_FLUSH) {
      force = TRUE;
      GST_DEBUG_OBJECT (watchdog, "Got a FLUSHING seek, we need a buffer now!");
      watchdog->waiting_for_flush_start = TRUE;
    }
  }

  gst_watchdog_feed (watchdog, event, force);
  GST_OBJECT_UNLOCK (watchdog);

  return GST_BASE_TRANSFORM_CLASS (gst_watchdog_parent_class)->src_event (trans,
      event);
}

static GstFlowReturn
gst_watchdog_transform_ip (GstBaseTransform * trans, GstBuffer * buf)
{
  GstWatchdog *watchdog = GST_WATCHDOG (trans);

  GST_DEBUG_OBJECT (watchdog, "transform_ip");

  GST_OBJECT_LOCK (watchdog);
  gst_watchdog_feed (watchdog, buf, FALSE);
  GST_OBJECT_UNLOCK (watchdog);

  return GST_FLOW_OK;
}

/*
 * Change state handler for the element.
 */
static GstStateChangeReturn
gst_watchdog_change_state (GstElement * element, GstStateChange transition)
{
  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
  GstWatchdog *watchdog = GST_WATCHDOG (element);

  GST_DEBUG_OBJECT (watchdog, "gst_watchdog_change_state");

  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
      /* Activate timer */
      GST_OBJECT_LOCK (watchdog);
      gst_watchdog_feed (watchdog, NULL, FALSE);
      GST_OBJECT_UNLOCK (watchdog);
      break;
    default:
      break;
  }

  ret =
      GST_ELEMENT_CLASS (gst_watchdog_parent_class)->change_state (element,
      transition);

  switch (transition) {
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      GST_OBJECT_LOCK (watchdog);
      watchdog->waiting_for_a_buffer = TRUE;
      gst_watchdog_feed (watchdog, NULL, TRUE);
      GST_OBJECT_UNLOCK (watchdog);
      break;
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
      /* Disable the timer */
      GST_OBJECT_LOCK (watchdog);
      if (watchdog->source) {
        g_source_destroy (watchdog->source);
        g_source_unref (watchdog->source);
        watchdog->source = NULL;
      }
      GST_OBJECT_UNLOCK (watchdog);
      break;
    default:
      break;
  }

  return ret;


}
