/* GStreamer media licenses utility functions
 * Copyright (C) 2011 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.
 */

/**
 * SECTION:gsttaglicenses
 * @title: Licenses
 * @short_description: utility functions for Creative Commons licenses
 * @see_also: #GstTagList
 *
 * Provides information about Creative Commons media licenses, which are
 * often expressed in media files as a license URI in tags. Also useful
 * for applications creating media files, in case the user wants to license
 * the content under a Creative Commons license.
 */

/* FIXME: add API to check obsolete-ness / replace-by */

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

#include <gst/gst.h>

#include <string.h>
#include <stdlib.h>

#include "tag.h"
#include "licenses-tables.dat"

#ifndef GST_DISABLE_GST_DEBUG

#define GST_CAT_DEFAULT ensure_debug_category()

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

  if (g_once_init_enter (&cat_gonce)) {
    gsize cat_done;

    cat_done = (gsize) _gst_debug_category_new ("tag-licenses", 0,
        "GstTag licenses");

    g_once_init_leave (&cat_gonce, cat_done);
  }

  return (GstDebugCategory *) cat_gonce;
}

#else

#define ensure_debug_category() /* NOOP */

#endif /* GST_DISABLE_GST_DEBUG */

/* -------------------------------------------------------------------------
 *  Translations
 * ------------------------------------------------------------------------- */

#ifdef ENABLE_NLS
static GVariant *
gst_tag_get_license_translations_dictionary (void)
{
  static gsize var_gonce = 0;

  if (g_once_init_enter (&var_gonce)) {
    const gchar *dict_path;
    GVariant *var = NULL;
    GError *err = NULL;
    gchar *data;
    gsize len;

    /* for gst-uninstalled */
    dict_path = g_getenv ("GST_TAG_LICENSE_TRANSLATIONS_DICT");

    if (dict_path == NULL)
      dict_path = LICENSE_TRANSLATIONS_PATH;

    GST_INFO ("Loading license translations from '%s'", dict_path);
    if (g_file_get_contents (dict_path, &data, &len, &err)) {
      var = g_variant_new_from_data (G_VARIANT_TYPE ("a{sa{ss}}"), data, len,
          TRUE, (GDestroyNotify) g_free, data);
    } else {
      GST_WARNING ("Could not load translation dictionary %s", err->message);
      g_error_free (err);
      var = g_variant_new_array (G_VARIANT_TYPE ("{sa{ss}}"), NULL, 0);
    }

    g_once_init_leave (&var_gonce, (gsize) var);
  }

  return (GVariant *) var_gonce;
}
#endif

#ifdef ENABLE_NLS
static gboolean
gst_variant_lookup_string_value (GVariant * dict, const gchar * lang,
    const gchar ** translation)
{
  GVariant *trans;

  trans = g_variant_lookup_value (dict, lang, G_VARIANT_TYPE ("s"));
  if (trans == NULL)
    return FALSE;

  *translation = g_variant_get_string (trans, NULL);
  /* string will stay valid */
  g_variant_unref (trans);
  GST_TRACE ("Result: '%s' for language '%s'", *translation, lang);
  return TRUE;
}
#endif

static const gchar *
gst_license_str_translate (const gchar * s)
{
#ifdef ENABLE_NLS
  GVariant *v, *dict, *trans;

  v = gst_tag_get_license_translations_dictionary ();
  g_assert (v != NULL);

  dict = g_variant_lookup_value (v, s, G_VARIANT_TYPE ("a{ss}"));
  if (dict != NULL) {
    const gchar *const *lang;
    const gchar *env_lang;

    /* for unit tests */
    if ((env_lang = g_getenv ("GST_TAG_LICENSE_TRANSLATIONS_LANG"))) {
      if (gst_variant_lookup_string_value (dict, env_lang, &s))
        GST_TRACE ("Result: '%s' for forced language '%s'", s, env_lang);
      goto beach;
    }

    lang = g_get_language_names ();
    while (lang != NULL && *lang != NULL) {
      GST_TRACE ("Looking up '%s' for language '%s'", s, *lang);
      trans = g_variant_lookup_value (dict, *lang, G_VARIANT_TYPE ("s"));

      if (trans != NULL) {
        s = g_variant_get_string (trans, NULL);
        /* s will stay valid */
        g_variant_unref (trans);
        GST_TRACE ("Result: '%s'", s);
        break;
      }

      GST_TRACE ("No result for '%s' for language '%s'", s, *lang);
      ++lang;
    }

  beach:

    g_variant_unref (dict);
  } else {
    GST_WARNING ("No dict for string '%s'", s);
  }
#endif

  return s;
}

