/* GStreamer SSA subtitle parser
 * Copyright (c) 2006 Tim-Philipp Müller <tim centricular net>
 *
 * 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.
 */

/* Super-primitive SSA parser - we just want the text and ignore
 * everything else like styles and timing codes etc. for now */

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

#include <stdlib.h>             /* atoi() */
#include <string.h>

#include "gstssaparse.h"

GST_DEBUG_CATEGORY_STATIC (ssa_parse_debug);
#define GST_CAT_DEFAULT ssa_parse_debug

static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("application/x-ssa; application/x-ass")
    );

static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("text/x-raw, format=pango-markup")
    );

#define gst_ssa_parse_parent_class parent_class
G_DEFINE_TYPE (GstSsaParse, gst_ssa_parse, GST_TYPE_ELEMENT);

static GstStateChangeReturn gst_ssa_parse_change_state (GstElement *
    element, GstStateChange transition);
static gboolean gst_ssa_parse_setcaps (GstPad * sinkpad, GstCaps * caps);
static gboolean gst_ssa_parse_src_event (GstPad * pad, GstObject * parent,
    GstEvent * event);
static gboolean gst_ssa_parse_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * event);
static GstFlowReturn gst_ssa_parse_chain (GstPad * sinkpad, GstObject * parent,
    GstBuffer * buf);

static void
gst_ssa_parse_dispose (GObject * object)
{
  GstSsaParse *parse = GST_SSA_PARSE (object);

  g_free (parse->ini);
  parse->ini = NULL;

  GST_CALL_PARENT (G_OBJECT_CLASS, dispose, (object));
}

static void
gst_ssa_parse_init (GstSsaParse * parse)
{
  parse->sinkpad = gst_pad_new_from_static_template (&sink_templ, "sink");
  gst_pad_set_chain_function (parse->sinkpad,
      GST_DEBUG_FUNCPTR (gst_ssa_parse_chain));
  gst_pad_set_event_function (parse->sinkpad,
      GST_DEBUG_FUNCPTR (gst_ssa_parse_sink_event));
  gst_element_add_pad (GST_ELEMENT (parse), parse->sinkpad);

  parse->srcpad = gst_pad_new_from_static_template (&src_templ, "src");
  gst_pad_set_event_function (parse->srcpad,
      GST_DEBUG_FUNCPTR (gst_ssa_parse_src_event));
  gst_element_add_pad (GST_ELEMENT (parse), parse->srcpad);
  gst_pad_use_fixed_caps (parse->srcpad);

  parse->ini = NULL;
  parse->framed = FALSE;
  parse->send_tags = FALSE;
}

static void
gst_ssa_parse_class_init (GstSsaParseClass * klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);

  object_class->dispose = gst_ssa_parse_dispose;

  gst_element_class_add_static_pad_template (element_class, &sink_templ);
  gst_element_class_add_static_pad_template (element_class, &src_templ);
  gst_element_class_set_static_metadata (element_class,
      "SSA Subtitle Parser", "Codec/Parser/Subtitle",
      "Parses SSA subtitle streams",
      "Tim-Philipp Müller <tim centricular net>");

  GST_DEBUG_CATEGORY_INIT (ssa_parse_debug, "ssaparse", 0,
      "SSA subtitle parser");

  element_class->change_state = GST_DEBUG_FUNCPTR (gst_ssa_parse_change_state);
}

static gboolean
gst_ssa_parse_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  return gst_pad_event_default (pad, parent, event);
}

static gboolean
gst_ssa_parse_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  gboolean res;

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_CAPS:
    {
      GstCaps *caps;

      gst_event_parse_caps (event, &caps);
      res = gst_ssa_parse_setcaps (pad, caps);
      gst_event_unref (event);
      break;
    }
    default:
      res = gst_pad_event_default (pad, parent, event);
      break;
  }
  return res;
}

