/* GStreamer License 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.
 */

/* mklicensestables.c:
 * little program that reads liblicense's license RDF files and outputs tables
 * with the most important information, so we don't have to parse megabytes
 * of mostly redundant RDF files to get some basic information (and vendors
 * don't have to ship it all).
 */

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

#include "tag.h"

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

/* TODO: we can merge some of the jurisdiction-only license table entries
 * into one entry with multiple jurisdictions and without the 'generic' flag,
 * .e.g. by-nc-nd/2.5/es + by-nc-nd/2.5/au => by-nc-nd/2.5/{es,au} */

#define LIBLICENSE_DATA_PREFIX "/usr/share/liblicense/licenses"

static GHashTable *unknown_sources;     /* NULL */

static GList *licenses;         /* NULL */

/* list of languages used for translations */
static GList *langs;            /* NULL */

/* keep in sync with licenses.c */
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";

/* keep in sync with gst_tag_get_license_version() */
static const gchar known_versions[] = "1.0/2.0/2.1/2.5/3.0/";

/* 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)

typedef struct
{
  gchar *ref;
  guint64 jurisdiction;
  gchar *jurisdiction_suffix;   /* if not generic (e.g. "jp/") */
  gchar *legalcode;
  gchar *version;
  gchar *replaced_by;
  gchar *source;

  GstTagLicenseFlags flags;

  gboolean deprecated;

  GHashTable *titles;
  GHashTable *descriptions;

  /* for processing */
  const gchar *cur_lang;
  gboolean packed_into_source;

  /* list of licenses packed into this one (ie. this is the source of those) */
  GList *derived;
} License;

static GstTagLicenseFlags
ref_to_flag (const gchar * ref)
{
  if (strcmp (ref, "http://creativecommons.org/ns#Reproduction") == 0)
    return GST_TAG_LICENSE_PERMITS_REPRODUCTION;
  if (strcmp (ref, "http://creativecommons.org/ns#Distribution") == 0)
    return GST_TAG_LICENSE_PERMITS_DISTRIBUTION;
  if (strcmp (ref, "http://creativecommons.org/ns#DerivativeWorks") == 0)
    return GST_TAG_LICENSE_PERMITS_DERIVATIVE_WORKS;
  if (strcmp (ref, "http://creativecommons.org/ns#Sharing") == 0)
    return GST_TAG_LICENSE_PERMITS_SHARING;
  if (strcmp (ref, "http://creativecommons.org/ns#Notice") == 0)
    return GST_TAG_LICENSE_REQUIRES_NOTICE;
  if (strcmp (ref, "http://creativecommons.org/ns#Attribution") == 0)
    return GST_TAG_LICENSE_REQUIRES_ATTRIBUTION;
  if (strcmp (ref, "http://creativecommons.org/ns#ShareAlike") == 0)
    return GST_TAG_LICENSE_REQUIRES_SHARE_ALIKE;
  if (strcmp (ref, "http://creativecommons.org/ns#SourceCode") == 0)
    return GST_TAG_LICENSE_REQUIRES_SOURCE_CODE;
  if (strcmp (ref, "http://creativecommons.org/ns#Copyleft") == 0)
    return GST_TAG_LICENSE_REQUIRES_COPYLEFT;
  if (strcmp (ref, "http://creativecommons.org/ns#LesserCopyleft") == 0)
    return GST_TAG_LICENSE_REQUIRES_LESSER_COPYLEFT;
  if (strcmp (ref, "http://creativecommons.org/ns#CommercialUse") == 0)
    return GST_TAG_LICENSE_PROHIBITS_COMMERCIAL_USE;
  if (strcmp (ref, "http://creativecommons.org/ns#HighIncomeNationUse") == 0)
    return GST_TAG_LICENSE_PROHIBITS_HIGH_INCOME_NATION_USE;

  g_error ("Unknown permits/requires/prohibits: %s\n", ref);
  return 0;
};

static guint64
ref_to_jurisdiction (const gchar * ref)
{
  const gchar *j = jurisdictions;
  gchar *jur;
  guint64 bit = 1;

  jur = g_strdup (ref + strlen ("http://creativecommons.org/international/"));
  g_strdelimit (jur, "/", '\0');
  while (j < jurisdictions + sizeof (jurisdictions)) {
    if (strcmp (j, jur) == 0) {
      g_free (jur);
      g_assert (bit != 0 && bit != JURISDICTION_GENERIC);
      return bit;
    }
    j += strlen (j) + 1;
    bit <<= 1;
  }
  g_error ("Unknown jurisdiction '%s'\n", ref);
}

