/* GStreamer
 * 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.
 */

/* FIXME: shouldn't all this GstKateDecoderBase stuff really be a base class? */

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

#include <string.h>
#ifdef HAVE_TIGER
#include <tiger/tiger.h>
#endif
#include <gst/tag/tag.h>
#include "gstkate.h"
#include "gstkateutil.h"

GST_DEBUG_CATEGORY_EXTERN (gst_kateutil_debug);
#define GST_CAT_DEFAULT gst_kateutil_debug

static void gst_kate_util_decoder_base_free_event_queue (GstKateDecoderBase *
    decoder);

GstCaps *
gst_kate_util_set_header_on_caps (GstElement * element, GstCaps * caps,
    GList * headers)
{
  GstStructure *structure;
  GValue array = { 0 };

  GST_LOG_OBJECT (element, "caps: %" GST_PTR_FORMAT, caps);

  if (G_UNLIKELY (!caps))
    return NULL;
  if (G_UNLIKELY (!headers))
    return NULL;

  caps = gst_caps_make_writable (caps);
  structure = gst_caps_get_structure (caps, 0);

  g_value_init (&array, GST_TYPE_ARRAY);

  while (headers) {
    GValue value = { 0 };
    GstBuffer *buffer = headers->data;
    g_assert (buffer);
    g_value_init (&value, GST_TYPE_BUFFER);
    buffer = gst_buffer_copy (buffer);
    GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_HEADER);
    gst_value_take_buffer (&value, buffer);
    gst_value_array_append_value (&array, &value);
    g_value_unset (&value);
    headers = headers->next;
  }

  gst_structure_take_value (structure, "streamheader", &array);

  GST_LOG_OBJECT (element, "here are the newly set caps: %" GST_PTR_FORMAT,
      caps);

  return caps;
}