/* -------------------------------------------------------------------------
 *  License handling
 * ------------------------------------------------------------------------- */

#define CC_LICENSE_REF_PREFIX "http://creativecommons.org/licenses/"

/* is this license 'generic' (and a base for any of the supported
 * jurisdictions), or jurisdiction-specific only? */
#define JURISDICTION_GENERIC (G_GUINT64_CONSTANT (1) << 63)

static const gchar jurisdictions[] =
    "ar\000at\000au\000be\000bg\000br\000ca\000ch\000cl\000cn\000co\000de\000"
    "dk\000es\000fi\000fr\000hr\000hu\000il\000in\000it\000jp\000kr\000mk\000"
    "mt\000mx\000my\000nl\000pe\000pl\000pt\000scotland\000se\000si\000tw\000"
    "uk\000us\000za";

/**
 * gst_tag_get_licenses:
 *
 * Returns a list of known license references (in form of URIs). This is
 * useful for UIs to build a list of available licenses for tagging purposes
 * (e.g. to tag an audio track appropriately in a video or audio editor, or
 * an image in a camera application).
 *
 * Returns: (transfer full): NULL-terminated array of license strings. Free
 *     with g_strfreev() when no longer needed.
 */
gchar **
gst_tag_get_licenses (void)
{
  GPtrArray *arr;
  int i;

  arr = g_ptr_array_new ();
  for (i = 0; i < G_N_ELEMENTS (licenses); ++i) {
    const gchar *jurs;
    gboolean is_generic;
    guint64 jbits;
    gchar *ref;

    jbits = licenses[i].jurisdictions;
    is_generic = (jbits & JURISDICTION_GENERIC) != 0;
    if (is_generic) {
      ref = g_strconcat (CC_LICENSE_REF_PREFIX, licenses[i].ref, NULL);
      GST_LOG ("Adding %2d %s (generic)", i, ref);
      g_ptr_array_add (arr, ref);
      jbits &= ~JURISDICTION_GENERIC;
    }

    jurs = jurisdictions;
    while (jbits != 0) {
      if ((jbits & 1)) {
        ref = g_strconcat (CC_LICENSE_REF_PREFIX, licenses[i].ref, jurs, "/",
            NULL);
        GST_LOG ("Adding %2d %s (%s: %s)", i, ref,
            (is_generic) ? "derived" : "specific", jurs);
        g_ptr_array_add (arr, ref);
      }
      g_assert (jurs < (jurisdictions + sizeof (jurisdictions)));
      jurs += strlen (jurs) + 1;
      jbits >>= 1;
    }
  }
  g_ptr_array_add (arr, NULL);
  return (gchar **) g_ptr_array_free (arr, FALSE);
}

