/* GStreamer APEv1/2 tag reader
 * Copyright (C) 2004 Ronald Bultje <rbultje@ronald.bitfreak.net>
 * 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

/**
 * SECTION:element-apedemux
 *
 * apedemux accepts data streams with APE tags at the start or at the end
 * (or both). 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.
 *
 * The element is only able to read APE tags at the end of a stream from
 * a seekable stream, ie. when get_range mode is supported by the upstream
 * elements. If get_range operation is available, apedemux makes it available
 * downstream. This means that elements which require get_range mode, such as
 * wavparse or musepackdec, can operate on files containing APE tag
 * information.
 *
 * <refsect2>
 * <title>Example launch line</title>
 * |[
 * gst-launch -t filesrc location=file.mpc ! apedemux ! fakesink
 * ]| This pipeline should read any available APE tag information and output it.
 * The contents of the file inside the APE tag regions should be detected, and
 * the appropriate mime type set on buffers produced from apedemux.
 * </refsect2>
 */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <gst/gst.h>
#include <gst/gst-i18n-plugin.h>
#include <gst/pbutils/pbutils.h>

#include "gstapedemux.h"

#include <stdio.h>
#include <string.h>

#define APE_VERSION_MAJOR(ver)  ((ver)/1000)

GST_DEBUG_CATEGORY_STATIC (apedemux_debug);
#define GST_CAT_DEFAULT (apedemux_debug)

static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("application/x-apetag")
    );

static gboolean gst_ape_demux_identify_tag (GstTagDemux * demux,
    GstBuffer * buffer, gboolean start_tag, guint * tag_size);
static GstTagDemuxResult gst_ape_demux_parse_tag (GstTagDemux * demux,
    GstBuffer * buffer, gboolean start_tag, guint * tag_size,
    GstTagList ** tags);

G_DEFINE_TYPE (GstApeDemux, gst_ape_demux, GST_TYPE_TAG_DEMUX);

static void
gst_ape_demux_class_init (GstApeDemuxClass * klass)
{
  GstElementClass *element_class;
  GstTagDemuxClass *tagdemux_class;

  GST_DEBUG_CATEGORY_INIT (apedemux_debug, "apedemux", 0,
      "GStreamer APE tag demuxer");

  tagdemux_class = GST_TAG_DEMUX_CLASS (klass);
  element_class = GST_ELEMENT_CLASS (klass);

  gst_element_class_set_static_metadata (element_class, "APE tag demuxer",
      "Codec/Demuxer/Metadata",
      "Read and output APE tags while demuxing the contents",
      "Tim-Philipp Müller <tim centricular net>");

  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&sink_factory));

  tagdemux_class->identify_tag = GST_DEBUG_FUNCPTR (gst_ape_demux_identify_tag);
  tagdemux_class->parse_tag = GST_DEBUG_FUNCPTR (gst_ape_demux_parse_tag);

  /* no need for a merge function, the default behaviour to prefer start
   * tags (APEv2) over end tags (usually APEv1, but could theoretically also
   * be APEv2) is fine */

  tagdemux_class->min_start_size = 32;
  tagdemux_class->min_end_size = 32;
}

static void
gst_ape_demux_init (GstApeDemux * apedemux)
{
  /* nothing to do here */
}

static const struct _GstApeDemuxTagTableEntry
{
  const gchar *ape_tag;
  const gchar *gst_tag;
} tag_table[] = {
  {
  "replaygain_track_gain", GST_TAG_TRACK_GAIN}, {
  "replaygain_track_peak", GST_TAG_TRACK_PEAK}, {
  "replaygain_album_gain", GST_TAG_ALBUM_GAIN}, {
  "replaygain_album_peak", GST_TAG_ALBUM_PEAK}, {
  "title", GST_TAG_TITLE}, {
  "artist", GST_TAG_ARTIST}, {
  "album", GST_TAG_ALBUM}, {
  "composer", GST_TAG_COMPOSER}, {
  "comment", GST_TAG_COMMENT}, {
  "comments", GST_TAG_COMMENT}, {
  "copyright", GST_TAG_COPYRIGHT}, {
  "genre", GST_TAG_GENRE}, {
  "isrc", GST_TAG_ISRC}, {
  "disc", GST_TAG_ALBUM_VOLUME_NUMBER}, {
  "disk", GST_TAG_ALBUM_VOLUME_NUMBER}, {
  "discnumber", GST_TAG_ALBUM_VOLUME_NUMBER}, {
  "disknumber", GST_TAG_ALBUM_VOLUME_NUMBER}, {
  "track", GST_TAG_TRACK_NUMBER}, {
  "tracknumber", GST_TAG_TRACK_NUMBER}, {
  "year", GST_TAG_DATE}, {
  "file", GST_TAG_LOCATION}
};

