/* GStreamer
 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
 *               <2002> Wim Taymans <wim.taymans@chello.be>
 *               <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.
 */

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

/* FIXME 0.11: suppress warnings for deprecated API such as GStaticRecMutex
 * with newer GLib versions (>= 2.31.0) */
#define GLIB_DISABLE_DEPRECATION_WARNINGS

#include <string.h>

#include "gstcdxaparse.h"
#include "gstvcdparse.h"

#include <gst/riff/riff-ids.h>
#include <gst/riff/riff-read.h>

GST_DEBUG_CATEGORY (vcdparse_debug);

GST_DEBUG_CATEGORY_STATIC (cdxaparse_debug);
#define GST_CAT_DEFAULT cdxaparse_debug

static gboolean gst_cdxa_parse_sink_activate (GstPad * sinkpad);
static void gst_cdxa_parse_loop (GstPad * sinkpad);
static gboolean gst_cdxa_parse_sink_activate_pull (GstPad * sinkpad,
    gboolean active);
static GstStateChangeReturn gst_cdxa_parse_change_state (GstElement * element,
    GstStateChange transition);
static gboolean gst_cdxa_parse_src_event (GstPad * srcpad, GstEvent * event);
static gboolean gst_cdxa_parse_src_query (GstPad * srcpad, GstQuery * query);

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

static GstStaticPadTemplate src_template_factory =
GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("video/mpeg, " "systemstream = (boolean) TRUE")
    );

GST_BOILERPLATE (GstCDXAParse, gst_cdxa_parse, GstElement, GST_TYPE_ELEMENT);

static void
gst_cdxa_parse_base_init (gpointer g_class)
{
  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);

  gst_element_class_set_static_metadata (element_class, "(S)VCD parser",
      "Codec/Parser",
      "Parse a .dat file from (S)VCD into raw MPEG-1",
      "Wim Taymans <wim.taymans@tvd.be>");

  /* register src pads */
  gst_element_class_add_static_pad_template (element_class,
      &sink_template_factory);
  gst_element_class_add_static_pad_template (element_class,
      &src_template_factory);
}

static void
gst_cdxa_parse_class_init (GstCDXAParseClass * klass)
{
  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);

  gstelement_class->change_state =
      GST_DEBUG_FUNCPTR (gst_cdxa_parse_change_state);
}

static void
gst_cdxa_parse_init (GstCDXAParse * cdxaparse, GstCDXAParseClass * klass)
{
  GstCaps *caps;

  cdxaparse->sinkpad =
      gst_pad_new_from_static_template (&sink_template_factory, "sink");
  gst_pad_set_activate_function (cdxaparse->sinkpad,
      GST_DEBUG_FUNCPTR (gst_cdxa_parse_sink_activate));
  gst_pad_set_activatepull_function (cdxaparse->sinkpad,
      GST_DEBUG_FUNCPTR (gst_cdxa_parse_sink_activate_pull));

  gst_element_add_pad (GST_ELEMENT (cdxaparse), cdxaparse->sinkpad);

  cdxaparse->srcpad =
      gst_pad_new_from_static_template (&src_template_factory, "src");

  gst_pad_set_event_function (cdxaparse->srcpad,
      GST_DEBUG_FUNCPTR (gst_cdxa_parse_src_event));
  gst_pad_set_query_function (cdxaparse->srcpad,
      GST_DEBUG_FUNCPTR (gst_cdxa_parse_src_query));

  caps = gst_caps_new_simple ("video/mpeg",
      "systemstream", G_TYPE_BOOLEAN, TRUE, NULL);
  gst_pad_use_fixed_caps (cdxaparse->srcpad);
  gst_pad_set_caps (cdxaparse->srcpad, caps);
  gst_caps_unref (caps);
  gst_element_add_pad (GST_ELEMENT (cdxaparse), cdxaparse->srcpad);


  cdxaparse->state = GST_CDXA_PARSE_START;
  cdxaparse->offset = 0;
  cdxaparse->datasize = 0;
  cdxaparse->datastart = -1;
}

