/* GStreamer taglib-based APEv2 muxer
 * Copyright (C) 2006 Christophe Fergeau <teuf@gnome.org>
 * Copyright (C) 2006 Tim-Philipp Müller <tim centricular net>
 * Copyright (C) 2006 Sebastian Dröge <slomo@circular-chaos.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-apev2mux
 * @see_also: #GstTagSetter
 *
 * This element adds APEv2 tags to the beginning of a stream using the taglib
 * library.
 *
 * Applications can set the tags to write using the #GstTagSetter interface.
 * Tags sent by upstream elements will be picked up automatically (and merged
 * according to the merge mode set via the tag setter interface).
 *
 * <refsect2>
 * <title>Example pipelines</title>
 * |[
 * gst-launch-1.0 -v filesrc location=foo.ogg ! decodebin ! audioconvert ! lame ! apev2mux ! filesink location=foo.mp3
 * ]| A pipeline that transcodes a file from Ogg/Vorbis to mp3 format with an
 * APEv2 that contains the same as the the Ogg/Vorbis file. Make sure the
 * Ogg/Vorbis file actually has comments to preserve.
 * |[
 * gst-launch-1.0 -m filesrc location=foo.mp3 ! apedemux ! fakesink silent=TRUE 2&gt; /dev/null | grep taglist
 * ]| Verify that tags have been written.
 * </refsect2>
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include "gstapev2mux.h"

#include <string.h>

#include <apetag.h>
#include <gst/tag/tag.h>

using namespace TagLib;

GST_DEBUG_CATEGORY_STATIC (gst_apev2_mux_debug);
#define GST_CAT_DEFAULT gst_apev2_mux_debug

static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("application/x-apetag"));

static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("ANY"));

G_DEFINE_TYPE (GstApev2Mux, gst_apev2_mux, GST_TYPE_TAG_MUX);

static GstBuffer *gst_apev2_mux_render_start_tag (GstTagMux * mux,
    const GstTagList * taglist);
static GstBuffer *gst_apev2_mux_render_end_tag (GstTagMux * mux,
    const GstTagList * taglist);

static void
gst_apev2_mux_class_init (GstApev2MuxClass * klass)
{
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);

  GST_TAG_MUX_CLASS (klass)->render_start_tag =
      GST_DEBUG_FUNCPTR (gst_apev2_mux_render_start_tag);
  GST_TAG_MUX_CLASS (klass)->render_end_tag =
      GST_DEBUG_FUNCPTR (gst_apev2_mux_render_end_tag);

  gst_element_class_add_static_pad_template (element_class, &sink_template);
  gst_element_class_add_static_pad_template (element_class, &src_template);

  gst_element_class_set_static_metadata (element_class,
      "TagLib-based APEv2 Muxer", "Formatter/Metadata",
      "Adds an APEv2 header to the beginning of files using taglib",
      "Sebastian Dröge <slomo@circular-chaos.org>");

  GST_DEBUG_CATEGORY_INIT (gst_apev2_mux_debug, "apev2mux", 0,
      "taglib-based APEv2 tag muxer");
}

static void
gst_apev2_mux_init (GstApev2Mux * apev2mux)
{
  /* nothing to do */
}

static gboolean
gst_apev2_mux_have_wavpack (GstApev2Mux * apev2mux)
{
  const GstStructure *s;
  gboolean ret;
  GstCaps *caps;
  GstPad *sink;

  sink = gst_element_get_static_pad (GST_ELEMENT_CAST (apev2mux), "sink");
  caps = gst_pad_get_current_caps (sink);
  gst_object_unref (sink);

  if (caps == NULL)
    return FALSE;

  s = gst_caps_get_structure (caps, 0);
  ret = gst_structure_has_name (s, "audio/x-wavpack");
  gst_caps_unref (caps);

  GST_LOG_OBJECT (apev2mux, "got wavpack input: %s", ret ? "yes" : "no");
  return ret;
}