static gint
gst_tag_get_license_idx (const gchar * license_ref, const gchar ** jurisdiction)
{
  const gchar *ref, *jur_suffix;
  int i;

  GST_TRACE ("Looking up '%s'", license_ref);

  if (!g_str_has_prefix (license_ref, CC_LICENSE_REF_PREFIX)) {
    GST_WARNING ("unknown license prefix in ref '%s'", license_ref);
    return -1;
  }

  if (jurisdiction != NULL)
    *jurisdiction = NULL;

  ref = license_ref + sizeof (CC_LICENSE_REF_PREFIX) - 1;
  for (i = 0; i < G_N_ELEMENTS (licenses); ++i) {
    guint64 jbits = licenses[i].jurisdictions;
    const gchar *jurs, *lref = licenses[i].ref;
    gsize lref_len = strlen (lref);

    /* table should have "foo/bar/" with trailing slash */
    g_assert (lref[lref_len - 1] == '/');

    if ((jbits & JURISDICTION_GENERIC)) {
      GST_TRACE ("[%2d] %s checking generic match", i, licenses[i].ref);

      /* exact match? */
      if (strcmp (ref, lref) == 0)
        return i;

      /* exact match but without the trailing slash in ref? */
      if (strncmp (ref, lref, lref_len - 1) == 0 && ref[lref_len - 1] == '\0')
        return i;
    }

    if (!g_str_has_prefix (ref, lref))
      continue;

    GST_TRACE ("[%2d] %s checking jurisdictions", i, licenses[i].ref);

    jbits &= ~JURISDICTION_GENERIC;

    jur_suffix = ref + lref_len;
    if (*jur_suffix == '\0')
      continue;

    jurs = jurisdictions;
    while (jbits != 0) {
      guint jur_len = strlen (jurs);

      if ((jbits & 1)) {
        if (strncmp (jur_suffix, jurs, jur_len) == 0 &&
            (jur_suffix[jur_len] == '\0' || jur_suffix[jur_len] == '/')) {
          GST_LOG ("matched %s to %s with jurisdiction %s (idx %d)",
              license_ref, licenses[i].ref, jurs, i);
          if (jurisdiction != NULL)
            *jurisdiction = jurs;
          return i;
        }
      }
      g_assert (jurs < (jurisdictions + sizeof (jurisdictions)));
      jurs += jur_len + 1;
      jbits >>= 1;
    }
  }

  GST_WARNING ("unhandled license ref '%s'", license_ref);
  return -1;
}

/**
 * gst_tag_get_license_flags:
 * @license_ref: a license reference string in form of a URI,
 *     e.g. "http://creativecommons.org/licenses/by-nc-nd/2.0/"
 *
 * Get the flags of a license, which describe most of the features of
 * a license in their most general form.
 *
 * Returns: the flags of the license, or 0 if the license is unknown
 */
GstTagLicenseFlags
gst_tag_get_license_flags (const gchar * license_ref)
{
  int idx;

  g_return_val_if_fail (license_ref != NULL, 0);

  idx = gst_tag_get_license_idx (license_ref, NULL);
  return (idx < 0) ? 0 : licenses[idx].flags;
}

/**
 * gst_tag_get_license_nick:
 * @license_ref: a license reference string in form of a URI,
 *     e.g. "http://creativecommons.org/licenses/by-nc-nd/2.0/"
 *
 * Get the nick name of a license, which is a short (untranslated) string
 * such as e.g. "CC BY-NC-ND 2.0 UK".
 *
 * Returns: the nick name of the license, or NULL if the license is unknown
 */
const gchar *
gst_tag_get_license_nick (const gchar * license_ref)
{
  GstTagLicenseFlags flags;
  const gchar *creator_prefix, *res;
  gchar *nick, *c;

  g_return_val_if_fail (license_ref != NULL, NULL);

  flags = gst_tag_get_license_flags (license_ref);

  if ((flags & GST_TAG_LICENSE_CREATIVE_COMMONS_LICENSE)) {
    creator_prefix = "CC ";
  } else if ((flags & GST_TAG_LICENSE_FREE_SOFTWARE_FOUNDATION_LICENSE)) {
    creator_prefix = "FSF ";
  } else if (g_str_has_suffix (license_ref, "publicdomain/")) {
    creator_prefix = "";
  } else {
    return NULL;
  }

  nick = g_strdup_printf ("%s%s", creator_prefix,
      license_ref + sizeof (CC_LICENSE_REF_PREFIX) - 1);
  g_strdelimit (nick, "/", ' ');
  g_strchomp (nick);
  for (c = nick; *c != '\0'; ++c)
    *c = g_ascii_toupper (*c);

  GST_LOG ("%s => nick %s", license_ref, nick);
  res = g_intern_string (nick); /* for convenience */
  g_free (nick);

  return res;
}

/**
 * gst_tag_get_license_title:
 * @license_ref: a license reference string in form of a URI,
 *     e.g. "http://creativecommons.org/licenses/by-nc-nd/2.0/"
 *
 * Get the title of a license, which is a short translated description
 * of the license's features (generally not very pretty though).
 *
 * Returns: the title of the license, or NULL if the license is unknown or
 *    no title is available.
 */
