/* -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2 -*- */
/* Copyright 2005 Jan Schmidt <thaytan@mad.scientist.com>
 *           2006 Michael Smith <msmith@fluendo.com>
 * Copyright (C) 2003-2004 Benjamin Otte <otte@gnome.org>
 *
 * 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-icydemux
 *
 * icydemux accepts data streams with ICY metadata at known intervals, as
 * transmitted from an upstream element (usually read as response headers from
 * an HTTP stream). The mime type of the data between the tag blocks is
 * detected using typefind functions, and the appropriate output mime type set
 * on outgoing buffers. 
 *
 * <refsect2>
 * <title>Example launch line</title>
 * |[
 * gst-launch-1.0 souphttpsrc location=http://some.server/ iradio-mode=true ! icydemux ! fakesink -t
 * ]| This pipeline should read any available ICY tag information and output it.
 * The contents of the stream should be detected, and the appropriate mime
 * type set on buffers produced from icydemux. (Using gnomevfssrc, neonhttpsrc
 * or giosrc instead of souphttpsrc should also work.)
 * </refsect2>
 */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/gst.h>
#include <gst/gst-i18n-plugin.h>
#include <gst/tag/tag.h>

#include "gsticydemux.h"

#include <string.h>

#define ICY_TYPE_FIND_MAX_SIZE (40*1024)

GST_DEBUG_CATEGORY_STATIC (icydemux_debug);
#define GST_CAT_DEFAULT (icydemux_debug)

static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("application/x-icy, metadata-interval = (int)[0, MAX]")
    );

static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_SOMETIMES,
    GST_STATIC_CAPS ("ANY")
    );

static void gst_icydemux_dispose (GObject * object);

static GstFlowReturn gst_icydemux_chain (GstPad * pad, GstObject * parent,
    GstBuffer * buf);
static gboolean gst_icydemux_handle_event (GstPad * pad, GstObject * parent,
    GstEvent * event);

static gboolean gst_icydemux_add_srcpad (GstICYDemux * icydemux,
    GstCaps * new_caps);
static gboolean gst_icydemux_remove_srcpad (GstICYDemux * icydemux);

static GstStateChangeReturn gst_icydemux_change_state (GstElement * element,
    GstStateChange transition);
static gboolean gst_icydemux_sink_setcaps (GstPad * pad, GstCaps * caps);

static gboolean gst_icydemux_send_tag_event (GstICYDemux * icydemux,
    GstTagList * taglist);


#define gst_icydemux_parent_class parent_class
G_DEFINE_TYPE (GstICYDemux, gst_icydemux, GST_TYPE_ELEMENT);

static void
gst_icydemux_class_init (GstICYDemuxClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;

  gobject_class = (GObjectClass *) klass;
  gstelement_class = (GstElementClass *) klass;

  parent_class = g_type_class_ref (GST_TYPE_ELEMENT);

  gobject_class->dispose = gst_icydemux_dispose;

  gstelement_class->change_state = gst_icydemux_change_state;

  gst_element_class_add_static_pad_template (gstelement_class, &src_factory);
  gst_element_class_add_static_pad_template (gstelement_class, &sink_factory);

  gst_element_class_set_static_metadata (gstelement_class, "ICY tag demuxer",
      "Codec/Demuxer/Metadata",
      "Read and output ICY tags while demuxing the contents",
      "Jan Schmidt <thaytan@mad.scientist.com>, "
      "Michael Smith <msmith@fluendo.com>");
}

static void
gst_icydemux_reset (GstICYDemux * icydemux)
{
  /* Unknown at the moment (this is a fatal error if don't have a value by the
   * time we get to our chain function)
   */
  icydemux->meta_interval = -1;
  icydemux->remaining = 0;

  icydemux->typefinding = TRUE;

  gst_caps_replace (&(icydemux->src_caps), NULL);

  gst_icydemux_remove_srcpad (icydemux);

  if (icydemux->cached_tags) {
    gst_tag_list_unref (icydemux->cached_tags);
    icydemux->cached_tags = NULL;
  }

  if (icydemux->cached_events) {
    g_list_foreach (icydemux->cached_events,
        (GFunc) gst_mini_object_unref, NULL);
    g_list_free (icydemux->cached_events);
    icydemux->cached_events = NULL;
  }

  if (icydemux->meta_adapter) {
    gst_adapter_clear (icydemux->meta_adapter);
    g_object_unref (icydemux->meta_adapter);
    icydemux->meta_adapter = NULL;
  }

  if (icydemux->typefind_buf) {
    gst_buffer_unref (icydemux->typefind_buf);
    icydemux->typefind_buf = NULL;
  }

  if (icydemux->content_type) {
    g_free (icydemux->content_type);
    icydemux->content_type = NULL;
  }
}