typedef enum
{
  TAG_CC_LICENSE,
  TAG_CC_JURISDICTION,
  TAG_CC_LEGALCODE,
  TAG_CC_PROHIBITS,
  TAG_CC_REQUIRES,
  TAG_CC_PERMITS,
  TAG_CC_DEPRECATED_ON,
  TAG_DC_CREATOR,
  TAG_DC_SOURCE,
  TAG_DC_TITLE,
  TAG_DC_DESCRIPTION,
  TAG_DCQ_HAS_VERSION,
  TAG_DCQ_IS_REPLACED_BY,
  TAG_RDF_RDF,
  TAG_RDF_DESCRIPTION,
} Tag;

static const struct
{
  const gchar *element_name;
  const gchar *attribute;
  const Tag element_tag;
} tag_map[] = {
  {
  "cc:License", "rdf:about", TAG_CC_LICENSE}, {
  "cc:deprecatedOn", "rdf:datatype", TAG_CC_DEPRECATED_ON}, {
  "cc:jurisdiction", "rdf:resource", TAG_CC_JURISDICTION}, {
  "cc:legalcode", "rdf:resource", TAG_CC_LEGALCODE}, {
  "cc:prohibits", "rdf:resource", TAG_CC_PROHIBITS}, {
  "cc:requires", "rdf:resource", TAG_CC_REQUIRES}, {
  "cc:permits", "rdf:resource", TAG_CC_PERMITS}, {
  "dc:creator", "rdf:resource", TAG_DC_CREATOR}, {
  "dc:source", "rdf:resource", TAG_DC_SOURCE}, {
  "dc:title", "xml:lang", TAG_DC_TITLE}, {
  "dc:description", "xml:lang", TAG_DC_DESCRIPTION}, {
  "dcq:hasVersion", NULL, TAG_DCQ_HAS_VERSION}, {
  "dcq:isReplacedBy", "rdf:resource", TAG_DCQ_IS_REPLACED_BY}, {
  "rdf:RDF", NULL, TAG_RDF_RDF}, {
  "rdf:Description", "rdf:about", TAG_RDF_DESCRIPTION},
      /* these three are just for by-nc-nd_2.0_jp_.rdf */
  {
  "dc:isBasedOn", "rdf:resource", TAG_DC_SOURCE}, {
  "dc:hasVersion", NULL, TAG_DCQ_HAS_VERSION}, {
  "dc:isReplacedBy", "rdf:resource", TAG_DCQ_IS_REPLACED_BY}
};

