/*
 * gstrtponviftimestamp.h
 *
 * Copyright (C) 2014 Axis Communications AB
 *  Author: Guillaume Desmottes <guillaume.desmottes@collabora.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */

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

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

#include <gst/rtp/gstrtpbuffer.h>

#include "gstrtponviftimestamp.h"

#define GST_NTP_OFFSET_EVENT_NAME "GstNtpOffset"

#define DEFAULT_NTP_OFFSET GST_CLOCK_TIME_NONE
#define DEFAULT_CSEQ 0
#define DEFAULT_SET_E_BIT FALSE

GST_DEBUG_CATEGORY_STATIC (rtponviftimestamp_debug);
#define GST_CAT_DEFAULT (rtponviftimestamp_debug)

static GstFlowReturn gst_rtp_onvif_timestamp_chain (GstPad * pad,
    GstObject * parent, GstBuffer * buf);
static GstFlowReturn gst_rtp_onvif_timestamp_chain_list (GstPad * pad,
    GstObject * parent, GstBufferList * list);

static GstFlowReturn handle_and_push_buffer (GstRtpOnvifTimestamp * self,
    GstBuffer * buf);
static GstFlowReturn handle_and_push_buffer_list (GstRtpOnvifTimestamp * self,
    GstBufferList * list);

static GstStaticPadTemplate sink_template_factory =
GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("application/x-rtp")
    );

static GstStaticPadTemplate src_template_factory =
GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("application/x-rtp")
    );

enum
{
  PROP_0,
  PROP_NTP_OFFSET,
  PROP_CSEQ,
  PROP_SET_E_BIT,
};

/*static guint gst_rtp_onvif_timestamp_signals[LAST_SIGNAL] = { 0 }; */

G_DEFINE_TYPE (GstRtpOnvifTimestamp, gst_rtp_onvif_timestamp, GST_TYPE_ELEMENT);