static void
gst_icydemux_init (GstICYDemux * icydemux)
{
  GstElementClass *klass = GST_ELEMENT_GET_CLASS (icydemux);

  icydemux->sinkpad =
      gst_pad_new_from_template (gst_element_class_get_pad_template (klass,
          "sink"), "sink");
  gst_pad_set_chain_function (icydemux->sinkpad,
      GST_DEBUG_FUNCPTR (gst_icydemux_chain));
  gst_pad_set_event_function (icydemux->sinkpad,
      GST_DEBUG_FUNCPTR (gst_icydemux_handle_event));
  gst_element_add_pad (GST_ELEMENT (icydemux), icydemux->sinkpad);

  gst_icydemux_reset (icydemux);
}

static gboolean
gst_icydemux_sink_setcaps (GstPad * pad, GstCaps * caps)
{
  GstICYDemux *icydemux = GST_ICYDEMUX (GST_PAD_PARENT (pad));
  GstStructure *structure = gst_caps_get_structure (caps, 0);
  const gchar *tmp;

  if (!gst_structure_get_int (structure, "metadata-interval",
          &icydemux->meta_interval))
    return FALSE;

  /* If incoming caps have the HTTP Content-Type, copy that over */
  if ((tmp = gst_structure_get_string (structure, "content-type")))
    icydemux->content_type = g_strdup (tmp);

  /* We have a meta interval, so initialise the rest */
  icydemux->remaining = icydemux->meta_interval;
  icydemux->meta_remaining = 0;
  return TRUE;
}

static void
gst_icydemux_dispose (GObject * object)
{
  GstICYDemux *icydemux = GST_ICYDEMUX (object);

  gst_icydemux_reset (icydemux);

  G_OBJECT_CLASS (parent_class)->dispose (object);
}

typedef struct
{
  GstCaps *caps;
  GstPad *pad;
} CopyStickyEventsData;

static gboolean
copy_sticky_events (GstPad * pad, GstEvent ** event, gpointer user_data)
{
  CopyStickyEventsData *data = user_data;

  if (GST_EVENT_TYPE (*event) >= GST_EVENT_CAPS && data->caps) {
    gst_pad_set_caps (data->pad, data->caps);
    data->caps = NULL;
  }

  if (GST_EVENT_TYPE (*event) != GST_EVENT_CAPS)
    gst_pad_push_event (data->pad, gst_event_ref (*event));

  return TRUE;
}

static gboolean
gst_icydemux_add_srcpad (GstICYDemux * icydemux, GstCaps * new_caps)
{
  if (icydemux->src_caps == NULL ||
      !gst_caps_is_equal (new_caps, icydemux->src_caps)) {
    gst_caps_replace (&(icydemux->src_caps), new_caps);
    if (icydemux->srcpad != NULL) {
      GST_DEBUG_OBJECT (icydemux, "Changing src pad caps to %" GST_PTR_FORMAT,
          icydemux->src_caps);

      gst_pad_set_caps (icydemux->srcpad, icydemux->src_caps);
    }
  } else {
    /* Caps never changed */
    gst_caps_unref (new_caps);
  }

  if (icydemux->srcpad == NULL) {
    CopyStickyEventsData data;

    icydemux->srcpad =
        gst_pad_new_from_template (gst_element_class_get_pad_template
        (GST_ELEMENT_GET_CLASS (icydemux), "src"), "src");
    g_return_val_if_fail (icydemux->srcpad != NULL, FALSE);

    gst_pad_use_fixed_caps (icydemux->srcpad);
    gst_pad_set_active (icydemux->srcpad, TRUE);

    data.pad = icydemux->srcpad;
    data.caps = icydemux->src_caps;
    gst_pad_sticky_events_foreach (icydemux->sinkpad, copy_sticky_events,
        &data);
    if (data.caps)
      gst_pad_set_caps (data.pad, data.caps);

    GST_DEBUG_OBJECT (icydemux, "Adding src pad with caps %" GST_PTR_FORMAT,
        icydemux->src_caps);

    if (!(gst_element_add_pad (GST_ELEMENT (icydemux), icydemux->srcpad)))
      return FALSE;
    gst_element_no_more_pads (GST_ELEMENT (icydemux));
  }

  return TRUE;
}