static void
parse_start (GMarkupParseContext * ctx, const gchar * element_name,
    const gchar ** attr_names, const gchar ** attr_vals,
    gpointer user_data, GError ** err)
{
  License *license = user_data;
  const gchar *ref = NULL;
  int i;

  for (i = 0; i < G_N_ELEMENTS (tag_map); ++i) {
    if (strcmp (element_name, tag_map[i].element_name) == 0)
      break;
  }

  if (i == G_N_ELEMENTS (tag_map))
    g_error ("Unexpected tag '%s'\n", element_name);

  if (tag_map[i].attribute == NULL)
    return;

  if (!g_markup_collect_attributes (element_name, attr_names, attr_vals,
          err, G_MARKUP_COLLECT_STRING, tag_map[i].attribute, &ref,
          G_MARKUP_COLLECT_INVALID)) {
    return;
  }

  switch (tag_map[i].element_tag) {
    case TAG_CC_LICENSE:
      if (!g_str_has_prefix (ref, "http://creativecommons.org/licenses/"))
        g_error ("Unexpected license reference: %s\n", ref);
      /* we assume one license per file, and CC license ref */
      g_assert (license->ref == NULL);
      license->ref = g_strdup (ref);
      break;
    case TAG_CC_JURISDICTION:
      if (!g_str_has_prefix (ref, "http://creativecommons.org/international/"))
        g_error ("Unknown license jurisdiction: %s\n", ref);
      /* we assume one jurisdiction per license */
      g_assert (license->jurisdiction == JURISDICTION_GENERIC);
      license->jurisdiction = ref_to_jurisdiction (ref);
      license->jurisdiction_suffix =
          g_strdup (ref + strlen ("http://creativecommons.org/international/"));
      break;
    case TAG_CC_LEGALCODE:
      if (!g_str_has_prefix (ref, "http://creativecommons.org/licenses/"))
        g_error ("Unexpected legalcode reference: %s\n", ref);
      /* we assume one legalcode per license */
      g_assert (license->legalcode == NULL);
      license->legalcode = g_strdup (ref);
      break;
    case TAG_DC_CREATOR:
      if (strcmp (ref, "http://creativecommons.org") == 0) {
        license->flags |= GST_TAG_LICENSE_CREATIVE_COMMONS_LICENSE;
      } else if (strcmp (ref, "http://fsf.org") == 0) {
        license->flags |= GST_TAG_LICENSE_FREE_SOFTWARE_FOUNDATION_LICENSE;
      } else {
        g_error ("Unknown license creator: %s\n", ref);
      }
      break;
    case TAG_CC_DEPRECATED_ON:
      break;
    case TAG_CC_PROHIBITS:
    case TAG_CC_REQUIRES:
    case TAG_CC_PERMITS:
      license->flags |= ref_to_flag (ref);
      break;
    case TAG_DC_TITLE:{
      gchar *cur_lang;

      cur_lang = g_strdelimit (g_strdup (ref), "-", '_');
      license->cur_lang = g_intern_string (cur_lang);
      if (!g_list_find_custom (langs, cur_lang, (GCompareFunc) strcmp))
        langs = g_list_prepend (langs, (gpointer) license->cur_lang);

      g_free (cur_lang);
      break;
    }
    case TAG_DC_DESCRIPTION:{
      gchar *cur_lang;

      cur_lang = g_strdelimit (g_strdup (ref), "-", '_');
      license->cur_lang = g_intern_string (cur_lang);
      if (!g_list_find_custom (langs, cur_lang, (GCompareFunc) strcmp))
        langs = g_list_prepend (langs, (gpointer) license->cur_lang);

      g_free (cur_lang);
      break;
    }
    case TAG_DCQ_IS_REPLACED_BY:
      /* we assume one replacer per license for now */
      g_assert (license->replaced_by == NULL);
      license->replaced_by = g_strdup (ref);
      break;
    case TAG_RDF_DESCRIPTION:
      if (!g_str_has_prefix (ref, "http://creativecommons.org/licenses/"))
        g_error ("Unexpected license reference: %s\n", ref);
      if (license->ref != NULL && strcmp (license->ref, ref) != 0) {
        gchar *f, *r = g_strdup (ref);

        /* work around bug in some of the RDFs ... */
        if ((f = strstr (r, "by-nc-nd"))) {
          memcpy (f, "by-nd-nc", 8);
        }
        if (strcmp (license->ref, r) != 0) {
          g_error ("rdf:Description chunk for other than current license");
        }
        g_free (r);
      }
      break;
    case TAG_DC_SOURCE:
      if (!g_str_has_prefix (ref, "http://creativecommons.org/licenses/"))
        g_error ("Unexpected source reference: %s\n", ref);
      /* we assume one source (for jurisdiction-specific versions) */
      g_assert (license->source == NULL);
      license->source = g_strdup (ref);
      break;
    default:
      g_printerr ("unhandled start tag: %s\n", element_name);
      break;
  }
}