static gboolean
ape_demux_get_gst_tag_from_tag (const gchar * ape_tag,
    const gchar ** gst_tag, GType * gst_tag_type)
{
  gint i;

  for (i = 0; i < G_N_ELEMENTS (tag_table); ++i) {
    if (g_ascii_strcasecmp (tag_table[i].ape_tag, ape_tag) == 0) {
      *gst_tag = tag_table[i].gst_tag;
      *gst_tag_type = gst_tag_get_type (tag_table[i].gst_tag);
      GST_LOG ("Mapped APE tag '%s' to GStreamer tag '%s'", ape_tag, *gst_tag);
      return TRUE;
    }
  }

  GST_WARNING ("Could not map APE tag '%s' to a GStreamer tag", ape_tag);
  return FALSE;
}

static GstTagList *
ape_demux_parse_tags (const guint8 * data, gint size)
{
  GstTagList *taglist = gst_tag_list_new_empty ();

  GST_LOG ("Reading tags from chunk of size %u bytes", size);

  /* get rid of header/footer */
  if (size >= 32 && memcmp (data, "APETAGEX", 8) == 0) {
    data += 32;
    size -= 32;
  }
  if (size > 32 && memcmp (data + size - 32, "APETAGEX", 8) == 0) {
    size -= 32;
  }

  /* read actual tags - at least 10 bytes for tag header */
  while (size >= 10) {
    guint len, n = 8;
    gchar *tag, *val;
    const gchar *gst_tag;
    GType gst_tag_type;

    /* find tag type and size */
    len = GST_READ_UINT32_LE (data);
    while (n < size && data[n] != 0x0)
      n++;
    if (n == size)
      break;
    g_assert (data[n] == 0x0);
    n++;
    if (size - n < len)
      break;

    /* If the tag is empty, skip to the next one */
    if (len == 0)
      goto next_tag;

    /* read */
    tag = g_strndup ((gchar *) data + 8, n - 9);
    val = g_strndup ((gchar *) data + n, len);

    GST_LOG ("tag [%s], val[%s]", tag, val);

    /* special-case 'media' tag, could be e.g. "CD 1/2" */
    if (g_ascii_strcasecmp (tag, "media") == 0) {
      gchar *sp, *sp2;

      g_free (tag);
      tag = g_strdup ("discnumber");
      /* get rid of the medium in front */
      sp = strchr (val, ' ');
      while (sp != NULL && (sp2 = strchr (sp + 1, ' ')) != NULL)
        sp = sp2;
      if (sp) {
        g_memmove (val, sp + 1, strlen (sp + 1) + 1);
      }
    }

    if (ape_demux_get_gst_tag_from_tag (tag, &gst_tag, &gst_tag_type)) {
      GValue v = { 0, };

      switch (gst_tag_type) {
        case G_TYPE_INT:{
          gint v_int;

          if (sscanf (val, "%d", &v_int) == 1) {
            g_value_init (&v, G_TYPE_INT);
            g_value_set_int (&v, v_int);
          }
          break;
        }
        case G_TYPE_UINT:{
          guint v_uint, count;

          if (strcmp (gst_tag, GST_TAG_TRACK_NUMBER) == 0) {
            gint dummy;

            if (sscanf (val, "%u", &v_uint) == 1 && v_uint > 0) {
              g_value_init (&v, G_TYPE_UINT);
              g_value_set_uint (&v, v_uint);
            }
            GST_LOG ("checking for track count: %s", val);
            /* might be 0/N or -1/N to specify that there is only a count */
            if (sscanf (val, "%d/%u", &dummy, &count) == 2 && count > 0) {
              gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND,
                  GST_TAG_TRACK_COUNT, count, NULL);
            }
          } else if (strcmp (gst_tag, GST_TAG_ALBUM_VOLUME_NUMBER) == 0) {
            gint dummy;

            if (sscanf (val, "%u", &v_uint) == 1 && v_uint > 0) {
              g_value_init (&v, G_TYPE_UINT);
              g_value_set_uint (&v, v_uint);
            }
            GST_LOG ("checking for volume count: %s", val);
            /* might be 0/N or -1/N to specify that there is only a count */
            if (sscanf (val, "%d/%u", &dummy, &count) == 2 && count > 0) {
              gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND,
                  GST_TAG_ALBUM_VOLUME_COUNT, count, NULL);
            }
          } else if (sscanf (val, "%u", &v_uint) == 1) {
            g_value_init (&v, G_TYPE_UINT);
            g_value_set_uint (&v, v_uint);
          }
          break;
        }
        case G_TYPE_STRING:{
          g_value_init (&v, G_TYPE_STRING);
          g_value_set_string (&v, val);
          break;
        }
        case G_TYPE_DOUBLE:{
          gdouble v_double;
          gchar *endptr;

          /* floating point strings can be "4,123" or "4.123" depending on
           * the locale. We need to be able to parse and read either version
           * no matter what our current locale is */
          g_strdelimit (val, ",", '.');
          v_double = g_ascii_strtod (val, &endptr);
          if (endptr != val) {
            g_value_init (&v, G_TYPE_DOUBLE);
            g_value_set_double (&v, v_double);
          }

          break;
        }
        default:{
          if (gst_tag_type == G_TYPE_DATE) {
            gint v_int;

            if (sscanf (val, "%d", &v_int) == 1) {
              GDate *date = g_date_new_dmy (1, 1, v_int);

              g_value_init (&v, G_TYPE_DATE);
              g_value_take_boxed (&v, date);
            }
          } else {
            GST_WARNING ("Unhandled tag type '%s' for tag '%s'",
                g_type_name (gst_tag_type), gst_tag);
          }
          break;
        }
      }
      if (G_VALUE_TYPE (&v) != 0) {
        gst_tag_list_add_values (taglist, GST_TAG_MERGE_APPEND,
            gst_tag, &v, NULL);
        g_value_unset (&v);
      }
    }
    GST_DEBUG ("Read tag %s: %s", tag, val);
    g_free (tag);
    g_free (val);

    /* move data pointer */
  next_tag:
    size -= len + n;
    data += len + n;
  }

  GST_DEBUG ("Taglist: %" GST_PTR_FORMAT, taglist);
  return taglist;
}