static gboolean
gst_ssa_parse_setcaps (GstPad * sinkpad, GstCaps * caps)
{
  GstSsaParse *parse = GST_SSA_PARSE (GST_PAD_PARENT (sinkpad));
  GstCaps *outcaps;
  const GValue *val;
  GstStructure *s;
  const guchar bom_utf8[] = { 0xEF, 0xBB, 0xBF };
  const gchar *end;
  GstBuffer *priv;
  GstMapInfo map;
  gchar *ptr;
  gsize left, bad_offset;
  gboolean ret;

  s = gst_caps_get_structure (caps, 0);
  val = gst_structure_get_value (s, "codec_data");
  if (val == NULL) {
    parse->framed = FALSE;
    GST_ERROR ("Only SSA subtitles embedded in containers are supported");
    return FALSE;
  }

  parse->framed = TRUE;
  parse->send_tags = TRUE;

  priv = (GstBuffer *) g_value_get_boxed (val);
  g_return_val_if_fail (priv != NULL, FALSE);

  gst_buffer_ref (priv);

  if (!gst_buffer_map (priv, &map, GST_MAP_READ)) {
    gst_buffer_unref (priv);
    return FALSE;
  }

  GST_MEMDUMP_OBJECT (parse, "init section", map.data, map.size);

  ptr = (gchar *) map.data;
  left = map.size;

  /* skip UTF-8 BOM */
  if (left >= 3 && memcmp (ptr, bom_utf8, 3) == 0) {
    ptr += 3;
    left -= 3;
  }

  if (!strstr (ptr, "[Script Info]"))
    goto invalid_init;

  if (!g_utf8_validate (ptr, left, &end)) {
    bad_offset = (gsize) (end - ptr);
    GST_WARNING_OBJECT (parse, "Init section is not valid UTF-8. Problem at "
        "byte offset %" G_GSIZE_FORMAT, bad_offset);
    /* continue with valid UTF-8 data */
    left = bad_offset;
  }

  /* FIXME: parse initial section */
  if (parse->ini)
    g_free (parse->ini);
  parse->ini = g_strndup (ptr, left);
  GST_LOG_OBJECT (parse, "Init section:\n%s", parse->ini);

  gst_buffer_unmap (priv, &map);
  gst_buffer_unref (priv);

  outcaps = gst_caps_new_simple ("text/x-raw",
      "format", G_TYPE_STRING, "pango-markup", NULL);

  ret = gst_pad_set_caps (parse->srcpad, outcaps);
  gst_caps_unref (outcaps);

  return ret;

  /* ERRORS */
invalid_init:
  {
    GST_WARNING_OBJECT (parse, "Invalid Init section - no Script Info header");
    gst_buffer_unmap (priv, &map);
    gst_buffer_unref (priv);
    return FALSE;
  }
}

static gboolean
gst_ssa_parse_remove_override_codes (GstSsaParse * parse, gchar * txt)
{
  gchar *t, *end;
  gboolean removed_any = FALSE;

  while ((t = strchr (txt, '{'))) {
    end = strchr (txt, '}');
    if (end == NULL) {
      GST_WARNING_OBJECT (parse, "Missing { for style override code");
      return removed_any;
    }
    /* move terminating NUL character forward as well */
    memmove (t, end + 1, strlen (end + 1) + 1);
    removed_any = TRUE;
  }

  /* these may occur outside of curly brackets. We don't handle the different
   * wrapping modes yet, so just remove these markers from the text for now */
  while ((t = strstr (txt, "\\n"))) {
    t[0] = ' ';
    t[1] = '\n';
  }
  while ((t = strstr (txt, "\\N"))) {
    t[0] = ' ';
    t[1] = '\n';
  }
  while ((t = strstr (txt, "\\h"))) {
    t[0] = ' ';
    t[1] = ' ';
  }

  return removed_any;
}

/**
 * gst_ssa_parse_push_line:
 * @parse: caller element
 * @txt: text to push
 * @size: text size need to be parse
 * @start: timestamp for the buffer
 * @duration: duration for the buffer
 *
 * Parse the text in a buffer with the given properties and
 * push it to the srcpad of the @parse element
 *
 * Returns: result of the push of the created buffer
 */