static void
parse_text (GMarkupParseContext * ctx, const gchar * text, gsize text_len,
    gpointer user_data, GError ** err)
{
  License *license = user_data;
  const gchar *element_name, *found;
  int i;

  element_name = g_markup_parse_context_get_element (ctx);
  for (i = 0; i < G_N_ELEMENTS (tag_map); ++i) {
    if (strcmp (element_name, tag_map[i].element_name) == 0)
      break;
  }

  if (i == G_N_ELEMENTS (tag_map))
    g_error ("Unexpected tag '%s'\n", element_name);

  switch (tag_map[i].element_tag) {
    case TAG_CC_LICENSE:
    case TAG_CC_JURISDICTION:
    case TAG_CC_LEGALCODE:
    case TAG_DC_CREATOR:
    case TAG_CC_PROHIBITS:
    case TAG_CC_REQUIRES:
    case TAG_CC_PERMITS:
    case TAG_RDF_RDF:
    case TAG_RDF_DESCRIPTION:
      break;
    case TAG_DC_TITLE:
      if (license->titles == NULL) {
        license->titles = g_hash_table_new (g_str_hash, g_str_equal);
      }
      g_hash_table_insert (license->titles, (gpointer) license->cur_lang,
          (gpointer) g_intern_string (text));
      break;
    case TAG_DC_DESCRIPTION:{
      gchar *txt = g_strdup (text);

      if (license->descriptions == NULL) {
        license->descriptions = g_hash_table_new (g_str_hash, g_str_equal);
      }
      g_strdelimit (txt, "\n", ' ');
      g_hash_table_insert (license->descriptions, (gpointer) license->cur_lang,
          (gpointer) g_intern_string (txt));
      g_free (txt);
      break;
    }
    case TAG_DCQ_HAS_VERSION:
      /* we assume one version per license */
      g_assert (license->version == NULL);
      license->version = g_strdup (text);
      found = strstr (known_versions, license->version);
      if (found == NULL || found[strlen (license->version)] != '/')
        g_error ("Unexpected version '%s', please add to table.", text);
      break;
    case TAG_CC_DEPRECATED_ON:
      license->deprecated = TRUE;
      break;
    case TAG_DC_SOURCE:        // FIXME
    default:
      g_print ("text (%s) (%s): '%s'\n", element_name, license->cur_lang, text);
  }
}

static void
parse_passthrough (GMarkupParseContext * ctx, const gchar * text, gsize len,
    gpointer user_data, GError ** err)
{
  if (!g_str_has_prefix (text, "<?xml ")) {
    g_error ("Unexpected passthrough text: %s\n", text);
  }
}

static void
parse_error (GMarkupParseContext * ctx, GError * err, gpointer data)
{
  g_error ("parse error: %s\n", err->message);
}

static const GMarkupParser license_rdf_parser = {
  parse_start, NULL, parse_text, parse_passthrough, parse_error
};

static void
parse_license_rdf (const gchar * fn, const gchar * rdf)
{
  GMarkupParseContext *ctx;
  License *license;
  GError *err = NULL;

  if (!g_utf8_validate (rdf, -1, NULL)) {
    g_error ("%s is not valid UTF-8\n", fn);
  }

  license = g_new0 (License, 1);

  /* mark as generic until proven otherwise */
  license->jurisdiction = JURISDICTION_GENERIC;

  ctx = g_markup_parse_context_new (&license_rdf_parser,
      G_MARKUP_TREAT_CDATA_AS_TEXT, license, NULL);

  /* g_print ("Parsing %s\n", fn); */

  if (!g_markup_parse_context_parse (ctx, rdf, -1, &err)) {
    g_error ("Error parsing file %s: %s\n", fn, err->message);
    g_clear_error (&err);
  }

  licenses = g_list_append (licenses, license);

  g_markup_parse_context_free (ctx);
}

static void
read_licenses (const gchar * licenses_dir)
{
  const gchar *name;
  GError *err = NULL;
  GDir *dir;

  dir = g_dir_open (licenses_dir, 0, &err);

  if (dir == NULL)
    g_error ("Failed to g_dir_open('%s'): %s", licenses_dir, err->message);
  g_clear_error (&err);

  while ((name = g_dir_read_name (dir))) {
    gchar *fn, *rdf;

    fn = g_build_filename (licenses_dir, name, NULL);
    if (g_file_get_contents (fn, &rdf, NULL, &err)) {
      parse_license_rdf (fn, rdf);
      g_free (rdf);
    } else {
      g_printerr ("Could not read file '%s': %s\n", fn, err->message);
      g_clear_error (&err);
      err = NULL;
    }
    g_free (fn);
  }

  g_dir_close (dir);
}

static License *
find_license (const gchar * ref)
{
  GList *l;

  if (!g_str_has_prefix (ref, "http://creativecommons.org/"))
    return NULL;

  for (l = licenses; l != NULL; l = l->next) {
    License *license = l->data;

    if (strcmp (license->ref, ref) == 0)
      return license;
  }

  return NULL;
}

static int
license_ref_cmp (License * a, License * b)
{
  return strcmp (a->ref, b->ref);
}