static void
add_one_tag (const GstTagList * list, const gchar * tag, gpointer user_data)
{
  APE::Tag * apev2tag = (APE::Tag *) user_data;
  gboolean result;

  /* FIXME: if there are several values set for the same tag, this won't
   * work, only the first value will be taken into account
   */
  if (strcmp (tag, GST_TAG_TITLE) == 0) {
    const char *title;

    result = gst_tag_list_peek_string_index (list, tag, 0, &title);
    if (result != FALSE) {
      GST_DEBUG ("Setting title to %s", title);
      apev2tag->setTitle (String (title, String::UTF8));
    }
  } else if (strcmp (tag, GST_TAG_ALBUM) == 0) {
    const char *album;

    result = gst_tag_list_peek_string_index (list, tag, 0, &album);
    if (result != FALSE) {
      GST_DEBUG ("Setting album to %s", album);
      apev2tag->setAlbum (String (album, String::UTF8));
    }
  } else if (strcmp (tag, GST_TAG_ARTIST) == 0) {
    const char *artist;

    result = gst_tag_list_peek_string_index (list, tag, 0, &artist);
    if (result != FALSE) {
      GST_DEBUG ("Setting artist to %s", artist);
      apev2tag->setArtist (String (artist, String::UTF8));
    }
  } else if (strcmp (tag, GST_TAG_COMPOSER) == 0) {
    const char *composer;

    result = gst_tag_list_peek_string_index (list, tag, 0, &composer);
    if (result != FALSE) {
      GST_DEBUG ("Setting composer to %s", composer);
      apev2tag->addValue (String ("COMPOSER", String::UTF8),
          String (composer, String::UTF8));
    }
  } else if (strcmp (tag, GST_TAG_GENRE) == 0) {
    const char *genre;

    result = gst_tag_list_peek_string_index (list, tag, 0, &genre);
    if (result != FALSE) {
      GST_DEBUG ("Setting genre to %s", genre);
      apev2tag->setGenre (String (genre, String::UTF8));
    }
  } else if (strcmp (tag, GST_TAG_COMMENT) == 0) {
    const char *comment;

    result = gst_tag_list_peek_string_index (list, tag, 0, &comment);
    if (result != FALSE) {
      GST_DEBUG ("Setting comment to %s", comment);
      apev2tag->setComment (String (comment, String::UTF8));
    }
  } else if (strcmp (tag, GST_TAG_DATE) == 0) {
    GDate *date;

    result = gst_tag_list_get_date_index (list, tag, 0, &date);
    if (result != FALSE) {
      GDateYear year;

      year = g_date_get_year (date);
      GST_DEBUG ("Setting track year to %d", year);
      apev2tag->setYear (year);
      g_date_free (date);
    }
  } else if (strcmp (tag, GST_TAG_TRACK_NUMBER) == 0) {
    guint track_number;

    result = gst_tag_list_get_uint_index (list, tag, 0, &track_number);
    if (result != FALSE) {
      guint total_tracks;

      result = gst_tag_list_get_uint_index (list, GST_TAG_TRACK_COUNT,
          0, &total_tracks);
      if (result) {
        gchar *tag_str;

        tag_str = g_strdup_printf ("%d/%d", track_number, total_tracks);
        GST_DEBUG ("Setting track number to %s", tag_str);
        apev2tag->addValue (String ("TRACK", String::UTF8),
            String (tag_str, String::UTF8), true);
        g_free (tag_str);
      } else {
        GST_DEBUG ("Setting track number to %d", track_number);
        apev2tag->setTrack (track_number);
      }
    }
  } else if (strcmp (tag, GST_TAG_TRACK_COUNT) == 0) {
    guint n;

    if (gst_tag_list_get_uint_index (list, GST_TAG_TRACK_NUMBER, 0, &n)) {
      GST_DEBUG ("track-count handled with track-number, skipping");
    } else if (gst_tag_list_get_uint_index (list, GST_TAG_TRACK_COUNT, 0, &n)) {
      gchar *tag_str;

      tag_str = g_strdup_printf ("0/%d", n);
      GST_DEBUG ("Setting track number to %s", tag_str);
      apev2tag->addValue (String ("TRACK", String::UTF8),
          String (tag_str, String::UTF8), true);
      g_free (tag_str);
    }
#if 0
  } else if (strcmp (tag, GST_TAG_ALBUM_VOLUME_NUMBER) == 0) {
    guint volume_number;

    result = gst_tag_list_get_uint_index (list, tag, 0, &volume_number);

    if (result != FALSE) {
      guint volume_count;
      gchar *tag_str;

      result = gst_tag_list_get_uint_index (list, GST_TAG_ALBUM_VOLUME_COUNT,
          0, &volume_count);

      if (result) {
        tag_str = g_strdup_printf ("CD %d/%d", volume_number, volume_count);
      } else {
        tag_str = g_strdup_printf ("CD %d", volume_number);
      }

      GST_DEBUG ("Setting album number to %s", tag_str);

      apev2tag->addValue (String ("MEDIA", String::UTF8),
          String (tag_str, String::UTF8), true);
      g_free (tag_str);
    }
  } else if (strcmp (tag, GST_TAG_ALBUM_VOLUME_COUNT) == 0) {
    guint n;

    if (gst_tag_list_get_uint_index (list, GST_TAG_ALBUM_VOLUME_NUMBER, 0, &n)) {
      GST_DEBUG ("volume-count handled with volume-number, skipping");
    } else if (gst_tag_list_get_uint_index (list, GST_TAG_ALBUM_VOLUME_COUNT,
            0, &n)) {
      gchar *tag_str;

      tag_str = g_strdup_printf ("CD 0/%u", n);
      GST_DEBUG ("Setting album volume number/count to %s", tag_str);

      apev2tag->addValue (String ("MEDIA", String::UTF8),
          String (tag_str, String::UTF8), true);
      g_free (tag_str);
    }
#endif
  } else if (strcmp (tag, GST_TAG_COPYRIGHT) == 0) {
    const gchar *copyright;

    result = gst_tag_list_peek_string_index (list, tag, 0, &copyright);

    if (result != FALSE) {
      GST_DEBUG ("Setting copyright to %s", copyright);
      apev2tag->addValue (String ("COPYRIGHT", String::UTF8),
          String (copyright, String::UTF8), true);
    }
  } else if (strcmp (tag, GST_TAG_LOCATION) == 0) {
    const gchar *location;

    result = gst_tag_list_peek_string_index (list, tag, 0, &location);

    if (result != FALSE) {
      GST_DEBUG ("Setting location to %s", location);
      apev2tag->addValue (String ("FILE", String::UTF8),
          String (location, String::UTF8), true);
    }
  } else if (strcmp (tag, GST_TAG_ISRC) == 0) {
    const gchar *isrc;

    result = gst_tag_list_peek_string_index (list, tag, 0, &isrc);

    if (result != FALSE) {
      GST_DEBUG ("Setting ISRC to %s", isrc);
      apev2tag->addValue (String ("ISRC", String::UTF8),
          String (isrc, String::UTF8), true);
    }
  } else if (strcmp (tag, GST_TAG_TRACK_GAIN) == 0) {
    gdouble value;

    result = gst_tag_list_get_double_index (list, tag, 0, &value);

    if (result != FALSE) {
      gchar *track_gain = (gchar *) g_malloc0 (G_ASCII_DTOSTR_BUF_SIZE);

      track_gain = g_ascii_dtostr (track_gain, G_ASCII_DTOSTR_BUF_SIZE, value);
      GST_DEBUG ("Setting track gain to %s", track_gain);
      apev2tag->addValue (String ("REPLAYGAIN_TRACK_GAIN",
              String::UTF8), String (track_gain, String::UTF8), true);
      g_free (track_gain);
    }
  } else if (strcmp (tag, GST_TAG_TRACK_PEAK) == 0) {
    gdouble value;

    result = gst_tag_list_get_double_index (list, tag, 0, &value);

    if (result != FALSE) {
      gchar *track_peak = (gchar *) g_malloc0 (G_ASCII_DTOSTR_BUF_SIZE);

      track_peak = g_ascii_dtostr (track_peak, G_ASCII_DTOSTR_BUF_SIZE, value);
      GST_DEBUG ("Setting track peak to %s", track_peak);
      apev2tag->addValue (String ("REPLAYGAIN_TRACK_PEAK",
              String::UTF8), String (track_peak, String::UTF8), true);
      g_free (track_peak);
    }
  } else if (strcmp (tag, GST_TAG_ALBUM_GAIN) == 0) {
    gdouble value;

    result = gst_tag_list_get_double_index (list, tag, 0, &value);

    if (result != FALSE) {
      gchar *album_gain = (gchar *) g_malloc0 (G_ASCII_DTOSTR_BUF_SIZE);

      album_gain = g_ascii_dtostr (album_gain, G_ASCII_DTOSTR_BUF_SIZE, value);
      GST_DEBUG ("Setting album gain to %s", album_gain);
      apev2tag->addValue (String ("REPLAYGAIN_ALBUM_GAIN",
              String::UTF8), String (album_gain, String::UTF8), true);
      g_free (album_gain);
    }
  } else if (strcmp (tag, GST_TAG_ALBUM_PEAK) == 0) {
    gdouble value;

    result = gst_tag_list_get_double_index (list, tag, 0, &value);

    if (result != FALSE) {
      gchar *album_peak = (gchar *) g_malloc0 (G_ASCII_DTOSTR_BUF_SIZE);

      album_peak = g_ascii_dtostr (album_peak, G_ASCII_DTOSTR_BUF_SIZE, value);
      GST_DEBUG ("Setting album peak to %s", album_peak);
      apev2tag->addValue (String ("REPLAYGAIN_ALBUM_PEAK",
              String::UTF8), String (album_peak, String::UTF8), true);
      g_free (album_peak);
    }
  } else {
    GST_WARNING ("Unsupported tag: %s", tag);
  }
}