static GstFlowReturn
gst_ssa_parse_push_line (GstSsaParse * parse, gchar * txt, gint size,
    GstClockTime start, GstClockTime duration)
{
  GstFlowReturn ret;
  GstBuffer *buf;
  gchar *t, *text, *p, *escaped, *p_start, *p_end;
  gint num, i, len;
  GstClockTime start_time = G_MAXUINT64, end_time = 0;

  p = text = g_malloc(size + 1);
  *p = '\0';
  t = txt;

  /* there are may have multiple dialogue lines at a time */
  while (*t) {
    /* ignore leading white space characters */
    while (isspace(*t))
      t++;

    /* ignore Format: and Style: lines */
    if (strncmp(t, "Format:", 7) == 0 || strncmp(t, "Style:", 6) == 0) {
      while (*t != '\0' && *t != '\n') {
        t++;
      }
    }

    if (*t == '\0')
      break;

    /* continue with next line */
    if (*t == '\n') {
      t++;
      continue;
    }

    if(strncmp(t, "Dialogue:", 9) != 0) {
      /* not started with "Dialogue:", it must be a line trimmed by demuxer */
      num = atoi (t);
      GST_LOG_OBJECT (parse, "Parsing line #%d at %" GST_TIME_FORMAT,
          num, GST_TIME_ARGS (start));

      /* skip all non-text fields before the actual text */
      for (i = 0; i < 8; ++i) {
        t = strchr (t, ',');
        if (t == NULL)
          break;
        ++t;
      }
    } else {
      /* started with "Dialogue:", update timestamp and duration */
      /* time format are like Dialog:Mark,0:00:01.02,0:00:03.04,xx,xxx,... */
      guint hour, min, sec, msec, len;
      GstClockTime tmp;
      gchar t_str[12] = {0};

      /* find the first ',' */
      p_start = strchr (t, ',');
      if (p_start)
        p_end = strchr (++p_start, ',');

      if (p_start && p_end) {
        /* copy text between first ',' and second ',' */
        strncpy(t_str, p_start, p_end - p_start);
        if (sscanf (t_str, "%u:%u:%u.%u", &hour, &min, &sec, &msec) == 4) {
          tmp = ((hour*3600) + (min*60) + sec) * GST_SECOND + msec*GST_MSECOND;
          GST_DEBUG_OBJECT (parse, "Get start time:%02d:%02d:%02d:%03d\n",
              hour, min, sec, msec);
          if (start_time > tmp)
            start_time = tmp;
        } else {
          GST_WARNING_OBJECT (parse,
              "failed to parse ssa start timestamp string :%s", t_str);
        }

        p_start = p_end;
        p_end = strchr (++p_start, ',');
        if (p_end) {
          /* copy text between second ',' and third ',' */
          strncpy(t_str, p_start, p_end - p_start);
          if (sscanf (t_str, "%u:%u:%u.%u", &hour, &min, &sec, &msec) == 4) {
            tmp = ((hour*3600) + (min*60) + sec)*GST_SECOND + msec*GST_MSECOND;
            GST_DEBUG_OBJECT(parse, "Get end time:%02d:%02d:%02d:%03d\n",
                hour, min, sec, msec);
            if (end_time < tmp)
              end_time = tmp;
          } else {
            GST_WARNING_OBJECT (parse,
                "failed to parse ssa end timestamp string :%s", t_str);
          }
        }
      }

      /* now skip all non-text fields before the actual text */
      for (i = 0; i <= 8; ++i) {
        t = strchr (t, ',');
        if (t == NULL)
          break;
        ++t;
      }
    }

    /* line end before expected number of ',', not a Dialogue line */
    if (t == NULL)
      break;

    /* if not the first line, and the last character of previous line is '\0',
     * then replace it with '\N' */
    if (p != text && *p == '\0') {
      *p++ = '\\';
      *p++ = 'N';
    }

    /* copy all actual text of this line */
    while ((*t != '\0') && (*t != '\n'))
      *p++ = *t++;

    /* add a terminator at the end */
    *p = '\0';
  }

  /* not valid text found in this buffer return OK to let caller unref buffer */
  if (strlen(text) <= 0) {
    GST_WARNING_OBJECT (parse, "Not valid text found in this buffer\n");
    return GST_FLOW_ERROR;
  }

  t = text;
  GST_LOG_OBJECT (parse, "Text : %s", t);

  if (gst_ssa_parse_remove_override_codes (parse, t)) {
    GST_LOG_OBJECT (parse, "Clean: %s", t);
  }

  /* we claim to output pango markup, so we must escape the
   * text even if we don't actually use any pango markup yet */
  escaped = g_markup_printf_escaped ("%s", t);

  len = strlen (escaped);

  /* allocate enough for a terminating NUL, but don't include it in buf size */
  buf = gst_buffer_new_and_alloc (len + 1);
  gst_buffer_fill (buf, 0, escaped, len + 1);
  gst_buffer_set_size (buf, len);
  g_free (escaped);
  g_free(t);

  if (start_time != G_MAXUINT64)
    GST_BUFFER_TIMESTAMP (buf) = start_time;
  else
    GST_BUFFER_TIMESTAMP (buf) = start;

  if (end_time > start_time)
    GST_BUFFER_DURATION (buf) = end_time - start_time;
  else
    GST_BUFFER_DURATION (buf) = duration;

  GST_LOG_OBJECT (parse, "Pushing buffer with timestamp %" GST_TIME_FORMAT
      " and duration %" GST_TIME_FORMAT,
      GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
      GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));

  ret = gst_pad_push (parse->srcpad, buf);

  if (ret != GST_FLOW_OK) {
    GST_DEBUG_OBJECT (parse, "Push of text '%s' returned flow %s", txt,
        gst_flow_get_name (ret));
  }

  return ret;
}