static gboolean
gst_icydemux_remove_srcpad (GstICYDemux * icydemux)
{
  gboolean res = TRUE;

  if (icydemux->srcpad != NULL) {
    res = gst_element_remove_pad (GST_ELEMENT (icydemux), icydemux->srcpad);
    g_return_val_if_fail (res != FALSE, FALSE);
    icydemux->srcpad = NULL;
  }

  return res;
};

static gchar *
gst_icydemux_unicodify (const gchar * str)
{
  const gchar *env_vars[] = { "GST_ICY_TAG_ENCODING",
    "GST_TAG_ENCODING", NULL
  };

  return gst_tag_freeform_string_to_utf8 (str, -1, env_vars);
}

/* takes ownership of tag list */
static gboolean
gst_icydemux_tag_found (GstICYDemux * icydemux, GstTagList * tags)
{
  /* send the tag event if we have finished typefinding and have a src pad */
  if (icydemux->srcpad)
    return gst_icydemux_send_tag_event (icydemux, tags);

  /* if we haven't a source pad yet, cache the tags */
  if (!icydemux->cached_tags) {
    icydemux->cached_tags = tags;
  } else {
    gst_tag_list_insert (icydemux->cached_tags, tags,
        GST_TAG_MERGE_REPLACE_ALL);
    gst_tag_list_unref (tags);
  }

  return TRUE;
}

static void
gst_icydemux_parse_and_send_tags (GstICYDemux * icydemux)
{
  GstTagList *tags;
  const guint8 *data;
  int length, i;
  gchar *buffer;
  gchar **strings;

  length = gst_adapter_available (icydemux->meta_adapter);

  data = gst_adapter_map (icydemux->meta_adapter, length);

  /* Now, copy this to a buffer where we can NULL-terminate it to make things
   * a bit easier, then do that parsing. */
  buffer = g_strndup ((const gchar *) data, length);

  tags = gst_tag_list_new_empty ();
  strings = g_strsplit (buffer, "';", 0);

  for (i = 0; strings[i]; i++) {
    if (!g_ascii_strncasecmp (strings[i], "StreamTitle=", 12)) {
      char *title = gst_icydemux_unicodify (strings[i] + 13);

      if (title && *title) {
        gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, GST_TAG_TITLE,
            title, NULL);
        g_free (title);
      }
    } else if (!g_ascii_strncasecmp (strings[i], "StreamUrl=", 10)) {
      char *url = gst_icydemux_unicodify (strings[i] + 11);

      if (url && *url) {
        gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, GST_TAG_HOMEPAGE,
            url, NULL);
        g_free (url);
      }
    }
  }

  g_strfreev (strings);
  g_free (buffer);
  gst_adapter_unmap (icydemux->meta_adapter);
  gst_adapter_flush (icydemux->meta_adapter, length);

  if (!gst_tag_list_is_empty (tags))
    gst_icydemux_tag_found (icydemux, tags);
  else
    gst_tag_list_unref (tags);
}

static gboolean
gst_icydemux_handle_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  GstICYDemux *icydemux = GST_ICYDEMUX (parent);
  gboolean result;

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_TAG:
    {
      GstTagList *tags;

      gst_event_parse_tag (event, &tags);
      result = gst_icydemux_tag_found (icydemux, gst_tag_list_copy (tags));
      gst_event_unref (event);
      return result;
    }
    case GST_EVENT_CAPS:
    {
      GstCaps *caps;

      gst_event_parse_caps (event, &caps);
      result = gst_icydemux_sink_setcaps (pad, caps);
      gst_event_unref (event);
      return result;
    }
    default:
      break;
  }

  if (icydemux->typefinding) {
    switch (GST_EVENT_TYPE (event)) {
      case GST_EVENT_FLUSH_STOP:
        g_list_foreach (icydemux->cached_events,
            (GFunc) gst_mini_object_unref, NULL);
        g_list_free (icydemux->cached_events);
        icydemux->cached_events = NULL;

        return gst_pad_event_default (pad, parent, event);
      default:
        if (!GST_EVENT_IS_STICKY (event)) {
          icydemux->cached_events =
              g_list_append (icydemux->cached_events, event);
        } else {
          gst_event_unref (event);
        }
        return TRUE;
    }
  } else {
    return gst_pad_event_default (pad, parent, event);
  }
}

