/* GStreamer non-core tag registration and tag utility functions
 * Copyright (C) 2005 Ross Burton <ross@burtonini.com>
 * Copyright (C) 2006-2008 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

#include <gst/gst-i18n-plugin.h>
#include <gst/base/gsttypefindhelper.h>
#include <gst/gst.h>
#include "tag.h"
#include "id3v2.h"

#include <string.h>

/**
 * SECTION:gsttag
 * @title: Tags
 * @short_description: additional tag definitions for plugins and applications
 * @see_also: #GstTagList
 *
 * Contains additional standardized GStreamer tag definitions for plugins
 * and applications, and functions to register them with the GStreamer
 * tag system.
 *
 */

#ifndef GST_DISABLE_GST_DEBUG
#define GST_CAT_DEFAULT gst_tag_ensure_debug_category()

static GstDebugCategory *
gst_tag_ensure_debug_category (void)
{
  static gsize cat_gonce = 0;

  if (g_once_init_enter (&cat_gonce)) {
    GstDebugCategory *cat = NULL;

    GST_DEBUG_CATEGORY_INIT (cat, "tag-tags", 0, "GstTag helper functions");

    g_once_init_leave (&cat_gonce, (gsize) cat);
  }

  return (GstDebugCategory *) cat_gonce;
}
#endif /* GST_DISABLE_GST_DEBUG */