void
gst_kate_util_install_decoder_base_properties (GObjectClass * gobject_class)
{
  g_object_class_install_property (gobject_class, ARG_DEC_BASE_LANGUAGE,
      g_param_spec_string ("language", "Language", "The language of the stream",
          "", G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, ARG_DEC_BASE_CATEGORY,
      g_param_spec_string ("category", "Category", "The category of the stream",
          "", G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class,
      ARG_DEC_BASE_ORIGINAL_CANVAS_WIDTH,
      g_param_spec_int ("original-canvas-width",
          "Original canvas width (0 is unspecified)",
          "The canvas width this stream was authored for", 0, G_MAXINT, 0,
          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class,
      ARG_DEC_BASE_ORIGINAL_CANVAS_HEIGHT,
      g_param_spec_int ("original-canvas-height", "Original canvas height",
          "The canvas height this stream was authored for (0 is unspecified)",
          0, G_MAXINT, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
}

void
gst_kate_util_decode_base_init (GstKateDecoderBase * decoder,
    gboolean delay_events)
{
  if (G_UNLIKELY (!decoder))
    return;

  decoder->language = NULL;
  decoder->category = NULL;
  decoder->original_canvas_width = 0;
  decoder->original_canvas_height = 0;
  decoder->tags = NULL;
  decoder->tags_changed = FALSE;
  decoder->initialized = FALSE;
  decoder->delay_events = delay_events;
  decoder->event_queue = NULL;
}

static void
gst_kate_util_decode_base_reset (GstKateDecoderBase * decoder)
{
  g_free (decoder->language);
  decoder->language = NULL;
  g_free (decoder->category);
  decoder->category = NULL;
  if (decoder->tags) {
    gst_tag_list_unref (decoder->tags);
    decoder->tags = NULL;
  }
  decoder->tags_changed = FALSE;
  decoder->original_canvas_width = 0;
  decoder->original_canvas_height = 0;
  if (decoder->event_queue) {
    gst_kate_util_decoder_base_free_event_queue (decoder);
  }
  decoder->initialized = FALSE;
}

gboolean
gst_kate_util_decoder_base_queue_event (GstKateDecoderBase * decoder,
    GstEvent * event, gboolean (*handler) (GstPad *, GstObject *, GstEvent *),
    GstObject * parent, GstPad * pad)
{
  gboolean can_be_queued;

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_FLUSH_START:
    case GST_EVENT_FLUSH_STOP:
    case GST_EVENT_EOS:
      can_be_queued = FALSE;
      break;
    default:
      can_be_queued = TRUE;
      break;
  }

  if (GST_EVENT_IS_STICKY (event) && GST_EVENT_TYPE (event) < GST_EVENT_CAPS)
    can_be_queued = FALSE;

  if (decoder->delay_events && can_be_queued) {
    GstKateDecoderBaseQueuedEvent *item;
    GST_DEBUG_OBJECT (decoder, "We have to delay the event");
    item = g_slice_new (GstKateDecoderBaseQueuedEvent);
    if (item) {
      item->event = event;
      item->parent = parent;
      item->pad = pad;
      item->handler = handler;
      g_queue_push_tail (decoder->event_queue, item);
      return TRUE;
    } else {
      return FALSE;
    }
  } else {
    return FALSE;
  }
}

static void
gst_kate_util_decoder_base_free_event_queue (GstKateDecoderBase * decoder)
{
  while (decoder->event_queue->length) {
    GstKateDecoderBaseQueuedEvent *item = (GstKateDecoderBaseQueuedEvent *)
        g_queue_pop_head (decoder->event_queue);
    gst_event_unref (item->event);
    g_slice_free (GstKateDecoderBaseQueuedEvent, item);
  }
  g_queue_free (decoder->event_queue);
  decoder->event_queue = NULL;
}

static void
gst_kate_util_decoder_base_drain_event_queue (GstKateDecoderBase * decoder)
{
  decoder->delay_events = FALSE;

  if (decoder->event_queue->length == 0)
    return;

  GST_DEBUG_OBJECT (decoder, "We can now drain all events!");
  while (decoder->event_queue->length) {
    GstKateDecoderBaseQueuedEvent *item = (GstKateDecoderBaseQueuedEvent *)
        g_queue_pop_head (decoder->event_queue);
    (*item->handler) (item->pad, item->parent, item->event);
    g_slice_free (GstKateDecoderBaseQueuedEvent, item);
  }
}

void
gst_kate_util_decoder_base_add_tags (GstKateDecoderBase * decoder,
    GstTagList * tags, gboolean take_ownership_of_tags)
{
  if (!decoder->tags) {
    if (!take_ownership_of_tags)
      tags = gst_tag_list_ref (tags);
    decoder->tags = tags;
  } else {
    GstTagList *old = decoder->tags;
    decoder->tags = gst_tag_list_merge (old, tags, GST_TAG_MERGE_REPLACE);
    gst_tag_list_unref (old);
    if (take_ownership_of_tags)
      gst_tag_list_unref (tags);
  }
  decoder->tags_changed = TRUE;
}

GstEvent *
gst_kate_util_decoder_base_get_tag_event (GstKateDecoderBase * decoder)
{
  if (!decoder->tags)
    return NULL;
  decoder->tags_changed = FALSE;
  return gst_event_new_tag (gst_tag_list_ref (decoder->tags));
}

gboolean
gst_kate_util_decoder_base_get_property (GstKateDecoderBase * decoder,
    GObject * object, guint prop_id, GValue * value, GParamSpec * pspec)
{
  gboolean res = TRUE;
  switch (prop_id) {
    case ARG_DEC_BASE_LANGUAGE:
      g_value_set_string (value, decoder->language);
      break;
    case ARG_DEC_BASE_CATEGORY:
      g_value_set_string (value, decoder->category);
      break;
    case ARG_DEC_BASE_ORIGINAL_CANVAS_WIDTH:
      g_value_set_int (value, decoder->original_canvas_width);
      break;
    case ARG_DEC_BASE_ORIGINAL_CANVAS_HEIGHT:
      g_value_set_int (value, decoder->original_canvas_height);
      break;
    default:
      res = FALSE;
      break;
  }
  return res;
}

static inline gboolean
gst_kate_util_is_utf8_string (const char *value, size_t len)
{
  if (len == 0)
    return FALSE;
  if (memchr (value, 0, len - 1))
    return FALSE;
  if (value[len - 1])
    return FALSE;
  return (kate_text_validate (kate_utf8, value, len) >= 0);
}

GstFlowReturn
gst_kate_util_decoder_base_chain_kate_packet (GstKateDecoderBase * decoder,
    GstElement * element, GstPad * pad, GstBuffer * buf, GstPad * srcpad,
    GstPad * tagpad, GstCaps ** src_caps, const kate_event ** ev)
{
  kate_packet kp;
  int ret;
  GstFlowReturn rflow = GST_FLOW_OK;
  gboolean is_header;
  GstMapInfo info;
  gsize header_size;
  guint8 header[1];

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

  GST_DEBUG_OBJECT (element,
      "got kate packet, %" G_GSIZE_FORMAT " bytes, type %02x",
      gst_buffer_get_size (buf), header_size == 0 ? -1 : header[0]);

  is_header = header_size > 0 && (header[0] & 0x80);

  if (!is_header && decoder->tags_changed) {
    /* after we've processed headers, send any tags before processing the data packet */
    GST_DEBUG_OBJECT (element, "Not a header, sending tags for pad %s:%s",
        GST_DEBUG_PAD_NAME (tagpad));
    gst_pad_push_event (tagpad,
        gst_kate_util_decoder_base_get_tag_event (decoder));
  }

  if (gst_buffer_map (buf, &info, GST_MAP_READ)) {
    kate_packet_wrap (&kp, info.size, info.data);
    ret = kate_high_decode_packetin (&decoder->k, &kp, ev);
    gst_buffer_unmap (buf, &info);
  } else {
    GST_ELEMENT_ERROR (element, STREAM, DECODE, (NULL),
        ("Failed to map buffer"));
    return GST_FLOW_ERROR;
  }

  if (G_UNLIKELY (ret < 0)) {
    GST_ELEMENT_ERROR (element, STREAM, DECODE, (NULL),
        ("Failed to decode Kate packet: %s",
            gst_kate_util_get_error_message (ret)));
    return GST_FLOW_ERROR;
  }

  if (G_UNLIKELY (ret > 0)) {
    GST_DEBUG_OBJECT (element,
        "kate_high_decode_packetin has received EOS packet");
  }

  /* headers may be interesting to retrieve information from */
  if (G_UNLIKELY (is_header)) {
    switch (header[0]) {
      case 0x80:               /* ID header */
        GST_INFO_OBJECT (element, "Parsed ID header: language %s, category %s",
            decoder->k.ki->language, decoder->k.ki->category);
        if (src_caps) {
          if (*src_caps) {
            gst_caps_unref (*src_caps);
            *src_caps = NULL;
          }
          if (strcmp (decoder->k.ki->category, "K-SPU") == 0 ||
              strcmp (decoder->k.ki->category, "spu-subtitles") == 0) {
            *src_caps = gst_caps_new_empty_simple ("subpicture/x-dvd");
          } else if (decoder->k.ki->text_markup_type == kate_markup_none) {
            *src_caps = gst_caps_new_simple ("text/x-raw", "format",
                G_TYPE_STRING, "utf8", NULL);
          } else {
            *src_caps = gst_caps_new_simple ("text/x-raw", "format",
                G_TYPE_STRING, "pango-markup", NULL);
          }
          GST_INFO_OBJECT (srcpad, "Setting caps: %" GST_PTR_FORMAT, *src_caps);
          if (!gst_pad_set_caps (srcpad, *src_caps)) {
            GST_ERROR_OBJECT (srcpad, "Failed to set caps %" GST_PTR_FORMAT,
                *src_caps);
          }
        }
        if (decoder->k.ki->language && *decoder->k.ki->language) {
          GstTagList *tags = gst_tag_list_new_empty ();
          gchar *lang_code;

          /* en_GB -> en */
          lang_code = g_ascii_strdown (decoder->k.ki->language, -1);
          g_strdelimit (lang_code, NULL, '\0');
          gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_LANGUAGE_CODE,
              lang_code, NULL);
          g_free (lang_code);
          /* TODO: category - where should it go ? */
          gst_kate_util_decoder_base_add_tags (decoder, tags, TRUE);
        }

        /* update properties */
        if (decoder->language)
          g_free (decoder->language);
        decoder->language = g_strdup (decoder->k.ki->language);
        if (decoder->category)
          g_free (decoder->category);
        decoder->category = g_strdup (decoder->k.ki->category);
        decoder->original_canvas_width = decoder->k.ki->original_canvas_width;
        decoder->original_canvas_height = decoder->k.ki->original_canvas_height;

        /* we can now send away any event we've delayed, as the src pad now has caps */
        gst_kate_util_decoder_base_drain_event_queue (decoder);

        break;

      case 0x81:               /* Vorbis comments header */
        GST_INFO_OBJECT (element, "Parsed comments header");
        {
          gchar *encoder = NULL;
          GstTagList *list = gst_tag_list_from_vorbiscomment_buffer (buf,
              (const guint8 *) "\201kate\0\0\0\0", 9, &encoder);
          if (!list) {
            GST_ERROR_OBJECT (element, "failed to decode comment header");
            list = gst_tag_list_new_empty ();
          }
          if (encoder) {
            gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
                GST_TAG_ENCODER, encoder, NULL);
            g_free (encoder);
          }
          gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
              GST_TAG_SUBTITLE_CODEC, "Kate", NULL);
          gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
              GST_TAG_ENCODER_VERSION, decoder->k.ki->bitstream_version_major,
              NULL);

          gst_kate_util_decoder_base_add_tags (decoder, list, TRUE);

          if (decoder->initialized) {
            gst_pad_push_event (tagpad,
                gst_event_new_tag (gst_tag_list_ref (decoder->tags)));
          }
        }
        break;

      default:
        break;
    }
  }
#if ((KATE_VERSION_MAJOR<<16)|(KATE_VERSION_MINOR<<8)|KATE_VERSION_PATCH) >= 0x000400
  else if (*ev && (*ev)->meta) {
    int count = kate_meta_query_count ((*ev)->meta);
    if (count > 0) {
      GstTagList *evtags = gst_tag_list_new_empty ();
      int idx;
      GST_DEBUG_OBJECT (decoder, "Kate event has %d attached metadata", count);
      for (idx = 0; idx < count; ++idx) {
        const char *tag, *value;
        size_t len;
        if (kate_meta_query ((*ev)->meta, idx, &tag, &value, &len) < 0) {
          GST_WARNING_OBJECT (decoder, "Failed to retrieve metadata %d", idx);
        } else {
          if (gst_kate_util_is_utf8_string (value, len)) {
            gchar *compound = g_strdup_printf ("%s=%s", tag, value);
            GST_DEBUG_OBJECT (decoder,
                "Metadata %d: %s=%s (%" G_GSIZE_FORMAT " bytes)", idx, tag,
                value, len);
            gst_tag_list_add (evtags, GST_TAG_MERGE_APPEND,
                GST_TAG_EXTENDED_COMMENT, compound, NULL);
            g_free (compound);
          } else {
            GST_INFO_OBJECT (decoder,
                "Metadata %d, (%s, %" G_GSIZE_FORMAT
                " bytes) is binary, ignored", idx, tag, len);
          }
        }
      }
      gst_kate_util_decoder_base_add_tags (decoder, evtags, TRUE);
      gst_pad_push_event (tagpad,
          gst_kate_util_decoder_base_get_tag_event (decoder));
    }
  }
#endif

  return rflow;
}