static void
gst_rtp_onvif_timestamp_get_property (GObject * object,
    guint prop_id, GValue * value, GParamSpec * pspec)
{
  GstRtpOnvifTimestamp *self = GST_RTP_ONVIF_TIMESTAMP (object);

  switch (prop_id) {
    case PROP_NTP_OFFSET:
      g_value_set_uint64 (value, self->prop_ntp_offset);
      break;
    case PROP_CSEQ:
      g_value_set_uint (value, self->prop_cseq);
      break;
    case PROP_SET_E_BIT:
      g_value_set_boolean (value, self->prop_set_e_bit);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_rtp_onvif_timestamp_set_property (GObject * object,
    guint prop_id, const GValue * value, GParamSpec * pspec)
{
  GstRtpOnvifTimestamp *self = GST_RTP_ONVIF_TIMESTAMP (object);

  switch (prop_id) {
    case PROP_NTP_OFFSET:
      self->prop_ntp_offset = g_value_get_uint64 (value);
      break;
    case PROP_CSEQ:
      self->prop_cseq = g_value_get_uint (value);
      break;
    case PROP_SET_E_BIT:
      self->prop_set_e_bit = g_value_get_boolean (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

/* send cached buffer or list, and events, if present */
static GstFlowReturn
send_cached_buffer_and_events (GstRtpOnvifTimestamp * self)
{
  GstFlowReturn ret = GST_FLOW_OK;

  g_assert (!(self->buffer && self->list));

  if (self->buffer) {
    GST_DEBUG_OBJECT (self, "pushing %" GST_PTR_FORMAT, self->buffer);
    ret = handle_and_push_buffer (self, self->buffer);
    self->buffer = NULL;
  }
  if (self->list) {
    GST_DEBUG_OBJECT (self, "pushing %" GST_PTR_FORMAT, self->list);
    ret = handle_and_push_buffer_list (self, self->list);
    self->list = NULL;
  }

  if (ret != GST_FLOW_OK)
    goto out;

  while (!g_queue_is_empty (self->event_queue)) {
    GstEvent *event;

    event = GST_EVENT_CAST (g_queue_pop_head (self->event_queue));
    GST_LOG_OBJECT (self->sinkpad, "sending %" GST_PTR_FORMAT, event);
    (void) gst_pad_send_event (self->sinkpad, event);
  }

out:
  return ret;
}

static void
purge_cached_buffer_and_events (GstRtpOnvifTimestamp * self)
{
  g_assert (!(self->buffer && self->list));

  if (self->buffer) {
    GST_DEBUG_OBJECT (self, "purging %" GST_PTR_FORMAT, self->buffer);
    gst_buffer_unref (self->buffer);
    self->buffer = NULL;
  }
  if (self->list) {
    GST_DEBUG_OBJECT (self, "purging %" GST_PTR_FORMAT, self->list);
    gst_buffer_list_unref (self->list);
    self->list = NULL;
  }

  while (!g_queue_is_empty (self->event_queue)) {
    GstEvent *event;

    event = GST_EVENT_CAST (g_queue_pop_head (self->event_queue));
    gst_event_unref (event);
  }
}

static GstStateChangeReturn
gst_rtp_onvif_timestamp_change_state (GstElement * element,
    GstStateChange transition)
{
  GstRtpOnvifTimestamp *self = GST_RTP_ONVIF_TIMESTAMP (element);
  GstStateChangeReturn ret;

  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      purge_cached_buffer_and_events (self);
      gst_segment_init (&self->segment, GST_FORMAT_UNDEFINED);
      break;
    default:
      break;
  }

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

  if (ret == GST_STATE_CHANGE_FAILURE)
    return ret;

  switch (transition) {
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      self->ntp_offset = self->prop_ntp_offset;
      GST_DEBUG_OBJECT (self, "ntp-offset: %" GST_TIME_FORMAT,
          GST_TIME_ARGS (self->ntp_offset));
      self->set_d_bit = FALSE;
      self->set_e_bit = FALSE;
      break;
    default:
      break;
  }

  return ret;
}

static void
gst_rtp_onvif_timestamp_finalize (GObject * object)
{
  GstRtpOnvifTimestamp *self = GST_RTP_ONVIF_TIMESTAMP (object);

  g_queue_free (self->event_queue);

  G_OBJECT_CLASS (gst_rtp_onvif_timestamp_parent_class)->finalize (object);
}

static void
gst_rtp_onvif_timestamp_class_init (GstRtpOnvifTimestampClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;

  gobject_class = G_OBJECT_CLASS (klass);
  gstelement_class = GST_ELEMENT_CLASS (klass);

  gobject_class->get_property = gst_rtp_onvif_timestamp_get_property;
  gobject_class->set_property = gst_rtp_onvif_timestamp_set_property;
  gobject_class->finalize = gst_rtp_onvif_timestamp_finalize;

  g_object_class_install_property (gobject_class, PROP_NTP_OFFSET,
      g_param_spec_uint64 ("ntp-offset", "NTP offset",
          "Offset between the pipeline running time and the absolute UTC time, "
          "in nano-seconds since 1900 (-1 for automatic computation)",
          0, G_MAXUINT64,
          DEFAULT_NTP_OFFSET, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_CSEQ,
      g_param_spec_uint ("cseq", "CSeq",
          "The RTSP CSeq which initiated the playback",
          0, G_MAXUINT32,
          DEFAULT_CSEQ, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_SET_E_BIT,
      g_param_spec_boolean ("set-e-bit", "Set 'E' bit",
          "If the element should set the 'E' bit as defined in the ONVIF RTP "
          "extension. This increases latency by one packet",
          DEFAULT_SET_E_BIT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /* register pads */
  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&sink_template_factory));
  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&src_template_factory));

  gst_element_class_set_static_metadata (gstelement_class,
      "ONVIF NTP timestamps RTP extension", "Effect/RTP",
      "Add absolute timestamps and flags of recorded data in a playback "
      "session", "Guillaume Desmottes <guillaume.desmottes@collabora.com>");

  gstelement_class->change_state =
      GST_DEBUG_FUNCPTR (gst_rtp_onvif_timestamp_change_state);

  GST_DEBUG_CATEGORY_INIT (rtponviftimestamp_debug, "rtponviftimestamp",
      0, "ONVIF NTP timestamps RTP extension");
}

static gboolean
parse_event_ntp_offset (GstRtpOnvifTimestamp * self, GstEvent * event,
    GstClockTime * offset, gboolean * discont)
{
  const GstStructure *structure = gst_event_get_structure (event);
  GstClockTime event_offset;
  gboolean event_discont;

  if (!gst_structure_get_clock_time (structure, "ntp-offset", &event_offset)) {
    GST_ERROR_OBJECT (self, "no ntp-offset in %" GST_PTR_FORMAT, event);
    return FALSE;
  }
  if (!gst_structure_get_boolean (structure, "discont", &event_discont)) {
    GST_ERROR_OBJECT (self, "no discontinue in %" GST_PTR_FORMAT, event);
    return FALSE;
  }

  if (offset)
    *offset = event_offset;

  if (discont)
    *discont = event_discont;

  return TRUE;
}

static gboolean
gst_rtp_onvif_timestamp_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * event)
{
  GstRtpOnvifTimestamp *self = GST_RTP_ONVIF_TIMESTAMP (parent);
  gboolean drop = FALSE;
  gboolean ret = TRUE;

  GST_DEBUG_OBJECT (pad, "handling event %s", GST_EVENT_TYPE_NAME (event));

  /* handle serialized events, which, should not be enqueued */
  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_CUSTOM_DOWNSTREAM:
      /* if the "set-e-bit" property is set, an offset event might mark the
       * stream as discontinued. We need to check if the currently cached buffer
       * needs the e-bit before it's pushed */
      if (self->prop_set_e_bit &&
          gst_event_has_name (event, GST_NTP_OFFSET_EVENT_NAME)) {
        gboolean discont;
        if (parse_event_ntp_offset (self, event, NULL, &discont)) {
          GST_DEBUG_OBJECT (self, "stream %s discontinued",
              (discont ? "is" : "is not"));
          self->set_e_bit = discont;
        } else {
          drop = TRUE;
          ret = FALSE;
          goto out;
        }
      }
      break;
    case GST_EVENT_EOS:
    {
      GstFlowReturn res;
      /* Push pending buffers, if any */
      self->set_e_bit = TRUE;
      res = send_cached_buffer_and_events (self);
      if (res != GST_FLOW_OK) {
        drop = TRUE;
        ret = FALSE;
        goto out;
      }
      break;
    }
    case GST_EVENT_FLUSH_STOP:
      purge_cached_buffer_and_events (self);
      self->set_d_bit = FALSE;
      self->set_e_bit = FALSE;
      gst_segment_init (&self->segment, GST_FORMAT_UNDEFINED);
      break;
    default:
      break;
  }

  /* enqueue serialized events if there is a cached buffer */
  if (GST_EVENT_IS_SERIALIZED (event) && (self->buffer || self->list)) {
    GST_DEBUG ("enqueueing serialized event");
    g_queue_push_tail (self->event_queue, event);
    event = NULL;
    goto out;
  }

  /* handle rest of the events */
  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_CUSTOM_DOWNSTREAM:
      /* update the ntp-offset after any cached buffer/buffer list has been
       * pushed. the d-bit of the next buffer/buffer list should be set if
       * the stream is discontinued */
      if (gst_event_has_name (event, GST_NTP_OFFSET_EVENT_NAME)) {
        GstClockTime offset;
        gboolean discont;
        if (parse_event_ntp_offset (self, event, &offset, &discont)) {
          GST_DEBUG_OBJECT (self, "new ntp-offset: %" GST_TIME_FORMAT
              ", stream %s discontinued", GST_TIME_ARGS (offset),
              (discont ? "is" : "is not"));
          self->ntp_offset = offset;
          self->set_d_bit = discont;
        } else {
          ret = FALSE;
        }
        drop = TRUE;
      }
      break;
    case GST_EVENT_SEGMENT:
      gst_event_copy_segment (event, &self->segment);
      break;
    default:
      break;
  }

out:
  if (drop)
    gst_event_unref (event);
  else if (event)
    ret = gst_pad_event_default (pad, parent, event);

  return ret;
}

static void
gst_rtp_onvif_timestamp_init (GstRtpOnvifTimestamp * self)
{
  self->sinkpad =
      gst_pad_new_from_static_template (&sink_template_factory, "sink");
  gst_pad_set_chain_function (self->sinkpad, gst_rtp_onvif_timestamp_chain);
  gst_pad_set_chain_list_function (self->sinkpad,
      gst_rtp_onvif_timestamp_chain_list);
  gst_pad_set_event_function (self->sinkpad,
      gst_rtp_onvif_timestamp_sink_event);
  gst_element_add_pad (GST_ELEMENT (self), self->sinkpad);
  GST_PAD_SET_PROXY_CAPS (self->sinkpad);
  GST_PAD_SET_PROXY_ALLOCATION (self->sinkpad);

  self->srcpad =
      gst_pad_new_from_static_template (&src_template_factory, "src");
  gst_element_add_pad (GST_ELEMENT (self), self->srcpad);

  self->prop_ntp_offset = DEFAULT_NTP_OFFSET;
  self->prop_set_e_bit = DEFAULT_SET_E_BIT;

  gst_segment_init (&self->segment, GST_FORMAT_UNDEFINED);

  self->event_queue = g_queue_new ();
  self->buffer = NULL;
  self->list = NULL;
}

#define EXTENSION_ID 0xABAC
#define EXTENSION_SIZE 3

static gboolean
handle_buffer (GstRtpOnvifTimestamp * self, GstBuffer * buf)
{
  GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
  guint8 *data;
  guint16 bits;
  guint wordlen;
  guint64 time;
  guint8 field = 0;

  if (!GST_CLOCK_TIME_IS_VALID (self->ntp_offset)) {
    GstClock *clock = gst_element_get_clock (GST_ELEMENT (self));

    if (clock) {
      GstClockTime clock_time = gst_clock_get_time (clock);
      guint64 real_time = g_get_real_time ();
      GstClockTime running_time = clock_time -
          gst_element_get_base_time (GST_ELEMENT (self));

      /* convert microseconds to nanoseconds */
      real_time *= 1000;

      /* add constant to convert from 1970 based time to 1900 based time */
      real_time += (G_GUINT64_CONSTANT (2208988800) * GST_SECOND);

      self->ntp_offset = real_time - running_time;

      GST_DEBUG_OBJECT (self, "new ntp-offset: %" GST_TIME_FORMAT,
          GST_TIME_ARGS (self->ntp_offset));

      gst_object_unref (clock);
    } else {
      GST_ELEMENT_ERROR (self, STREAM, FAILED, ("No ntp-offset present"),
          ("Can not guess ntp-offset with no clock."));
      /* Received a buffer in PAUSED, so we can't guess the match
       * between the running time and the NTP clock yet.
       */
      return FALSE;
    }
  }

  if (self->segment.format != GST_FORMAT_TIME) {
    GST_ELEMENT_ERROR (self, STREAM, FAILED,
        ("did not receive a time segment yet"), (NULL));
    return FALSE;
  }

  if (!gst_rtp_buffer_map (buf, GST_MAP_READWRITE, &rtp)) {
    GST_ELEMENT_ERROR (self, STREAM, FAILED,
        ("Failed to map RTP buffer"), (NULL));
    return FALSE;
  }

  if (!gst_rtp_buffer_set_extension_data (&rtp, EXTENSION_ID, EXTENSION_SIZE)) {
    GST_ELEMENT_ERROR (self, STREAM, FAILED, ("Failed to set extension data"),
        (NULL));
    gst_rtp_buffer_unmap (&rtp);
    return FALSE;
  }

  if (!gst_rtp_buffer_get_extension_data (&rtp, &bits, (gpointer) & data,
          &wordlen)) {
    GST_ELEMENT_ERROR (self, STREAM, FAILED, ("Failed to get extension data"),
        (NULL));
    gst_rtp_buffer_unmap (&rtp);
    return FALSE;
  }

  /* NTP timestamp */
  if (GST_BUFFER_DTS_IS_VALID (buf)) {
    time = gst_segment_to_stream_time (&self->segment, GST_FORMAT_TIME,
        GST_BUFFER_DTS (buf));
  } else if (GST_BUFFER_PTS_IS_VALID (buf)) {
    time = gst_segment_to_stream_time (&self->segment, GST_FORMAT_TIME,
        GST_BUFFER_PTS (buf));
  } else {
    GST_ERROR_OBJECT (self,
        "Buffer doesn't contain any valid DTS or PTS timestamp");
    goto done;
  }

  if (time == GST_CLOCK_TIME_NONE) {
    GST_ERROR_OBJECT (self, "Failed to get stream time");
    goto done;
  }

  /* add the offset (in seconds) */
  time += self->ntp_offset;

  /* convert to NTP time. upper 32 bits should contain the seconds
   * and the lower 32 bits, the fractions of a second. */
  time = gst_util_uint64_scale (time, (G_GINT64_CONSTANT (1) << 32),
      GST_SECOND);

  GST_DEBUG_OBJECT (self, "timestamp: %" G_GUINT64_FORMAT, time);

  GST_WRITE_UINT64_BE (data, time);

  /* The next byte is composed of: C E D mbz (5 bits) */

  /* Set C if the buffer does *not* have the DELTA_UNIT flag as it means
   * that's a key frame (or 'clean point'). */
  if (!GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT)) {
    GST_DEBUG_OBJECT (self, "set C flag");
    field |= (1 << 7);
  }

  /* Set E if the next buffer has DISCONT */
  if (self->set_e_bit) {
    GST_DEBUG_OBJECT (self, "set E flag");
    field |= (1 << 6);
    self->set_e_bit = FALSE;
  }

  /* Set D if the buffer has the DISCONT flag */
  if (self->set_d_bit) {
    GST_DEBUG_OBJECT (self, "set D flag");
    field |= (1 << 5);
    self->set_d_bit = FALSE;
  }

  GST_WRITE_UINT8 (data + 8, field);

  /* CSeq (low-order byte) */
  GST_WRITE_UINT8 (data + 9, (guchar) self->prop_cseq);

  memset (data + 10, 0, 3);

done:
  gst_rtp_buffer_unmap (&rtp);
  return TRUE;
}