#define STRING_TABLE_MAX_STRINGS 100
typedef struct
{
  GString *s;
  guint num_escaped;
  guint num_strings;
  guint indices[STRING_TABLE_MAX_STRINGS];
  gchar *strings[STRING_TABLE_MAX_STRINGS];     /* unescaped strings */
} StringTable;

static StringTable *
string_table_new (void)
{
  StringTable *t = g_new0 (StringTable, 1);

  t->s = g_string_new (NULL);
  return t;
}

static void
string_table_free (StringTable * t)
{
  int i;

  for (i = 0; i < t->num_strings; ++i)
    g_free (t->strings[i]);

  g_string_free (t->s, TRUE);
  g_free (t);
}

static guint
string_table_add_string (StringTable * t, const gchar * str)
{
  const gchar *s;
  guint idx, i;

  /* check if we already have this string */
  for (i = 0; i < t->num_strings; ++i) {
    if (strcmp (t->strings[i], str) == 0)
      return t->indices[i];
  }

  /* save current offset */
  idx = t->s->len;

  /* adjust for fact that \000 is 4 chars now but will take up only 1 later */
  idx -= t->num_escaped * 3;

  /* append one char at a time, making sure to escape UTF-8 characters */
  for (s = str; s != NULL && *s != '\0'; ++s) {
    if (g_ascii_isprint (*s) && *s != '"' && *s != '\\') {
      g_string_append_c (t->s, *s);
    } else {
      g_string_append_printf (t->s, "\\%03o", (unsigned char) *s);
      t->num_escaped++;
    }
  }
  g_string_append (t->s, "\\000");
  t->num_escaped++;

  t->indices[t->num_strings] = idx;
  t->strings[t->num_strings] = g_strdup (str);
  ++t->num_strings;

  return idx;
}

static void
string_table_print (StringTable * t)
{
  const gchar *s;

  s = t->s->str;
  while (s != NULL && *s != '\0') {
    gchar line[74], *lastesc;
    guint left;

    left = strlen (s);
    g_strlcpy (line, s, MIN (left, sizeof (line)));
    s += sizeof (line) - 1;
    /* avoid partial escaped codes at the end of a line */
    if ((lastesc = strrchr (line, '\\')) && strlen (lastesc) < 4) {
      s -= strlen (lastesc);
      *lastesc = '\0';
    }
    g_print ("  \"%s\"", line);
    if (left < 74)
      break;
    g_print ("\n");
  }
  g_print (";\n");
}

/* skip translation if translated string for e.g. "fr_ca" is same as for "fr" */
static gboolean
skip_translation (GHashTable * ht_strings, const gchar * lang,
    const gchar * trans)
{
  const gchar *simple_trans;
  gchar *simple_lang;

  if (strchr (lang, '_') == NULL)
    return FALSE;

  simple_lang = g_strdup (lang);
  g_strdelimit (simple_lang, "_", '\0');

  simple_trans = g_hash_table_lookup (ht_strings, (gpointer) simple_lang);
  g_free (simple_lang);

  return (simple_trans != NULL && strcmp (trans, simple_trans) == 0);
}

static GVariant *
create_translation_dict (GHashTable * ht_strings, const gchar * en)
{
  GVariantBuilder array;
  guint count = 0;
  GList *l;

  g_variant_builder_init (&array, G_VARIANT_TYPE_ARRAY);

  for (l = langs; l != NULL; l = l->next) {
    const gchar *trans, *lang;

    lang = (const gchar *) l->data;
    trans = g_hash_table_lookup (ht_strings, (gpointer) lang);
    if (trans != NULL && *trans != '\0' && strcmp (en, trans) != 0 &&
        !skip_translation (ht_strings, lang, trans)) {
      /* g_print ("%s (%s) => %s\n", en, lang, trans); */
      g_variant_builder_add_value (&array,
          g_variant_new_dict_entry (g_variant_new_string (lang),
              g_variant_new_string (trans)));
      ++count;
    }
  }

  if (count == 0) {
    g_variant_builder_clear (&array);
    return NULL;
  }

  return g_variant_builder_end (&array);
}