static gboolean
gst_ape_demux_identify_tag (GstTagDemux * demux, GstBuffer * buffer,
    gboolean start_tag, guint * tag_size)
{
  GstMapInfo map;

  gst_buffer_map (buffer, &map, GST_MAP_READ);

  if (memcmp (map.data, "APETAGEX", 8) != 0) {
    GST_DEBUG_OBJECT (demux, "No APETAGEX marker at %s - not an APE file",
        (start_tag) ? "start" : "end");
    gst_buffer_unmap (buffer, &map);
    return FALSE;
  }

  *tag_size = GST_READ_UINT32_LE (map.data + 12);

  /* size is without header, so add 32 to account for that */
  *tag_size += 32;

  gst_buffer_unmap (buffer, &map);

  return TRUE;
}

static GstTagDemuxResult
gst_ape_demux_parse_tag (GstTagDemux * demux, GstBuffer * buffer,
    gboolean start_tag, guint * tag_size, GstTagList ** tags)
{
  guint8 *data;
  guint8 *footer;
  gboolean have_header;
  gboolean end_tag = !start_tag;
  GstCaps *sink_caps;
  guint version, footer_size;
  GstMapInfo map;
  gsize size;

  gst_buffer_map (buffer, &map, GST_MAP_READ);
  data = map.data;
  size = map.size;

  GST_LOG_OBJECT (demux, "Parsing buffer of size %" G_GSIZE_FORMAT, size);

  footer = data + size - 32;

  GST_LOG_OBJECT (demux, "Checking for footer at offset 0x%04x",
      (guint) (footer - data));
  if (footer > data && memcmp (footer, "APETAGEX", 8) == 0) {
    GST_DEBUG_OBJECT (demux, "Found footer");
    footer_size = 32;
  } else {
    GST_DEBUG_OBJECT (demux, "No footer");
    footer_size = 0;
  }

  /* APE tags at the end must have a footer */
  if (end_tag && footer_size == 0) {
    GST_WARNING_OBJECT (demux, "Tag at end of file without footer!");
    return GST_TAG_DEMUX_RESULT_BROKEN_TAG;
  }

  /* don't trust the header/footer flags, better detect them ourselves */
  have_header = (memcmp (data, "APETAGEX", 8) == 0);

  if (start_tag && !have_header) {
    GST_DEBUG_OBJECT (demux, "Tag at beginning of file without header!");
    return GST_TAG_DEMUX_RESULT_BROKEN_TAG;
  }

  if (end_tag && !have_header) {
    GST_DEBUG_OBJECT (demux, "Tag at end of file has no header (APEv1)");
    *tag_size -= 32;            /* adjust tag size */
  }

  if (have_header) {
    version = GST_READ_UINT32_LE (data + 8);
  } else {
    version = GST_READ_UINT32_LE (footer + 8);
  }

  /* skip header */
  if (have_header) {
    data += 32;
  }

  GST_DEBUG_OBJECT (demux, "APE tag with version %u, size %u at offset 0x%08"
      G_GINT64_MODIFIER "x", version, *tag_size,
      GST_BUFFER_OFFSET (buffer) + ((have_header) ? 0 : 32));

  if (APE_VERSION_MAJOR (version) != 1 && APE_VERSION_MAJOR (version) != 2) {
    GST_WARNING ("APE tag is version %u.%03u, but decoder only supports "
        "v1 or v2. Ignoring.", APE_VERSION_MAJOR (version), version % 1000);
    return GST_TAG_DEMUX_RESULT_OK;
  }

  *tags = ape_demux_parse_tags (data, *tag_size - footer_size);

  sink_caps = gst_static_pad_template_get_caps (&sink_factory);
  gst_pb_utils_add_codec_description_to_tag_list (*tags,
      GST_TAG_CONTAINER_FORMAT, sink_caps);
  gst_caps_unref (sink_caps);

  gst_buffer_unmap (buffer, &map);

  return GST_TAG_DEMUX_RESULT_OK;
}

static gboolean
plugin_init (GstPlugin * plugin)
{
  return gst_element_register (plugin, "apedemux",
      GST_RANK_PRIMARY, GST_TYPE_APE_DEMUX);
}

GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
    GST_VERSION_MINOR,
    apetag,
    "APEv1/2 tag reader",
    plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
