/* 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);
  return JURISDICTION_GENERIC;
}

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;
}