static void
write_translations_dictionary (GList * licenses, const gchar * dict_filename)
{
  /* maps C string => (dictionary of: locale => translation) */
  GVariantBuilder array;
  /* maps C string => boolean (if it's in the dictionary already */
  GHashTable *translations;
  GVariant *var;
  GList *l;
  FILE *f;

  /* sort langs for prettiness / to make variant dumps easier to read */
  langs = g_list_sort (langs, (GCompareFunc) strcmp);

  g_variant_builder_init (&array, G_VARIANT_TYPE_ARRAY);

  translations = g_hash_table_new (g_str_hash, g_str_equal);

  for (l = licenses; l != NULL; l = l->next) {
    const gchar *en;
    License *license;

    license = l->data;

    if (license->packed_into_source)
      continue;

    /* add title + translations */
    en = g_hash_table_lookup (license->titles, "en");
    g_assert (en != NULL);

    /* check if we already have added translations for this string */
    if (!g_hash_table_lookup (translations, (gpointer) en)) {
      GVariant *trans;

      trans = create_translation_dict (license->titles, en);
      if (trans != NULL) {
        g_variant_builder_add_value (&array,
            g_variant_new_dict_entry (g_variant_new_string (en), trans));
        g_hash_table_insert (translations, (gpointer) en,
            GINT_TO_POINTER (TRUE));
      }
    }

    /* add description + translations */
    if (license->descriptions == NULL)
      continue;

    en = g_hash_table_lookup (license->descriptions, "en");
    g_assert (en != NULL);

    /* check if we already have added translations for this string */
    if (!g_hash_table_lookup (translations, (gpointer) en)) {
      GVariant *trans;

      trans = create_translation_dict (license->descriptions, en);
      if (trans != NULL) {
        g_variant_builder_add_value (&array,
            g_variant_new_dict_entry (g_variant_new_string (en), trans));
        g_hash_table_insert (translations, (gpointer) en,
            GINT_TO_POINTER (TRUE));
      }
    }
  }

  var = g_variant_builder_end (&array);

  f = fopen (dict_filename, "wb");
  if (fwrite (g_variant_get_data (var), g_variant_get_size (var), 1, f) != 1) {
    g_error ("failed to write dict to file: %s", g_strerror (errno));
  }
  fclose (f);

  g_printerr ("Wrote dictionary to %s, size: %u, type: %s\n", dict_filename,
      (guint) g_variant_get_size (var), (gchar *) g_variant_get_type (var));

  g_variant_unref (var);
  g_hash_table_destroy (translations);
}