GstStateChangeReturn
gst_kate_decoder_base_change_state (GstKateDecoderBase * decoder,
    GstElement * element, GstElementClass * parent_class,
    GstStateChange transition)
{
  GstStateChangeReturn res;
  int ret;

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      GST_DEBUG_OBJECT (element, "READY -> PAUSED, initializing kate state");
      ret = kate_high_decode_init (&decoder->k);
      if (ret < 0) {
        GST_WARNING_OBJECT (element, "failed to initialize kate state: %s",
            gst_kate_util_get_error_message (ret));
      }
      gst_segment_init (&decoder->kate_segment, GST_FORMAT_UNDEFINED);
      decoder->kate_flushing = FALSE;
      decoder->initialized = TRUE;
      decoder->event_queue = g_queue_new ();
      break;
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
      break;
    default:
      break;
  }

  res = parent_class->change_state (element, transition);

  switch (transition) {
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
      break;
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      GST_DEBUG_OBJECT (element, "PAUSED -> READY, clearing kate state");
      if (decoder->initialized) {
        kate_high_decode_clear (&decoder->k);
        decoder->initialized = FALSE;
      }
      gst_segment_init (&decoder->kate_segment, GST_FORMAT_UNDEFINED);
      decoder->kate_flushing = TRUE;
      gst_kate_util_decode_base_reset (decoder);
      break;
    case GST_STATE_CHANGE_READY_TO_NULL:
      gst_kate_util_decode_base_reset (decoder);
      break;
    default:
      break;
  }

  return res;
}