/* @buf: (transfer full) */
static GstFlowReturn
handle_and_push_buffer (GstRtpOnvifTimestamp * self, GstBuffer * buf)
{
  if (!handle_buffer (self, buf)) {
    gst_buffer_unref (buf);
    return GST_FLOW_ERROR;
  }

  return gst_pad_push (self->srcpad, buf);
}

static GstFlowReturn
gst_rtp_onvif_timestamp_chain (GstPad * pad, GstObject * parent,
    GstBuffer * buf)
{
  GstRtpOnvifTimestamp *self = GST_RTP_ONVIF_TIMESTAMP (parent);
  GstFlowReturn result = GST_FLOW_OK;

  if (!self->prop_set_e_bit) {
    /* Modify and push this buffer right away */
    return handle_and_push_buffer (self, buf);
  }

  /* send any previously cached item(s), this leaves an empty queue */
  result = send_cached_buffer_and_events (self);

  /* enqueue the new item, as the only item in the queue */
  self->buffer = buf;
  return result;
}

/* @buf: (transfer full) */
static GstFlowReturn
handle_and_push_buffer_list (GstRtpOnvifTimestamp * self, GstBufferList * list)
{
  GstBuffer *buf;

  /* Set the extension on the *first* buffer */
  buf = gst_buffer_list_get (list, 0);
  if (!handle_buffer (self, buf)) {
    gst_buffer_list_unref (list);
    return GST_FLOW_ERROR;
  }

  return gst_pad_push_list (self->srcpad, list);
}

/* gst_pad_chain_list_default() refs the buffer when passing it to the chain
 * function, making it not writable. We implement our own chain_list function
 * to avoid having to copy each buffer. */
static GstFlowReturn
gst_rtp_onvif_timestamp_chain_list (GstPad * pad, GstObject * parent,
    GstBufferList * list)
{
  GstRtpOnvifTimestamp *self = GST_RTP_ONVIF_TIMESTAMP (parent);
  GstFlowReturn result = GST_FLOW_OK;

  if (!self->prop_set_e_bit) {
    return handle_and_push_buffer_list (self, list);
  }

  /* send any previously cached item(s), this leaves an empty queue */
  result = send_cached_buffer_and_events (self);

  /* enqueue the new item, as the only item in the queue */
  self->list = list;
  return result;
}
