/* GStreamer
 * Copyright (C) <2004> Thomas Vander Stichele <thomas at apestaart dot org>
 * Copyright (C) 2006 Andy Wingo <wingo@pobox.com>
 * Copyright (C) 2008 Vincent Penquerc'h <ogg.k.ogg.k@googlemail.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., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

/**
 * SECTION:element-kateparse
 * @short_description: parses kate streams
 * @see_also: katedec, vorbisparse, oggdemux, theoraparse
 *
 * <refsect2>
 * <para>
 * The kateparse element will parse the header packets of the Kate
 * stream and put them as the streamheader in the caps. This is used in the
 * multifdsink case where you want to stream live kate streams to multiple
 * clients, each client has to receive the streamheaders first before they can
 * consume the kate packets.
 * </para>
 * <para>
 * This element also makes sure that the buffers that it pushes out are properly
 * timestamped and that their offset and offset_end are set. The buffers that
 * kateparse outputs have all of the metadata that oggmux expects to receive,
 * which allows you to (for example) remux an ogg/kate file.
 * </para>
 * <title>Example pipelines</title>
 * <para>
 * <programlisting>
 * gst-launch-1.0 -v filesrc location=kate.ogg ! oggdemux ! kateparse ! fakesink
 * </programlisting>
 * This pipeline shows that the streamheader is set in the caps, and that each
 * buffer has the timestamp, duration, offset, and offset_end set.
 * </para>
 * <para>
 * <programlisting>
 * gst-launch-1.0 filesrc location=kate.ogg ! oggdemux ! kateparse \
 *            ! oggmux ! filesink location=kate-remuxed.ogg
 * </programlisting>
 * This pipeline shows remuxing. kate-remuxed.ogg might not be exactly the same
 * as kate.ogg, but they should produce exactly the same decoded data.
 * </para>
 * </refsect2>
 *
 */

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

#include "gstkate.h"
#include "gstkateutil.h"
#include "gstkateparse.h"

GST_DEBUG_CATEGORY_EXTERN (gst_kateparse_debug);
#define GST_CAT_DEFAULT gst_kateparse_debug

static GstStaticPadTemplate gst_kate_parse_sink_factory =
    GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("subtitle/x-kate; application/x-kate")
    );

static GstStaticPadTemplate gst_kate_parse_src_factory =
    GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("subtitle/x-kate; application/x-kate")
    );

#define gst_kate_parse_parent_class parent_class
G_DEFINE_TYPE (GstKateParse, gst_kate_parse, GST_TYPE_ELEMENT);

static GstFlowReturn gst_kate_parse_chain (GstPad * pad, GstObject * parent,
    GstBuffer * buffer);
static GstStateChangeReturn gst_kate_parse_change_state (GstElement * element,
    GstStateChange transition);
static gboolean gst_kate_parse_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * event);
static gboolean gst_kate_parse_src_query (GstPad * pad, GstObject * parent,
    GstQuery * query);
#if 0
static gboolean gst_kate_parse_convert (GstPad * pad,
    GstFormat src_format, gint64 src_value,
    GstFormat * dest_format, gint64 * dest_value);
#endif
static GstFlowReturn gst_kate_parse_parse_packet (GstKateParse * parse,
    GstBuffer * buf);

static void
gst_kate_parse_class_init (GstKateParseClass * klass)
{
  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);

  gstelement_class->change_state = gst_kate_parse_change_state;

  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&gst_kate_parse_src_factory));
  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&gst_kate_parse_sink_factory));

  gst_element_class_set_static_metadata (gstelement_class, "Kate stream parser",
      "Codec/Parser/Subtitle",
      "parse raw kate streams",
      "Vincent Penquerc'h <ogg.k.ogg.k at googlemail dot com>");

  klass->parse_packet = GST_DEBUG_FUNCPTR (gst_kate_parse_parse_packet);
}