int
main (int argc, char **argv)
{
  gchar *translation_dict_fn = NULL;
  GOptionContext *ctx;
  GOptionEntry options[] = {
    {"translation-dictionary", 0, 0, G_OPTION_ARG_FILENAME,
          &translation_dict_fn, "Filename of translations dictionary to write",
        NULL},
    {NULL}
  };
  StringTable *string_table;
  GError *err = NULL;
  GList *l;
  int idx = 0;

  ctx = g_option_context_new ("");
  g_option_context_add_main_entries (ctx, options, NULL);
  if (!g_option_context_parse (ctx, &argc, &argv, &err)) {
    g_printerr ("Error initializing: %s\n", err->message);
    g_option_context_free (ctx);
    g_clear_error (&err);
    exit (1);
  }
  g_option_context_free (ctx);

  read_licenses (LIBLICENSE_DATA_PREFIX);

  g_printerr ("%d licenses\n", g_list_length (licenses));

  unknown_sources = g_hash_table_new (g_str_hash, g_str_equal);

  for (l = licenses; l != NULL; l = l->next) {
    License *license = l->data;

    /* if the license has as source, check if we can 'pack' it into the
     * original license as a jurisdiction-specific variant */
    if (license->source != NULL) {
      License *source = find_license (license->source);

      if (source != NULL) {
        if (source->flags != license->flags) {
          g_printerr ("Source and derived license have different flags:\n"
              "\t0x%08x : %s\n\t0x%08x : %s\n", source->flags, source->ref,
              license->flags, license->ref);
          source = NULL;
        } else {
          if (source->descriptions == NULL) {
            /* neither should the derived one then */
            g_assert (license->descriptions == NULL);
          } else {
            /* make sure we're not settling for fewer descriptions than
             * there are */
            g_assert (g_hash_table_size (license->titles) <=
                g_hash_table_size (source->titles));
            g_assert (g_hash_table_size (license->descriptions) <=
                g_hash_table_size (source->descriptions));
          }
        }
      } else {
        /* a source is referenced that we haven't encountered
         * (possibly a referencing bug? seems to happen e.g. when there's a
         * 2.1 version of a jurisdiction license and it refers to a 2.1
         * source version, but there's only a 2.0 or 2.5 source version. So
         * maybe it's supposed to refer to the 2.0 source then, who knows) */
        if (!g_hash_table_lookup (unknown_sources, license->source)) {
          g_printerr ("Unknown source license %s\n", license->source);
          g_hash_table_insert (unknown_sources, g_strdup (license->source),
              GUINT_TO_POINTER (TRUE));
        }
        /* g_print ("Unknown source license %s referenced from %s\n",
         * license->source, license->ref); */
      }

      /* should we pack this into the source or not */
      if (source != NULL) {
        source->jurisdiction |= license->jurisdiction;
        source->derived = g_list_insert_sorted (source->derived, license,
            (GCompareFunc) license_ref_cmp);
        license->packed_into_source = TRUE;
      }
    } else {
      /* no source license */
      if (license->titles == NULL)
        g_error ("License has no titles: %s\n", license->ref);
      if (license->descriptions == NULL);
      g_printerr ("License %s has no descriptions!\n", license->ref);
    }
  }

  licenses = g_list_sort (licenses, (GCompareFunc) license_ref_cmp);

  string_table = string_table_new ();

  g_print ("/* created by mklicensestables.c */\n");
  g_print ("static const struct {\n"
      "  /* jurisdictions in addition to the generic version, bitfield */\n"
      "  const guint64             jurisdictions;\n"
      "  const GstTagLicenseFlags  flags;\n"
      "  /* the bit after http://creativecommons.org/licenses/ */\n"
      "  const gchar               ref[18];\n"
      "  gint16                    title_idx;  /* index in string table */\n"
      "  gint16                    desc_idx;   /* index in string table */\n"
      "} licenses[] = {\n");

  for (l = licenses; l != NULL; l = l->next) {
    const gchar *title_en, *desc_en;
    int idx_title, idx_desc;
    License *license;

    license = l->data;

    if (license->packed_into_source)
      continue;

    title_en = g_hash_table_lookup (license->titles, "en");
    g_assert (title_en != NULL);
    idx_title = string_table_add_string (string_table, title_en);
    g_assert (idx_title <= G_MAXINT16);

    if (license->descriptions != NULL) {
      desc_en = g_hash_table_lookup (license->descriptions, "en");
      g_assert (desc_en != NULL);
      idx_desc = string_table_add_string (string_table, desc_en);
      g_assert (idx_desc <= G_MAXINT16);
    } else {
      idx_desc = -1;
    }

    /* output comments with license refs covered by the next stanza */
    if (license->derived != NULL) {
      GList *d;

      g_print ("  /* %2d %s\n", idx, license->ref);

      for (d = license->derived; d != NULL; d = d->next) {
        License *derived_license = d->data;

        g_print ("   * %2d %s%s\n", idx, derived_license->ref,
            (d->next == NULL) ? " */" : "");
      }
    } else {
      g_print ("  /* %2d %s */\n", idx, license->ref);
    }
    /* output essential data */
    {
      gchar *ref;

      ref =
          g_strdup (license->ref +
          strlen ("http://creativecommons.org/licenses/"));

      /* remove jurisdiction suffix from ref if this is non-generic, since
       * the suffix is already contained in the jurisdiction flags */
      if (license->jurisdiction_suffix != NULL) {
        gsize suffix_len = strlen (license->jurisdiction_suffix);
        gchar *cutoff;

        cutoff = ref + strlen (ref) - suffix_len;
        g_assert (!strncmp (cutoff, license->jurisdiction_suffix, suffix_len));
        g_assert (cutoff[suffix_len - 1] == '/');
        g_assert (cutoff[suffix_len] == '\0');
        *cutoff = '\0';
      }

      g_print ("  { 0x%016" G_GINT64_MODIFIER "x, 0x%08x, \"%s\", %d, %d }%s\n",
          license->jurisdiction, license->flags, ref, idx_title, idx_desc,
          (l->next != NULL) ? "," : "");

      g_free (ref);
    }
    ++idx;
  }
  g_print ("};\n");

  g_print ("\nstatic const gchar license_strings[] =\n");
  string_table_print (string_table);
  string_table_free (string_table);
  string_table = NULL;

  if (translation_dict_fn != NULL) {
    write_translations_dictionary (licenses, translation_dict_fn);
  }

  return 0;
}