#define HAVE_FOURCC(data,fourcc)  (GST_READ_UINT32_LE((data))==(fourcc))

static gboolean
gst_cdxa_parse_stream_init (GstCDXAParse * cdxa)
{
  GstFlowReturn flow_ret;
  GstBuffer *buf = NULL;
  guint8 *data;

  flow_ret = gst_pad_pull_range (cdxa->sinkpad, cdxa->offset, 12, &buf);
  if (flow_ret != GST_FLOW_OK)
    return flow_ret;

  if (GST_BUFFER_SIZE (buf) < 12)
    goto wrong_type;

  data = GST_BUFFER_DATA (buf);
  if (!HAVE_FOURCC (data, GST_RIFF_TAG_RIFF)) {
    GST_ERROR_OBJECT (cdxa, "Not a RIFF file");
    goto wrong_type;
  }

  if (!HAVE_FOURCC (data + 8, GST_RIFF_RIFF_CDXA)) {
    GST_ERROR_OBJECT (cdxa, "RIFF file does not have CDXA content");
    goto wrong_type;
  }

  cdxa->offset += 12;
  gst_buffer_unref (buf);

  return TRUE;

wrong_type:

  GST_ELEMENT_ERROR (cdxa, STREAM, WRONG_TYPE, (NULL), (NULL));
  gst_buffer_unref (buf);
  return FALSE;
}

static gboolean
gst_cdxa_parse_sink_activate (GstPad * sinkpad)
{
  GstCDXAParse *cdxa = GST_CDXA_PARSE (GST_PAD_PARENT (sinkpad));

  if (!gst_pad_check_pull_range (sinkpad) ||
      !gst_pad_activate_pull (sinkpad, TRUE)) {
    GST_DEBUG_OBJECT (cdxa, "No pull mode");
    return FALSE;
  }

  /* If we can activate pull_range upstream, then read the header
   * and see if it's really a RIFF CDXA file. */
  GST_DEBUG_OBJECT (cdxa, "Activated pull mode. Reading RIFF header");
  if (!gst_cdxa_parse_stream_init (cdxa))
    return FALSE;

  return TRUE;
}

static gboolean
gst_cdxa_parse_sink_activate_pull (GstPad * sinkpad, gboolean active)
{
  if (active) {
    /* if we have a scheduler we can start the task */
    gst_pad_start_task (sinkpad, (GstTaskFunction) gst_cdxa_parse_loop,
        sinkpad, NULL);
  } else {
    gst_pad_stop_task (sinkpad);
  }

  return TRUE;
}

/*
 * A sector is 2352 bytes long and is composed of:
 * 
 * !  sync    !  header ! subheader ! data ...   ! edc     !
 * ! 12 bytes ! 4 bytes ! 8 bytes   ! 2324 bytes ! 4 bytes !
 * !-------------------------------------------------------!
 * 
 * We strip the data out of it and send it to the srcpad.
 * 
 * sync : 00 FF FF FF FF FF FF FF FF FF FF 00
 * header : hour minute second mode
 * sub-header : track channel sub_mode coding repeat (4 bytes)
 * edc : checksum
 */

/* FIXME: use define from gstcdxastrip.h */
#define GST_CDXA_SECTOR_SIZE  	2352
#define GST_CDXA_DATA_SIZE  	2324
#define GST_CDXA_HEADER_SIZE	24

/* FIXME: use version from gstcdxastrip.c */
static GstBuffer *
gst_cdxa_parse_strip (GstBuffer * buf)
{
  GstBuffer *sub;

  g_assert (GST_BUFFER_SIZE (buf) >= GST_CDXA_SECTOR_SIZE);

  /* Skip CDXA headers, only keep data.
   * FIXME: check sync, resync, ... */
  sub = gst_buffer_create_sub (buf, GST_CDXA_HEADER_SIZE, GST_CDXA_DATA_SIZE);
  gst_buffer_unref (buf);

  return sub;
}