static void
gst_kate_parse_init (GstKateParse * parse)
{
  parse->sinkpad =
      gst_pad_new_from_static_template (&gst_kate_parse_sink_factory, "sink");
  gst_pad_set_chain_function (parse->sinkpad,
      GST_DEBUG_FUNCPTR (gst_kate_parse_chain));
  gst_pad_set_event_function (parse->sinkpad,
      GST_DEBUG_FUNCPTR (gst_kate_parse_sink_event));
  gst_element_add_pad (GST_ELEMENT (parse), parse->sinkpad);

  parse->srcpad =
      gst_pad_new_from_static_template (&gst_kate_parse_src_factory, "src");
  gst_pad_set_query_function (parse->srcpad,
      GST_DEBUG_FUNCPTR (gst_kate_parse_src_query));
  gst_element_add_pad (GST_ELEMENT (parse), parse->srcpad);
}

static void
gst_kate_parse_drain_event_queue (GstKateParse * parse)
{
  while (parse->event_queue->length) {
    GstEvent *event;

    event = GST_EVENT_CAST (g_queue_pop_head (parse->event_queue));
    gst_pad_event_default (parse->sinkpad, NULL, event);
  }
}

static GstFlowReturn
gst_kate_parse_push_headers (GstKateParse * parse)
{
  /* mark and put on caps */
  GstCaps *caps;
  GstBuffer *outbuf;
  kate_packet packet;
  GList *headers, *outbuf_list = NULL;
  int ret;
  gboolean res;

  /* get the headers into the caps, passing them to kate as we go */
  caps =
      gst_kate_util_set_header_on_caps (&parse->element,
      gst_pad_get_current_caps (parse->sinkpad), parse->streamheader);

  if (G_UNLIKELY (!caps)) {
    GST_ELEMENT_ERROR (parse, STREAM, DECODE, (NULL),
        ("Failed to set headers on caps"));
    return GST_FLOW_ERROR;
  }

  GST_DEBUG_OBJECT (parse, "here are the caps: %" GST_PTR_FORMAT, caps);
  res = gst_pad_set_caps (parse->srcpad, caps);
  gst_caps_unref (caps);
  if (G_UNLIKELY (!res)) {
    GST_WARNING_OBJECT (parse->srcpad, "Failed to set caps on source pad");
    return GST_FLOW_NOT_NEGOTIATED;
  }

  headers = parse->streamheader;
  while (headers) {
    GstMapInfo info;

    outbuf = GST_BUFFER_CAST (headers->data);

    if (!gst_buffer_map (outbuf, &info, GST_MAP_READ)) {
      GST_WARNING_OBJECT (outbuf, "Failed to map buffer");
      continue;
    }

    kate_packet_wrap (&packet, info.size, info.data);
    ret = kate_decode_headerin (&parse->ki, &parse->kc, &packet);
    if (G_UNLIKELY (ret < 0)) {
      GST_WARNING_OBJECT (parse, "Failed to decode header: %s",
          gst_kate_util_get_error_message (ret));
    }
    gst_buffer_unmap (outbuf, &info);
    /* takes ownership of outbuf, which was previously in parse->streamheader */
    GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_HEADER);
    outbuf_list = g_list_append (outbuf_list, outbuf);
    headers = headers->next;
  }

  /* first process queued events */
  gst_kate_parse_drain_event_queue (parse);

  /* push out buffers, ignoring return value... */
  headers = outbuf_list;
  while (headers) {
    outbuf = GST_BUFFER_CAST (headers->data);
    gst_pad_push (parse->srcpad, outbuf);
    headers = headers->next;
  }

  g_list_free (outbuf_list);
  g_list_free (parse->streamheader);
  parse->streamheader = NULL;

  parse->streamheader_sent = TRUE;

  return GST_FLOW_OK;
}