const gchar *
gst_tag_get_license_title (const gchar * license_ref)
{
  int idx;

  g_return_val_if_fail (license_ref != NULL, NULL);

  idx = gst_tag_get_license_idx (license_ref, NULL);

  if (idx < 0 || licenses[idx].title_idx < 0)
    return NULL;

  return gst_license_str_translate (&license_strings[licenses[idx].title_idx]);
}

/**
 * gst_tag_get_license_description:
 * @license_ref: a license reference string in form of a URI,
 *     e.g. "http://creativecommons.org/licenses/by-nc-nd/2.0/"
 *
 * Get the description of a license, which is a translated description
 * of the license's main features.
 *
 * Returns: the description of the license, or NULL if the license is unknown
 *    or a description is not available.
 */
const gchar *
gst_tag_get_license_description (const gchar * license_ref)
{
  int idx;

  g_return_val_if_fail (license_ref != NULL, NULL);

  idx = gst_tag_get_license_idx (license_ref, NULL);

  if (idx < 0 || licenses[idx].desc_idx < 0)
    return NULL;

  return gst_license_str_translate (&license_strings[licenses[idx].desc_idx]);
}

/**
 * gst_tag_get_license_jurisdiction:
 * @license_ref: a license reference string in form of a URI,
 *     e.g. "http://creativecommons.org/licenses/by-nc-nd/2.0/"
 *
 * Get the jurisdiction code of a license. This is usually a two-letter
 * ISO 3166-1 alpha-2 code, but there is also the special case of Scotland,
 * for which no code exists and which is thus represented as "scotland".
 *
 * Known jurisdictions: ar, at, au, be, bg, br, ca, ch, cl, cn, co, de,
 * dk, es, fi, fr, hr, hu, il, in, it, jp, kr, mk, mt, mx, my, nl, pe, pl,
 * pt, scotland, se, si, tw, uk, us, za.
 *
 * Returns: the jurisdiction code of the license, or NULL if the license is
 *    unknown or is not specific to a particular jurisdiction.
 */
const gchar *
gst_tag_get_license_jurisdiction (const gchar * license_ref)
{
  const gchar *jurisdiction;
  int idx;

  g_return_val_if_fail (license_ref != NULL, NULL);

  idx = gst_tag_get_license_idx (license_ref, &jurisdiction);
  return (idx < 0) ? NULL : jurisdiction;
}

/**
 * gst_tag_get_license_version:
 * @license_ref: a license reference string in form of a URI,
 *     e.g. "http://creativecommons.org/licenses/by-nc-nd/2.0/"
 *
 * Get the version of a license.
 *
 * Returns: the version of the license, or NULL if the license is not known or
 *    has no version
 */
const gchar *
gst_tag_get_license_version (const gchar * license_ref)
{
  int idx;

  g_return_val_if_fail (license_ref != NULL, NULL);

  idx = gst_tag_get_license_idx (license_ref, NULL);
  if (idx < 0)
    return NULL;

#define LICENSE_FLAG_CC_OR_FSF \
 (GST_TAG_LICENSE_CREATIVE_COMMONS_LICENSE|\
  GST_TAG_LICENSE_FREE_SOFTWARE_FOUNDATION_LICENSE)

  /* e.g. publicdomain isn't versioned */
  if (!(licenses[idx].flags & LICENSE_FLAG_CC_OR_FSF))
    return NULL;

  /* KISS for now... */
  if (strstr (licenses[idx].ref, "/1.0/"))
    return "1.0";
  else if (strstr (licenses[idx].ref, "/2.0/"))
    return "2.0";
  else if (strstr (licenses[idx].ref, "/2.1/"))
    return "2.1";
  else if (strstr (licenses[idx].ref, "/2.5/"))
    return "2.5";
  else if (strstr (licenses[idx].ref, "/3.0/"))
    return "3.0";

  GST_ERROR ("Could not determine version for ref '%s'", license_ref);
  return NULL;
}