void
gst_kate_util_decoder_base_set_flushing (GstKateDecoderBase * decoder,
    gboolean flushing)
{
  decoder->kate_flushing = flushing;
  gst_segment_init (&decoder->kate_segment, GST_FORMAT_UNDEFINED);
}

void
gst_kate_util_decoder_base_segment_event (GstKateDecoderBase * decoder,
    GstEvent * event)
{
  GstSegment seg;

  gst_event_copy_segment (event, &seg);

  GST_DEBUG_OBJECT (decoder, "kate pad segment: %" GST_SEGMENT_FORMAT, &seg);

  decoder->kate_segment = seg;
}

gboolean
gst_kate_util_decoder_base_update_segment (GstKateDecoderBase * decoder,
    GstElement * element, GstBuffer * buf)
{
  guint64 clip_start = 0, clip_stop = 0;
  gboolean in_seg;

  if (decoder->kate_flushing) {
    GST_LOG_OBJECT (element, "Kate pad flushing, buffer ignored");
    return FALSE;
  }

  if (G_LIKELY (GST_BUFFER_TIMESTAMP_IS_VALID (buf))) {
    GstClockTime stop;

    if (G_LIKELY (GST_BUFFER_DURATION_IS_VALID (buf)))
      stop = GST_BUFFER_TIMESTAMP (buf) + GST_BUFFER_DURATION (buf);
    else
      stop = GST_CLOCK_TIME_NONE;

    in_seg = gst_segment_clip (&decoder->kate_segment, GST_FORMAT_TIME,
        GST_BUFFER_TIMESTAMP (buf), stop, &clip_start, &clip_stop);
  } else {
    in_seg = TRUE;
  }

  if (in_seg) {
    if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
      decoder->kate_segment.position = clip_start;
    }
  } else {
    GST_INFO_OBJECT (element, "Kate buffer not in segment, ignored");
  }

  return in_seg;
}