static void
gst_kate_parse_clear_queue (GstKateParse * parse)
{
  GST_DEBUG_OBJECT (parse, "Clearing queue");
  while (parse->buffer_queue->length) {
    GstBuffer *buf;

    buf = GST_BUFFER_CAST (g_queue_pop_head (parse->buffer_queue));
    gst_buffer_unref (buf);
  }
  while (parse->event_queue->length) {
    GstEvent *event;

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

static GstFlowReturn
gst_kate_parse_push_buffer (GstKateParse * parse, GstBuffer * buf,
    gint64 granulepos)
{
  GST_LOG_OBJECT (parse, "granulepos %16" G_GINT64_MODIFIER "x", granulepos);
  if (granulepos < 0) {
    /* packets coming not from Ogg won't have a granpos in the offset end,
       so we have to synthesize one here - only problem is we don't know
       the backlink - pretend there's none for now */
    GST_INFO_OBJECT (parse, "No granulepos on buffer, synthesizing one");
    granulepos =
        kate_duration_granule (&parse->ki,
        GST_BUFFER_TIMESTAMP (buf) /
        (double) GST_SECOND) << kate_granule_shift (&parse->ki);
  }
  GST_BUFFER_OFFSET (buf) =
      kate_granule_time (&parse->ki, granulepos) * GST_SECOND;
  GST_BUFFER_OFFSET_END (buf) = granulepos;
  GST_BUFFER_TIMESTAMP (buf) = GST_BUFFER_OFFSET (buf);

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

static GstFlowReturn
gst_kate_parse_drain_queue_prematurely (GstKateParse * parse)
{
  GstFlowReturn ret = GST_FLOW_OK;

  /* got an EOS event, make sure to push out any buffers that were in the queue
   * -- won't normally be the case, but this catches the
   * didn't-get-a-granulepos-on-the-last-packet case. Assuming a continuous
   * stream. */

  /* if we got EOS before any buffers came, go ahead and push the other events
   * first */
  gst_kate_parse_drain_event_queue (parse);

  while (!g_queue_is_empty (parse->buffer_queue)) {
    GstBuffer *buf;
    gint64 granpos;

    buf = GST_BUFFER_CAST (g_queue_pop_head (parse->buffer_queue));

    granpos = GST_BUFFER_OFFSET_END (buf);
    ret = gst_kate_parse_push_buffer (parse, buf, granpos);

    if (ret != GST_FLOW_OK)
      goto done;
  }

  g_assert (g_queue_is_empty (parse->buffer_queue));

done:
  return ret;
}

static GstFlowReturn
gst_kate_parse_drain_queue (GstKateParse * parse, gint64 granulepos)
{
  GstFlowReturn ret = GST_FLOW_OK;

  if (!g_queue_is_empty (parse->buffer_queue)) {
    GstBuffer *buf;
    buf = GST_BUFFER_CAST (g_queue_pop_head (parse->buffer_queue));
    ret = gst_kate_parse_push_buffer (parse, buf, granulepos);

    if (ret != GST_FLOW_OK)
      goto done;
  }
  g_assert (g_queue_is_empty (parse->buffer_queue));

done:
  return ret;
}

static GstFlowReturn
gst_kate_parse_queue_buffer (GstKateParse * parse, GstBuffer * buf)
{
  GstFlowReturn ret = GST_FLOW_OK;
  gint64 granpos;

  buf = gst_buffer_make_writable (buf);

  /* oggdemux stores the granule pos in the offset end */
  granpos = GST_BUFFER_OFFSET_END (buf);
  GST_LOG_OBJECT (parse, "granpos %16" G_GINT64_MODIFIER "x", granpos);
  g_queue_push_tail (parse->buffer_queue, buf);

#if 1
  /* if getting buffers from matroska, we won't have a granpos here... */
  //if (GST_BUFFER_OFFSET_END_IS_VALID (buf)) {
  ret = gst_kate_parse_drain_queue (parse, granpos);
  //}
#else
  if (granpos >= 0) {
    ret = gst_kate_parse_drain_queue (parse, granpos);
  } else {
    GST_ELEMENT_ERROR (parse, STREAM, DECODE, (NULL),
        ("Bad granulepos %" G_GINT64_FORMAT, granpos));
    ret = GST_FLOW_ERROR;
  }
#endif

  return ret;
}

static GstFlowReturn
gst_kate_parse_parse_packet (GstKateParse * parse, GstBuffer * buf)
{
  GstFlowReturn ret = GST_FLOW_OK;
  guint8 header[1];
  gsize size;

  g_assert (parse);

  parse->packetno++;

  size = gst_buffer_extract (buf, 0, header, 1);

  GST_LOG_OBJECT (parse, "Got packet %02x, %" G_GSIZE_FORMAT " bytes",
      size ? header[0] : -1, gst_buffer_get_size (buf));

  if (size > 0 && header[0] & 0x80) {
    GST_DEBUG_OBJECT (parse, "Found header %02x", header[0]);
    /* if 0x80 is set, it's streamheader,
     * so put it on the streamheader list and return */
    parse->streamheader = g_list_append (parse->streamheader, buf);
    ret = GST_FLOW_OK;
  } else {
    if (!parse->streamheader_sent) {
      GST_DEBUG_OBJECT (parse, "Found non header, pushing headers seen so far");
      ret = gst_kate_parse_push_headers (parse);
    }

    if (ret == GST_FLOW_OK) {
      ret = gst_kate_parse_queue_buffer (parse, buf);
    }
  }

  return ret;
}

static GstFlowReturn
gst_kate_parse_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
{
  GstKateParseClass *klass;
  GstKateParse *parse;

  parse = GST_KATE_PARSE (parent);
  klass = GST_KATE_PARSE_CLASS (G_OBJECT_GET_CLASS (parse));

  g_assert (klass->parse_packet != NULL);

  if (G_UNLIKELY (!gst_pad_has_current_caps (pad)))
    return GST_FLOW_NOT_NEGOTIATED;

  return klass->parse_packet (parse, buffer);
}

static gboolean
gst_kate_parse_queue_event (GstKateParse * parse, GstEvent * event)
{
  GstFlowReturn ret = TRUE;

  g_queue_push_tail (parse->event_queue, event);

  return ret;
}

static gboolean
gst_kate_parse_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  gboolean ret;
  GstKateParse *parse;

  parse = GST_KATE_PARSE (parent);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_FLUSH_STOP:
      gst_kate_parse_clear_queue (parse);
      ret = gst_pad_event_default (pad, parent, event);
      break;
    case GST_EVENT_EOS:
      if (!parse->streamheader_sent) {
        GST_DEBUG_OBJECT (parse, "Got EOS, pushing headers seen so far");
        ret = gst_kate_parse_push_headers (parse);
        if (ret != GST_FLOW_OK)
          break;
      }
      gst_kate_parse_drain_queue_prematurely (parse);
      ret = gst_pad_event_default (pad, parent, event);
      break;
    default:
      if (!parse->streamheader_sent && GST_EVENT_IS_SERIALIZED (event)
          && GST_EVENT_TYPE (event) > GST_EVENT_CAPS)
        ret = gst_kate_parse_queue_event (parse, event);
      else
        ret = gst_pad_event_default (pad, parent, event);
      break;
  }

  return ret;
}

#if 0
static gboolean
gst_kate_parse_convert (GstPad * pad,
    GstFormat src_format, gint64 src_value,
    GstFormat * dest_format, gint64 * dest_value)
{
  gboolean res = TRUE;
  GstKateParse *parse;

  parse = GST_KATE_PARSE (GST_PAD_PARENT (pad));

  /* fixme: assumes atomic access to lots of instance variables modified from
   * the streaming thread, including 64-bit variables */

  if (!parse->streamheader_sent)
    return FALSE;

  if (src_format == *dest_format) {
    *dest_value = src_value;
    return TRUE;
  }

  if (parse->sinkpad == pad &&
      (src_format == GST_FORMAT_BYTES || *dest_format == GST_FORMAT_BYTES))
    return FALSE;

  switch (src_format) {
    case GST_FORMAT_TIME:
      switch (*dest_format) {
        default:
          res = FALSE;
      }
      break;
    case GST_FORMAT_DEFAULT:
      switch (*dest_format) {
        case GST_FORMAT_TIME:
          *dest_value = kate_granule_time (&parse->ki, src_value) * GST_SECOND;
          break;
        default:
          res = FALSE;
      }
      break;
    default:
      res = FALSE;
  }

  return res;
}
#endif

static gboolean
gst_kate_parse_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
{
#if 1
  // TODO
  GST_WARNING ("gst_kate_parse_src_query");
  return FALSE;
#else
  gint64 granulepos;
  GstKateParse *parse;
  gboolean res = FALSE;

  parse = GST_KATE_PARSE (parent);

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_POSITION:
    {
      GstFormat format;
      gint64 value;

      granulepos = parse->prev_granulepos;

      gst_query_parse_position (query, &format, NULL);

      /* and convert to the final format */
      if (!(res =
              gst_kate_parse_convert (pad, GST_FORMAT_DEFAULT, granulepos,
                  &format, &value)))
        goto error;

      /* fixme: support segments
         value = (value - parse->segment_start) + parse->segment_time;
       */

      gst_query_set_position (query, format, value);

      GST_LOG_OBJECT (parse, "query %p: peer returned granulepos: %"
          G_GUINT64_FORMAT " - we return %" G_GUINT64_FORMAT " (format %u)",
          query, granulepos, value, format);

      break;
    }
    case GST_QUERY_DURATION:
    {
      /* fixme: not threadsafe */
      /* query peer for total length */
      if (!gst_pad_is_linked (parse->sinkpad)) {
        GST_WARNING_OBJECT (parse, "sink pad %" GST_PTR_FORMAT " is not linked",
            parse->sinkpad);
        goto error;
      }
      if (!(res = gst_pad_query (GST_PAD_PEER (parse->sinkpad), query)))
        goto error;
      break;
    }
    case GST_QUERY_CONVERT:
    {
      GstFormat src_fmt, dest_fmt;
      gint64 src_val, dest_val;

      gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
      if (!(res =
              gst_kate_parse_convert (pad, src_fmt, src_val, &dest_fmt,
                  &dest_val)))
        goto error;
      gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
      break;
    }
    default:
      res = gst_pad_query_default (pad, query);
      break;
  }
  return res;

error:
  {
    GST_WARNING_OBJECT (parse, "error handling query");
    return res;
  }
#endif
}