/* -1 = no sync (discard buffer),
 * otherwise offset indicates syncpoint in buffer.
 */

static gint
gst_cdxa_parse_sync (GstBuffer * buf)
{
  const guint8 sync_marker[12] = { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00
  };
  guint8 *data;
  guint size;

  size = GST_BUFFER_SIZE (buf);
  data = GST_BUFFER_DATA (buf);

  while (size >= 12) {
    if (memcmp (data, sync_marker, 12) == 0) {
      return (gint) (data - GST_BUFFER_DATA (buf));
    }
    --size;
    ++data;
  }
  return -1;
}

static void
gst_cdxa_parse_loop (GstPad * sinkpad)
{
  GstFlowReturn flow_ret;
  GstCDXAParse *cdxa;
  GstBuffer *buf = NULL;
  gint sync_offset = -1;

  cdxa = GST_CDXA_PARSE (GST_PAD_PARENT (sinkpad));

  if (cdxa->datasize <= 0) {
    GstFormat format = GST_FORMAT_BYTES;
    GstPad *peer;

    if ((peer = gst_pad_get_peer (sinkpad))) {
      if (!gst_pad_query_duration (peer, &format, &cdxa->datasize)) {
        GST_DEBUG_OBJECT (cdxa, "Failed to query upstream size!");
        gst_object_unref (peer);
        goto pause;
      }
      gst_object_unref (peer);
    }
    GST_DEBUG_OBJECT (cdxa, "Upstream size: %" G_GINT64_FORMAT, cdxa->datasize);
  }

  do {
    guint req;

    req = 8 + GST_CDXA_SECTOR_SIZE;     /* riff chunk header = 8 bytes */

    buf = NULL;
    flow_ret = gst_pad_pull_range (cdxa->sinkpad, cdxa->offset, req, &buf);

    if (flow_ret != GST_FLOW_OK) {
      GST_DEBUG_OBJECT (cdxa, "Pull flow: %s", gst_flow_get_name (flow_ret));
      goto pause;
    }

    if (GST_BUFFER_SIZE (buf) < req) {
      GST_DEBUG_OBJECT (cdxa, "Short read, only got %u/%u bytes",
          GST_BUFFER_SIZE (buf), req);
      goto eos;
    }

    sync_offset = gst_cdxa_parse_sync (buf);
    gst_buffer_unref (buf);
    buf = NULL;

    if (sync_offset >= 0)
      break;

    cdxa->offset += req;
    cdxa->bytes_skipped += req;
  } while (1);

  cdxa->offset += sync_offset;
  cdxa->bytes_skipped += sync_offset;

  /* first sync frame? */
  if (cdxa->datastart < 0) {
    GST_LOG_OBJECT (cdxa, "datastart=0x%" G_GINT64_MODIFIER "x", cdxa->offset);
    cdxa->datastart = cdxa->offset;
    cdxa->bytes_skipped = 0;
    cdxa->bytes_sent = 0;
  }

  GST_DEBUG_OBJECT (cdxa, "pulling buffer at offset 0x%" G_GINT64_MODIFIER "x",
      cdxa->offset);

  buf = NULL;
  flow_ret = gst_pad_pull_range (cdxa->sinkpad, cdxa->offset,
      GST_CDXA_SECTOR_SIZE, &buf);

  if (flow_ret != GST_FLOW_OK) {
    GST_DEBUG_OBJECT (cdxa, "Flow: %s", gst_flow_get_name (flow_ret));
    goto pause;
  }

  if (GST_BUFFER_SIZE (buf) < GST_CDXA_SECTOR_SIZE) {
    GST_DEBUG_OBJECT (cdxa, "Short read, only got %u/%u bytes",
        GST_BUFFER_SIZE (buf), GST_CDXA_SECTOR_SIZE);
    goto eos;
  }

  buf = gst_cdxa_parse_strip (buf);

  GST_DEBUG_OBJECT (cdxa, "pushing buffer %p", buf);
  gst_buffer_set_caps (buf, GST_PAD_CAPS (cdxa->srcpad));

  cdxa->offset += GST_BUFFER_SIZE (buf);
  cdxa->bytes_sent += GST_BUFFER_SIZE (buf);

  flow_ret = gst_pad_push (cdxa->srcpad, buf);
  if (flow_ret != GST_FLOW_OK) {
    GST_DEBUG_OBJECT (cdxa, "Push flow: %s", gst_flow_get_name (flow_ret));
    goto pause;
  }

  return;

eos:
  {
    GST_DEBUG_OBJECT (cdxa, "Sending EOS");
    if (buf)
      gst_buffer_unref (buf);
    buf = NULL;
    gst_pad_push_event (cdxa->srcpad, gst_event_new_eos ());
    /* fallthrough */
  }
pause:
  {
    GST_DEBUG_OBJECT (cdxa, "Pausing");
    gst_pad_pause_task (cdxa->sinkpad);
    return;
  }
}