static void
gst_icydemux_send_cached_events (GstICYDemux * icydemux)
{
  GList *l;

  for (l = icydemux->cached_events; l != NULL; l = l->next) {
    GstEvent *event = GST_EVENT (l->data);

    gst_pad_push_event (icydemux->srcpad, event);
  }
  g_list_free (icydemux->cached_events);
  icydemux->cached_events = NULL;
}

static GstFlowReturn
gst_icydemux_typefind_or_forward (GstICYDemux * icydemux, GstBuffer * buf)
{
  if (icydemux->typefinding) {
    GstBuffer *tf_buf;
    GstCaps *caps = NULL;
    GstTypeFindProbability prob;

    /* If we have a content-type from upstream, let's see if we can shortcut
     * typefinding */
    if (G_UNLIKELY (icydemux->content_type)) {
      if (!g_ascii_strcasecmp (icydemux->content_type, "video/nsv")) {
        GST_DEBUG ("We have a NSV stream");
        caps = gst_caps_new_empty_simple ("video/x-nsv");
      } else {
        GST_DEBUG ("Upstream Content-Type isn't supported");
        g_free (icydemux->content_type);
        icydemux->content_type = NULL;
      }
    }

    if (icydemux->typefind_buf) {
      icydemux->typefind_buf = gst_buffer_append (icydemux->typefind_buf, buf);
    } else {
      icydemux->typefind_buf = buf;
    }

    /* Only typefind if we haven't already got some caps */
    if (caps == NULL) {
      caps = gst_type_find_helper_for_buffer (GST_OBJECT (icydemux),
          icydemux->typefind_buf, &prob);

      if (caps == NULL) {
        if (gst_buffer_get_size (icydemux->typefind_buf) <
            ICY_TYPE_FIND_MAX_SIZE) {
          /* Just break for more data */
          return GST_FLOW_OK;
        }

        /* We failed typefind */
        GST_ELEMENT_ERROR (icydemux, STREAM, TYPE_NOT_FOUND, (NULL),
            ("No caps found for contents within an ICY stream"));
        gst_buffer_unref (icydemux->typefind_buf);
        icydemux->typefind_buf = NULL;
        return GST_FLOW_ERROR;
      }
    }

    if (!gst_icydemux_add_srcpad (icydemux, caps)) {
      GST_DEBUG_OBJECT (icydemux, "Failed to add srcpad");
      gst_caps_unref (caps);
      gst_buffer_unref (icydemux->typefind_buf);
      icydemux->typefind_buf = NULL;
      return GST_FLOW_ERROR;
    }
    gst_caps_unref (caps);

    if (icydemux->cached_events) {
      gst_icydemux_send_cached_events (icydemux);
    }

    if (icydemux->cached_tags) {
      gst_icydemux_send_tag_event (icydemux, icydemux->cached_tags);
      icydemux->cached_tags = NULL;
    }

    /* Move onto streaming: call ourselves recursively with the typefind buffer
     * to get that forwarded. */
    icydemux->typefinding = FALSE;

    tf_buf = icydemux->typefind_buf;
    icydemux->typefind_buf = NULL;
    return gst_icydemux_typefind_or_forward (icydemux, tf_buf);
  } else {
    if (G_UNLIKELY (icydemux->srcpad == NULL)) {
      gst_buffer_unref (buf);
      return GST_FLOW_ERROR;
    }

    buf = gst_buffer_make_writable (buf);

    /* Most things don't care, and it's a pain to track (we should preserve a
     * 0 offset on the first buffer though if it's there, for id3demux etc.) */
    if (GST_BUFFER_OFFSET (buf) != 0) {
      GST_BUFFER_OFFSET (buf) = GST_BUFFER_OFFSET_NONE;
    }

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

static void
gst_icydemux_add_meta (GstICYDemux * icydemux, GstBuffer * buf)
{
  if (!icydemux->meta_adapter)
    icydemux->meta_adapter = gst_adapter_new ();

  gst_adapter_push (icydemux->meta_adapter, buf);
}

static GstFlowReturn
gst_icydemux_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
{
  GstICYDemux *icydemux;
  guint size, chunk, offset;
  GstBuffer *sub;
  GstFlowReturn ret = GST_FLOW_OK;

  icydemux = GST_ICYDEMUX (parent);

  if (G_UNLIKELY (icydemux->meta_interval < 0))
    goto not_negotiated;

  if (icydemux->meta_interval == 0) {
    ret = gst_icydemux_typefind_or_forward (icydemux, buf);
    buf = NULL;
    goto done;
  }

  /* Go through the buffer, chopping it into appropriate chunks. Forward as
   * tags or buffers, as appropriate
   */
  size = gst_buffer_get_size (buf);
  offset = 0;
  while (size) {
    if (icydemux->remaining) {
      chunk = (size <= icydemux->remaining) ? size : icydemux->remaining;
      if (offset == 0 && chunk == size) {
        sub = buf;
        buf = NULL;
      } else {
        sub = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL, offset, chunk);
      }
      offset += chunk;
      icydemux->remaining -= chunk;
      size -= chunk;

      /* This buffer goes onto typefinding, and/or directly pushed out */
      ret = gst_icydemux_typefind_or_forward (icydemux, sub);
      if (ret != GST_FLOW_OK)
        goto done;
    } else if (icydemux->meta_remaining) {
      chunk = (size <= icydemux->meta_remaining) ?
          size : icydemux->meta_remaining;
      sub = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL, offset, chunk);
      gst_icydemux_add_meta (icydemux, sub);

      offset += chunk;
      icydemux->meta_remaining -= chunk;
      size -= chunk;

      if (icydemux->meta_remaining == 0) {
        /* Parse tags from meta_adapter, send off as tag messages */
        GST_DEBUG_OBJECT (icydemux, "No remaining metadata, parsing for tags");
        gst_icydemux_parse_and_send_tags (icydemux);

        icydemux->remaining = icydemux->meta_interval;
      }
    } else {
      guint8 byte;
      /* We need to read a single byte (always safe at this point in the loop)
       * to figure out how many bytes of metadata exist. 
       * The 'spec' tells us to read 16 * (byte_value) bytes of metadata after
       * this (zero is common, and means the metadata hasn't changed).
       */
      gst_buffer_extract (buf, offset, &byte, 1);
      icydemux->meta_remaining = 16 * byte;
      if (icydemux->meta_remaining == 0)
        icydemux->remaining = icydemux->meta_interval;

      offset += 1;
      size -= 1;
    }
  }

done:
  if (buf)
    gst_buffer_unref (buf);

  return ret;

  /* ERRORS */
not_negotiated:
  {
    GST_WARNING_OBJECT (icydemux, "meta_interval not set, buffer probably had "
        "no caps set. Try enabling iradio-mode on the http source element");
    gst_buffer_unref (buf);
    return GST_FLOW_NOT_NEGOTIATED;
  }
}

static GstStateChangeReturn
gst_icydemux_change_state (GstElement * element, GstStateChange transition)
{
  GstStateChangeReturn ret;
  GstICYDemux *icydemux = GST_ICYDEMUX (element);

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

  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      gst_icydemux_reset (icydemux);
      break;
    default:
      break;
  }
  return ret;
}

/* takes ownership of tag list */
static gboolean
gst_icydemux_send_tag_event (GstICYDemux * icydemux, GstTagList * tags)
{
  GstEvent *event;

  event = gst_event_new_tag (tags);
  GST_EVENT_TIMESTAMP (event) = 0;

  GST_DEBUG_OBJECT (icydemux, "Sending tag event on src pad");
  return gst_pad_push_event (icydemux->srcpad, event);

}

static gboolean
plugin_init (GstPlugin * plugin)
{
  GST_DEBUG_CATEGORY_INIT (icydemux_debug, "icydemux", 0,
      "GStreamer ICY tag demuxer");

  return gst_element_register (plugin, "icydemux",
      GST_RANK_PRIMARY, GST_TYPE_ICYDEMUX);
}

GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
    GST_VERSION_MINOR,
    icydemux,
    "Demux ICY tags from a stream",
    plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