static void
gst_kate_parse_free_stream_headers (GstKateParse * parse)
{
  while (parse->streamheader != NULL) {
    gst_buffer_unref (GST_BUFFER (parse->streamheader->data));
    parse->streamheader = g_list_delete_link (parse->streamheader,
        parse->streamheader);
  }
}

static GstStateChangeReturn
gst_kate_parse_change_state (GstElement * element, GstStateChange transition)
{
  GstKateParse *parse = GST_KATE_PARSE (element);
  GstStateChangeReturn ret;

  switch (transition) {
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      kate_info_init (&parse->ki);
      kate_comment_init (&parse->kc);
      parse->packetno = 0;
      parse->streamheader_sent = FALSE;
      parse->streamheader = NULL;
      parse->buffer_queue = g_queue_new ();
      parse->event_queue = g_queue_new ();
      break;
    default:
      break;
  }

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

  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      kate_info_clear (&parse->ki);
      kate_comment_clear (&parse->kc);

      gst_kate_parse_clear_queue (parse);
      g_queue_free (parse->buffer_queue);
      parse->buffer_queue = NULL;
      g_queue_free (parse->event_queue);
      parse->event_queue = NULL;
      gst_kate_parse_free_stream_headers (parse);
      break;

    default:
      break;
  }

  return ret;
}