static gint64
gst_cdxa_parse_convert_src_to_sink_offset (GstCDXAParse * cdxa, gint64 src)
{
  gint64 sink;

  sink = src + cdxa->datastart;
  sink = gst_util_uint64_scale (sink, GST_CDXA_SECTOR_SIZE, GST_CDXA_DATA_SIZE);

  /* FIXME: take into account skipped bytes */

  GST_DEBUG_OBJECT (cdxa, "src offset=%" G_GINT64_FORMAT ", sink offset=%"
      G_GINT64_FORMAT, src, sink);

  return sink;
}

static gint64
gst_cdxa_parse_convert_sink_to_src_offset (GstCDXAParse * cdxa, gint64 sink)
{
  gint64 src;

  src = sink - cdxa->datastart;
  src = gst_util_uint64_scale (src, GST_CDXA_DATA_SIZE, GST_CDXA_SECTOR_SIZE);

  /* FIXME: take into account skipped bytes */

  GST_DEBUG_OBJECT (cdxa, "sink offset=%" G_GINT64_FORMAT ", src offset=%"
      G_GINT64_FORMAT, sink, src);

  return src;
}

static gboolean
gst_cdxa_parse_do_seek (GstCDXAParse * cdxa, GstEvent * event)
{
  GstSeekFlags flags;
  GstSeekType start_type;
  GstFormat format;
  gint64 start, off, upstream_size;

  gst_event_parse_seek (event, NULL, &format, &flags, &start_type, &start,
      NULL, NULL);

  if (format != GST_FORMAT_BYTES) {
    GST_DEBUG_OBJECT (cdxa, "Can only handle seek in BYTES format");
    return FALSE;
  }

  if (start_type != GST_SEEK_TYPE_SET) {
    GST_DEBUG_OBJECT (cdxa, "Can only handle seek from start (SEEK_TYPE_SET)");
    return FALSE;
  }

  GST_OBJECT_LOCK (cdxa);
  off = gst_cdxa_parse_convert_src_to_sink_offset (cdxa, start);
  upstream_size = cdxa->datasize;
  GST_OBJECT_UNLOCK (cdxa);

  if (off >= upstream_size) {
    GST_DEBUG_OBJECT (cdxa, "Invalid target offset %" G_GINT64_FORMAT ", file "
        "is only %" G_GINT64_FORMAT " bytes in size", off, upstream_size);
    return FALSE;
  }

  /* unlock upstream pull_range */
  gst_pad_push_event (cdxa->sinkpad, gst_event_new_flush_start ());

  /* make sure our loop function exits */
  gst_pad_push_event (cdxa->srcpad, gst_event_new_flush_start ());

  /* wait for streaming to finish */
  GST_PAD_STREAM_LOCK (cdxa->sinkpad);

  /* prepare for streaming again */
  gst_pad_push_event (cdxa->sinkpad, gst_event_new_flush_stop ());
  gst_pad_push_event (cdxa->srcpad, gst_event_new_flush_stop ());

  gst_pad_push_event (cdxa->srcpad,
      gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_BYTES,
          start, GST_CLOCK_TIME_NONE, 0));

  GST_OBJECT_LOCK (cdxa);
  cdxa->offset = off;
  GST_OBJECT_UNLOCK (cdxa);

  /* and restart */
  gst_pad_start_task (cdxa->sinkpad,
      (GstTaskFunction) gst_cdxa_parse_loop, cdxa->sinkpad, NULL);

  GST_PAD_STREAM_UNLOCK (cdxa->sinkpad);
  return TRUE;
}