static GstBuffer *
gst_apev2_mux_render_tag (GstTagMux * mux, const GstTagList * taglist)
{
  APE::Tag apev2tag;
  ByteVector rendered_tag;
  GstBuffer *buf;
  guint tag_size;

  /* Render the tag */
  gst_tag_list_foreach (taglist, add_one_tag, &apev2tag);

  rendered_tag = apev2tag.render ();
  tag_size = rendered_tag.size ();

  GST_LOG_OBJECT (mux, "tag size = %d bytes", tag_size);

  /* Create buffer with tag */
  buf = gst_buffer_new_and_alloc (tag_size);
  gst_buffer_fill (buf, 0, rendered_tag.data (), tag_size);

  return buf;
}

static GstBuffer *
gst_apev2_mux_render_start_tag (GstTagMux * mux, const GstTagList * taglist)
{
  if (gst_apev2_mux_have_wavpack (GST_APEV2_MUX (mux)))
    return NULL;

  return gst_apev2_mux_render_tag (mux, taglist);
}

static GstBuffer *
gst_apev2_mux_render_end_tag (GstTagMux * mux, const GstTagList * taglist)
{
  if (gst_apev2_mux_have_wavpack (GST_APEV2_MUX (mux)))
    return gst_apev2_mux_render_tag (mux, taglist);

  return NULL;
}