static gpointer
gst_tag_register_tags_internal (gpointer unused)
{
#ifdef ENABLE_NLS
  GST_DEBUG ("binding text domain %s to locale dir %s", GETTEXT_PACKAGE,
      LOCALEDIR);
  bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
  bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
#endif

  /* musicbrainz tags */
  gst_tag_register_static (GST_TAG_MUSICBRAINZ_TRACKID, GST_TAG_FLAG_META,
      G_TYPE_STRING, _("track ID"), _("MusicBrainz track ID"), NULL);
  gst_tag_register_static (GST_TAG_MUSICBRAINZ_ARTISTID, GST_TAG_FLAG_META,
      G_TYPE_STRING, _("artist ID"), _("MusicBrainz artist ID"), NULL);
  gst_tag_register_static (GST_TAG_MUSICBRAINZ_ALBUMID, GST_TAG_FLAG_META,
      G_TYPE_STRING, _("album ID"), _("MusicBrainz album ID"), NULL);
  gst_tag_register_static (GST_TAG_MUSICBRAINZ_ALBUMARTISTID, GST_TAG_FLAG_META,
      G_TYPE_STRING,
      _("album artist ID"), _("MusicBrainz album artist ID"), NULL);
  gst_tag_register_static (GST_TAG_MUSICBRAINZ_TRMID, GST_TAG_FLAG_META,
      G_TYPE_STRING, _("track TRM ID"), _("MusicBrainz TRM ID"), NULL);

  /* CDDA tags */
  gst_tag_register_static (GST_TAG_CDDA_CDDB_DISCID, GST_TAG_FLAG_META,
      G_TYPE_STRING, "discid", "CDDB discid for metadata retrieval",
      gst_tag_merge_use_first);

  gst_tag_register_static (GST_TAG_CDDA_CDDB_DISCID_FULL, GST_TAG_FLAG_META,
      G_TYPE_STRING, "discid full",
      "CDDB discid for metadata retrieval (full)", gst_tag_merge_use_first);

  gst_tag_register_static (GST_TAG_CDDA_MUSICBRAINZ_DISCID, GST_TAG_FLAG_META,
      G_TYPE_STRING, "musicbrainz-discid",
      "Musicbrainz discid for metadata retrieval", gst_tag_merge_use_first);

  gst_tag_register_static (GST_TAG_CDDA_MUSICBRAINZ_DISCID_FULL,
      GST_TAG_FLAG_META, G_TYPE_STRING, "musicbrainz-discid-full",
      "Musicbrainz discid for metadata retrieval (full)",
      gst_tag_merge_use_first);

  /* photography tags */
  gst_tag_register_static (GST_TAG_CAPTURING_SHUTTER_SPEED, GST_TAG_FLAG_META,
      GST_TYPE_FRACTION, _("capturing shutter speed"),
      _("Shutter speed used when capturing an image, in seconds"), NULL);

  gst_tag_register_static (GST_TAG_CAPTURING_FOCAL_RATIO, GST_TAG_FLAG_META,
      G_TYPE_DOUBLE, _("capturing focal ratio"),
      _("Focal ratio (f-number) used when capturing the image"), NULL);

  gst_tag_register_static (GST_TAG_CAPTURING_FOCAL_LENGTH, GST_TAG_FLAG_META,
      G_TYPE_DOUBLE, _("capturing focal length"),
      _("Focal length of the lens used capturing the image, in mm"), NULL);

  gst_tag_register_static (GST_TAG_CAPTURING_FOCAL_LENGTH_35_MM,
      GST_TAG_FLAG_META, G_TYPE_DOUBLE,
      _("capturing 35 mm equivalent focal length"),
      _("35 mm equivalent focal length of the lens used capturing the image, "
          "in mm"), NULL);

  gst_tag_register_static (GST_TAG_CAPTURING_DIGITAL_ZOOM_RATIO,
      GST_TAG_FLAG_META, G_TYPE_DOUBLE, _("capturing digital zoom ratio"),
      _("Digital zoom ratio used when capturing an image"), NULL);

  gst_tag_register_static (GST_TAG_CAPTURING_ISO_SPEED, GST_TAG_FLAG_META,
      G_TYPE_INT, _("capturing iso speed"),
      _("The ISO speed used when capturing an image"), NULL);

  gst_tag_register_static (GST_TAG_CAPTURING_EXPOSURE_PROGRAM,
      GST_TAG_FLAG_META, G_TYPE_STRING, _("capturing exposure program"),
      _("The exposure program used when capturing an image"), NULL);

  gst_tag_register_static (GST_TAG_CAPTURING_EXPOSURE_MODE, GST_TAG_FLAG_META,
      G_TYPE_STRING, _("capturing exposure mode"),
      _("The exposure mode used when capturing an image"), NULL);

  gst_tag_register_static (GST_TAG_CAPTURING_EXPOSURE_COMPENSATION,
      GST_TAG_FLAG_META, G_TYPE_DOUBLE, _("capturing exposure compensation"),
      _("The exposure compensation used when capturing an image"), NULL);

  gst_tag_register_static (GST_TAG_CAPTURING_SCENE_CAPTURE_TYPE,
      GST_TAG_FLAG_META, G_TYPE_STRING, _("capturing scene capture type"),
      _("The scene capture mode used when capturing an image"), NULL);

  gst_tag_register_static (GST_TAG_CAPTURING_GAIN_ADJUSTMENT, GST_TAG_FLAG_META,
      G_TYPE_STRING, _("capturing gain adjustment"),
      _("The overall gain adjustment applied on an image"), NULL);

  gst_tag_register_static (GST_TAG_CAPTURING_WHITE_BALANCE, GST_TAG_FLAG_META,
      G_TYPE_STRING, _("capturing white balance"),
      _("The white balance mode set when capturing an image"), NULL);

  gst_tag_register_static (GST_TAG_CAPTURING_CONTRAST, GST_TAG_FLAG_META,
      G_TYPE_STRING, _("capturing contrast"),
      _("The direction of contrast processing applied "
          "when capturing an image"), NULL);

  gst_tag_register_static (GST_TAG_CAPTURING_SATURATION, GST_TAG_FLAG_META,
      G_TYPE_STRING, _("capturing saturation"),
      _("The direction of saturation processing applied when "
          "capturing an image"), NULL);

  gst_tag_register_static (GST_TAG_CAPTURING_SHARPNESS, GST_TAG_FLAG_META,
      G_TYPE_STRING, _("capturing sharpness"),
      _("The direction of sharpness processing applied "
          "when capturing an image"), NULL);

  gst_tag_register_static (GST_TAG_CAPTURING_FLASH_FIRED, GST_TAG_FLAG_META,
      G_TYPE_BOOLEAN, _("capturing flash fired"),
      _("If the flash fired while capturing an image"), NULL);

  gst_tag_register_static (GST_TAG_CAPTURING_FLASH_MODE, GST_TAG_FLAG_META,
      G_TYPE_STRING, _("capturing flash mode"),
      _("The selected flash mode while capturing an image"), NULL);

  gst_tag_register_static (GST_TAG_CAPTURING_METERING_MODE, GST_TAG_FLAG_META,
      G_TYPE_STRING, _("capturing metering mode"),
      _("The metering mode used while determining exposure for capturing an"
          " image"), NULL);

  gst_tag_register_static (GST_TAG_CAPTURING_SOURCE, GST_TAG_FLAG_META,
      G_TYPE_STRING, _("capturing source"),
      _("The source or type of device used for the capture"), NULL);

  gst_tag_register_static (GST_TAG_IMAGE_HORIZONTAL_PPI, GST_TAG_FLAG_META,
      G_TYPE_DOUBLE, _("image horizontal ppi"),
      _("Media (image/video) intended horizontal pixel density in ppi"), NULL);

  gst_tag_register_static (GST_TAG_IMAGE_VERTICAL_PPI, GST_TAG_FLAG_META,
      G_TYPE_DOUBLE, _("image vertical ppi"),
      _("Media (image/video) intended vertical pixel density in ppi"), NULL);

  gst_tag_register_static (GST_TAG_ID3V2_FRAME, GST_TAG_FLAG_META,
      GST_TYPE_SAMPLE, _("ID3v2 frame"), _("unparsed id3v2 tag frame"),
      gst_tag_merge_use_first);

  gst_tag_register_static (GST_TAG_MUSICAL_KEY, GST_TAG_FLAG_META,
      G_TYPE_STRING, _("musical-key"), _("Initial key in which the "
          "sound starts"), gst_tag_merge_use_first);

  return NULL;
}