static gboolean
gst_cdxa_parse_src_event (GstPad * srcpad, GstEvent * event)
{
  GstCDXAParse *cdxa = GST_CDXA_PARSE (gst_pad_get_parent (srcpad));
  gboolean res = FALSE;

  GST_DEBUG_OBJECT (cdxa, "Handling %s event", GST_EVENT_TYPE_NAME (event));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEEK:
      res = gst_cdxa_parse_do_seek (cdxa, event);
      break;
    default:
      res = gst_pad_event_default (srcpad, event);
      break;
  }

  gst_object_unref (cdxa);
  return res;
}

static gboolean
gst_cdxa_parse_src_query (GstPad * srcpad, GstQuery * query)
{
  GstCDXAParse *cdxa = GST_CDXA_PARSE (gst_pad_get_parent (srcpad));
  gboolean res = FALSE;

  GST_DEBUG_OBJECT (cdxa, "Handling %s query",
      gst_query_type_get_name (GST_QUERY_TYPE (query)));

  res = gst_pad_query_default (srcpad, query);

  if (res) {
    GstFormat format;
    gint64 val;

    switch (GST_QUERY_TYPE (query)) {
      case GST_QUERY_DURATION:
        gst_query_parse_duration (query, &format, &val);
        if (format == GST_FORMAT_BYTES) {
          val = gst_cdxa_parse_convert_sink_to_src_offset (cdxa, val);
          gst_query_set_duration (query, format, val);
        }
        break;
      case GST_QUERY_POSITION:
        gst_query_parse_position (query, &format, &val);
        if (format == GST_FORMAT_BYTES) {
          val = gst_cdxa_parse_convert_sink_to_src_offset (cdxa, val);
          gst_query_set_position (query, format, val);
        }
        break;
      default:
        break;
    }
  }

  gst_object_unref (cdxa);
  return res;
}

static GstStateChangeReturn
gst_cdxa_parse_change_state (GstElement * element, GstStateChange transition)
{
  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
  GstCDXAParse *cdxa = GST_CDXA_PARSE (element);

  switch (transition) {
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      cdxa->state = GST_CDXA_PARSE_START;
      break;
    default:
      break;
  }

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

  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      cdxa->state = GST_CDXA_PARSE_START;
      cdxa->datasize = 0;
      cdxa->datastart = -1;
      break;
    default:
      break;
  }

  return ret;
}

static gboolean
plugin_init (GstPlugin * plugin)
{
  GST_DEBUG_CATEGORY_INIT (cdxaparse_debug, "cdxaparse", 0, "CDXA Parser");
  GST_DEBUG_CATEGORY_INIT (vcdparse_debug, "vcdparse", 0, "VCD Parser");

  if (!gst_element_register (plugin, "cdxaparse", GST_RANK_PRIMARY,
          GST_TYPE_CDXA_PARSE))
    return FALSE;
  if (!gst_element_register (plugin, "vcdparse", GST_RANK_PRIMARY,
          GST_TYPE_VCD_PARSE))
    return FALSE;

  return TRUE;
}

GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
    GST_VERSION_MINOR,
    cdxaparse,
    "Parse a .dat file (VCD) into raw mpeg1",
    plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