static GstClockTime
gst_kate_util_granule_time (kate_state * k, gint64 granulepos)
{
  if (G_UNLIKELY (granulepos == -1))
    return -1;

  return kate_granule_time (k->ki, granulepos) * GST_SECOND;
}

/*
conversions on the sink:
  - default is granules at num/den rate (subject to the granule shift)
  - default -> time is possible
  - bytes do not mean anything, packets can be any number of bytes, and we
    have no way to know the number of bytes emitted without decoding
conversions on the source:
  - nothing
*/

gboolean
gst_kate_decoder_base_convert (GstKateDecoderBase * decoder,
    GstElement * element, GstPad * pad, GstFormat src_fmt, gint64 src_val,
    GstFormat * dest_fmt, gint64 * dest_val)
{
  gboolean res = FALSE;

  if (src_fmt == *dest_fmt) {
    *dest_val = src_val;
    return TRUE;
  }

  if (!decoder->initialized) {
    GST_WARNING_OBJECT (element, "not initialized yet");
    return FALSE;
  }

  if (src_fmt == GST_FORMAT_BYTES || *dest_fmt == GST_FORMAT_BYTES) {
    GST_WARNING_OBJECT (element, "unsupported format");
    return FALSE;
  }

  switch (src_fmt) {
    case GST_FORMAT_DEFAULT:
      switch (*dest_fmt) {
        case GST_FORMAT_TIME:
          *dest_val = gst_kate_util_granule_time (&decoder->k, src_val);
          res = TRUE;
          break;
        default:
          res = FALSE;
          break;
      }
      break;
    default:
      res = FALSE;
      break;
  }

  if (!res) {
    GST_WARNING_OBJECT (element, "unsupported format");
  }

  return res;
}

gboolean
gst_kate_decoder_base_sink_query (GstKateDecoderBase * decoder,
    GstElement * element, GstPad * pad, GstObject * parent, GstQuery * query)
{
  switch (GST_QUERY_TYPE (query)) {
    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 (!gst_kate_decoder_base_convert (decoder, element, pad, src_fmt,
              src_val, &dest_fmt, &dest_val)) {
        return gst_pad_query_default (pad, parent, query);
      }
      gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
      return TRUE;
    }
    default:
      return gst_pad_query_default (pad, parent, query);
  }
}

const char *
gst_kate_util_get_error_message (int ret)
{
  switch (ret) {
    case KATE_E_NOT_FOUND:
      return "value not found";
    case KATE_E_INVALID_PARAMETER:
      return "invalid parameter";
    case KATE_E_OUT_OF_MEMORY:
      return "out of memory";
    case KATE_E_BAD_GRANULE:
      return "bad granule";
    case KATE_E_INIT:
      return "initialization error";
    case KATE_E_BAD_PACKET:
      return "bad packet";
    case KATE_E_TEXT:
      return "invalid/truncated text";
    case KATE_E_LIMIT:
      return "a limit was exceeded";
    case KATE_E_VERSION:
      return "unsupported bitstream version";
    case KATE_E_NOT_KATE:
      return "not a kate bitstream";
    case KATE_E_BAD_TAG:
      return "bad tag";
    case KATE_E_IMPL:
      return "not implemented";

#ifdef HAVE_TIGER
    case TIGER_E_NOT_FOUND:
      return "value not found";
    case TIGER_E_INVALID_PARAMETER:
      return "invalid parameter";
    case TIGER_E_OUT_OF_MEMORY:
      return "out of memory";
    case TIGER_E_CAIRO_ERROR:
      return "Cairo error";
    case TIGER_E_BAD_SURFACE_TYPE:
      return "bad surface type";
#endif

    default:
      return "unknown error";
  }
}