static GstFlowReturn
gst_ssa_parse_chain (GstPad * sinkpad, GstObject * parent, GstBuffer * buf)
{
  GstFlowReturn ret;
  GstSsaParse *parse = GST_SSA_PARSE (parent);
  GstClockTime ts;
  gchar *txt;
  GstMapInfo map;
  gint size;

  if (G_UNLIKELY (!parse->framed))
    goto not_framed;

  if (G_UNLIKELY (parse->send_tags)) {
    GstTagList *tags;

    tags = gst_tag_list_new_empty ();
    gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_SUBTITLE_CODEC,
        "SubStation Alpha", NULL);
    gst_pad_push_event (parse->srcpad, gst_event_new_tag (tags));
    parse->send_tags = FALSE;
  }

  /* make double-sure it's 0-terminated and all */
  gst_buffer_map (buf, &map, GST_MAP_READ);
  txt = g_strndup ((gchar *) map.data, map.size);
  size = map.size;
  gst_buffer_unmap (buf, &map);

  if (txt == NULL)
    goto empty_text;

  ts = GST_BUFFER_TIMESTAMP (buf);
  ret = gst_ssa_parse_push_line (parse, txt, size, ts, GST_BUFFER_DURATION (buf));

  if (ret != GST_FLOW_OK && GST_CLOCK_TIME_IS_VALID (ts)) {
    GstSegment segment;

    /* just advance time without sending anything */
    gst_segment_init (&segment, GST_FORMAT_TIME);
    segment.start = ts;
    segment.time = ts;
    gst_pad_push_event (parse->srcpad, gst_event_new_segment (&segment));
    ret = GST_FLOW_OK;
  }

  gst_buffer_unref (buf);
  g_free (txt);

  return ret;

/* ERRORS */
not_framed:
  {
    GST_ELEMENT_ERROR (parse, STREAM, FORMAT, (NULL),
        ("Only SSA subtitles embedded in containers are supported"));
    gst_buffer_unref (buf);
    return GST_FLOW_NOT_NEGOTIATED;
  }
empty_text:
  {
    GST_ELEMENT_WARNING (parse, STREAM, FORMAT, (NULL),
        ("Received empty subtitle"));
    gst_buffer_unref (buf);
    return GST_FLOW_OK;
  }
}

static GstStateChangeReturn
gst_ssa_parse_change_state (GstElement * element, GstStateChange transition)
{
  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
  GstSsaParse *parse = GST_SSA_PARSE (element);

  switch (transition) {
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      break;
    default:
      break;
  }

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

  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      g_free (parse->ini);
      parse->ini = NULL;
      parse->framed = FALSE;
      break;
    default:
      break;
  }

  return ret;
}