/* FIXME 0.11: rename this to gst_tag_init() or gst_tag_register_tags() or
 * even better: make tags auto-register themselves, either by defining them
 * to a wrapper func that does the initing, or by adding tag factories so
 * that the core can load+register tags automatically when needed. */

/**
 * gst_tag_register_musicbrainz_tags:
 *
 * Registers additional musicbrainz-specific tags with the GStreamer tag
 * system. Plugins and applications that use these tags should call this
 * function before using them. Can be called multiple times.
 */
void
gst_tag_register_musicbrainz_tags (void)
{
  static GOnce mb_once = G_ONCE_INIT;

  g_once (&mb_once, gst_tag_register_tags_internal, NULL);
}

static inline gboolean
gst_tag_image_type_is_valid (GstTagImageType type)
{
  GEnumClass *klass;

  gboolean res;

  klass = g_type_class_ref (gst_tag_image_type_get_type ());
  res = (g_enum_get_value (klass, type) != NULL);
  g_type_class_unref (klass);

  return res;
}

/**
 * gst_tag_parse_extended_comment:
 * @ext_comment: an extended comment string, see #GST_TAG_EXTENDED_COMMENT
 * @key: return location for the comment description key, or NULL
 * @lang: return location for the comment ISO-639 language code, or NULL
 * @value: return location for the actual comment string, or NULL
 * @fail_if_no_key: whether to fail if strings are not in key=value form
 *
 * Convenience function to parse a GST_TAG_EXTENDED_COMMENT string and
 * separate it into its components.
 *
 * If successful, @key, @lang and/or @value will be set to newly allocated
 * strings that you need to free with g_free() when done. @key and @lang
 * may also be set to NULL by this function if there is no key or no language
 * code in the extended comment string.
 *
 * Returns: TRUE if the string could be parsed, otherwise FALSE
 */
gboolean
gst_tag_parse_extended_comment (const gchar * ext_comment, gchar ** key,
    gchar ** lang, gchar ** value, gboolean fail_if_no_key)
{
  const gchar *div, *bop, *bcl;

  g_return_val_if_fail (ext_comment != NULL, FALSE);
  g_return_val_if_fail (g_utf8_validate (ext_comment, -1, NULL), FALSE);

  if (key)
    *key = NULL;
  if (lang)
    *lang = NULL;

  div = strchr (ext_comment, '=');
  bop = strchr (ext_comment, '[');
  bcl = strchr (ext_comment, ']');

  if (div == NULL) {
    if (fail_if_no_key)
      return FALSE;
    if (value)
      *value = g_strdup (ext_comment);
    return TRUE;
  }

  if (bop != NULL && bop < div) {
    if (bcl < bop || bcl > div)
      return FALSE;
    if (key)
      *key = g_strndup (ext_comment, bop - ext_comment);
    if (lang)
      *lang = g_strndup (bop + 1, bcl - bop - 1);
  } else {
    if (key)
      *key = g_strndup (ext_comment, div - ext_comment);
  }

  if (value)
    *value = g_strdup (div + 1);

  return TRUE;
}

/**
 * gst_tag_freeform_string_to_utf8:
 * @data: string data
 * @size: length of string data, or -1 if the string is NUL-terminated
 * @env_vars: a NULL-terminated string array of environment variable names,
 *            or NULL
 *
 * Convenience function to read a string with unknown character encoding. If
 * the string is already in UTF-8 encoding, it will be returned right away.
 * If not it tries to detect byte-order-mark for UTF-16/32 cases and use that.
 * Otherwise, the environment will be searched for a number of environment
 * variables (whose names are specified in the NULL-terminated string array
 * @env_vars) containing a list of character encodings to try/use. If none
 * are specified, the current locale will be tried. If that also doesn't work,
 * WINDOWS-1252/ISO-8859-1 is assumed (which will almost always succeed).
 *
 * Returns: a newly-allocated string in UTF-8 encoding, or NULL
 */
gchar *
gst_tag_freeform_string_to_utf8 (const gchar * data, gint size,
    const gchar ** env_vars)
{
  const gchar *cur_loc = NULL;

  gsize bytes_read;

  gchar *utf8 = NULL;

  g_return_val_if_fail (data != NULL, NULL);

  if (size < 0)
    size = strlen (data);

  /* chop off trailing string terminators to make sure utf8_validate doesn't
   * get to see them (since that would make the utf8 check fail) */
  while (size > 0 && data[size - 1] == '\0')
    --size;

  /* Should we try the charsets specified
   * via environment variables FIRST ? */
  if (g_utf8_validate (data, size, NULL)) {
    utf8 = g_strndup (data, size);
    GST_LOG ("String '%s' is valid UTF-8 already", utf8);
    goto beach;
  }

  /* check for and use byte-order-mark for UTF-16/32 cases */
  if (size >= 2) {
    const gchar *c = NULL;
    gint prefix, ssize;

    if (size >= 4) {
      prefix = 4;
      ssize = GST_ROUND_DOWN_4 (size - 4);
      switch (GST_READ_UINT32_BE (data)) {
        case 0x0000FEFF:
          c = "UTF-32BE";
          break;
        case 0xFFFE0000:
          c = "UTF-32LE";
          break;
        default:
          break;
      }
    }
    if (!c) {
      prefix = 2;
      ssize = GST_ROUND_DOWN_2 (size - 2);
      switch (GST_READ_UINT16_BE (data)) {
        case 0xFEFF:
          c = "UTF-16BE";
          break;
        case 0xFFFE:
          c = "UTF-16LE";
          break;
        default:
          break;
      }
    }
    if (c) {
      GST_LOG ("Trying to convert freeform string to UTF-8 from '%s'", c);
      if ((utf8 =
              g_convert (data + prefix, ssize, "UTF-8", c, &bytes_read, NULL,
                  NULL))) {
        if (bytes_read == ssize)
          goto beach;
        g_free (utf8);
        utf8 = NULL;
      }
    }
  }

  while (env_vars && *env_vars != NULL) {
    const gchar *env = NULL;

    /* Try charsets specified via the environment */
    env = g_getenv (*env_vars);
    if (env != NULL && *env != '\0') {
      gchar **c, **csets;

      csets = g_strsplit (env, G_SEARCHPATH_SEPARATOR_S, -1);

      for (c = csets; c && *c; ++c) {
        GST_LOG ("Trying to convert freeform string to UTF-8 from '%s'", *c);
        if ((utf8 =
                g_convert (data, size, "UTF-8", *c, &bytes_read, NULL, NULL))) {
          if (bytes_read == size) {
            g_strfreev (csets);
            goto beach;
          }
          g_free (utf8);
          utf8 = NULL;
        }
      }

      g_strfreev (csets);
    }
    ++env_vars;
  }

  /* Try current locale (if not UTF-8) */
  if (!g_get_charset (&cur_loc)) {
    GST_LOG ("Trying to convert freeform string using locale ('%s')", cur_loc);
    if ((utf8 = g_locale_to_utf8 (data, size, &bytes_read, NULL, NULL))) {
      if (bytes_read == size) {
        goto beach;
      }
      g_free (utf8);
      utf8 = NULL;
    }
  }

  /* Try Windows-1252 (which is a superset of ISO 8859-1 that uses a control
   * character range in ISO 8859-1 for more printable characters) */
  {
    GError *err = NULL;

    GST_LOG ("Trying to convert freeform string using Windows-1252/ISO-8859-1 "
        "fallback");
    utf8 = g_convert (data, size, "UTF-8", "WINDOWS-1252", &bytes_read, NULL,
        &err);
    if (err != NULL) {
      /* fallback in case iconv implementation doesn't support windows-1252
       * for some reason */
      if (err->code == G_CONVERT_ERROR_NO_CONVERSION) {
        g_free (utf8);
        utf8 = g_convert (data, size, "UTF-8", "ISO-8859-1", &bytes_read,
            NULL, NULL);
      }
      g_error_free (err);
    }

    if (utf8 != NULL && bytes_read == size)
      goto beach;
  }

  g_free (utf8);
  return NULL;

beach:

  g_strchomp (utf8);
  if (utf8 && utf8[0] != '\0') {
    GST_LOG ("Returning '%s'", utf8);
    return utf8;
  }

  g_free (utf8);
  return NULL;
}

/**
 * gst_tag_image_data_to_image_sample:
 * @image_data: the (encoded) image
 * @image_data_len: the length of the encoded image data at @image_data
 * @image_type: type of the image, or #GST_TAG_IMAGE_TYPE_UNDEFINED. Pass
 *     #GST_TAG_IMAGE_TYPE_NONE if no image type should be set at all (e.g.
 *     for preview images)
 *
 * Helper function for tag-reading plugins to create a #GstSample suitable to
 * add to a #GstTagList as an image tag (such as #GST_TAG_IMAGE or
 * #GST_TAG_PREVIEW_IMAGE) from the encoded image data and an (optional) image
 * type.
 *
 * Background: cover art and other images in tags are usually stored as a
 * blob of binary image data, often accompanied by a MIME type or some other
 * content type string (e.g. 'png', 'jpeg', 'jpg'). Sometimes there is also an
 * 'image type' to indicate what kind of image this is (e.g. front cover,
 * back cover, artist, etc.). The image data may also be an URI to the image
 * rather than the image itself.
 *
 * In GStreamer, image tags are #GstSample<!-- -->s containing the raw image
 * data, with the sample caps describing the content type of the image
 * (e.g. image/jpeg, image/png, text/uri-list). The sample info may contain
 * an additional 'image-type' field of #GST_TYPE_TAG_IMAGE_TYPE to describe
 * the type of image (front cover, back cover etc.). #GST_TAG_PREVIEW_IMAGE
 * tags should not carry an image type, their type is already indicated via
 * the special tag name.
 *
 * This function will do various checks and typefind the encoded image
 * data (we can't trust the declared mime type).
 *
 * Returns: a newly-allocated image sample for use in tag lists, or NULL
 */
GstSample *
gst_tag_image_data_to_image_sample (const guint8 * image_data,
    guint image_data_len, GstTagImageType image_type)
{
  const gchar *name;
  GstBuffer *image;
  GstSample *sample;
  GstCaps *caps;
  GstMapInfo info;
  GstStructure *image_info = NULL;

  g_return_val_if_fail (image_data != NULL, NULL);
  g_return_val_if_fail (image_data_len > 0, NULL);
  g_return_val_if_fail (gst_tag_image_type_is_valid (image_type), NULL);

  GST_DEBUG ("image data len: %u bytes", image_data_len);

  /* allocate space for a NUL terminator for an uri too */
  image = gst_buffer_new_and_alloc (image_data_len + 1);
  if (image == NULL)
    goto alloc_failed;

  gst_buffer_map (image, &info, GST_MAP_WRITE);
  memcpy (info.data, image_data, image_data_len);
  info.data[image_data_len] = '\0';
  gst_buffer_unmap (image, &info);

  /* Find GStreamer media type, can't trust declared type */
  caps = gst_type_find_helper_for_buffer (NULL, image, NULL);

  if (caps == NULL)
    goto no_type;

  GST_DEBUG ("Found GStreamer media type: %" GST_PTR_FORMAT, caps);

  /* sanity check: make sure typefound/declared caps are either URI or image */
  name = gst_structure_get_name (gst_caps_get_structure (caps, 0));

  if (!g_str_has_prefix (name, "image/") &&
      !g_str_has_prefix (name, "video/") &&
      !g_str_equal (name, "text/uri-list")) {
    GST_DEBUG ("Unexpected image type '%s', ignoring image frame", name);
    goto error;
  }

  /* Decrease size by 1 if we don't have an URI list
   * to keep the original size of the image
   */
  if (!g_str_equal (name, "text/uri-list"))
    gst_buffer_set_size (image, image_data_len);

  if (image_type != GST_TAG_IMAGE_TYPE_NONE) {
    GST_LOG ("Setting image type: %d", image_type);
    image_info = gst_structure_new ("GstTagImageInfo",
        "image-type", GST_TYPE_TAG_IMAGE_TYPE, image_type, NULL);
  }
  sample = gst_sample_new (image, caps, NULL, image_info);
  gst_buffer_unref (image);
  gst_caps_unref (caps);

  return sample;

/* ERRORS */
no_type:
  {
    GST_DEBUG ("Could not determine GStreamer media type, ignoring image");
    /* fall through */
  }
error:
  {
    if (image)
      gst_buffer_unref (image);
    if (caps)
      gst_caps_unref (caps);
    return NULL;
  }
alloc_failed:
  {
    GST_WARNING ("failed to allocate buffer of %d for image", image_data_len);
    gst_buffer_unref (image);
    return NULL;
  }

}
