/* GStreamer encoding profile registry
 * Copyright (C) 2010 Edward Hervey <edward.hervey@collabora.co.uk>
 *           (C) 2010 Nokia Corporation
 *
 * 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 <locale.h>
#include <errno.h>
#include <string.h>
#include "encoding-target.h"
#include "pbutils-private.h"

/* Documented in encoding-profile.c */

#define GST_ENCODING_TARGET_HEADER "GStreamer Encoding Target"
#define GST_ENCODING_TARGET_DIRECTORY "encoding-profiles"
#define GST_ENCODING_TARGET_SUFFIX ".gep"

struct _GstEncodingTarget
{
  GObject parent;

  gchar *name;
  gchar *category;
  gchar *description;
  GList *profiles;

  /*< private > */
  gchar *keyfile;
};

G_DEFINE_TYPE (GstEncodingTarget, gst_encoding_target, G_TYPE_OBJECT);

static void
gst_encoding_target_init (GstEncodingTarget * target)
{
  /* Nothing to initialize */
}

static void
gst_encoding_target_finalize (GObject * object)
{
  GstEncodingTarget *target = (GstEncodingTarget *) object;

  GST_DEBUG ("Finalizing");

  g_free (target->name);
  g_free (target->category);
  g_free (target->description);

  g_list_foreach (target->profiles, (GFunc) g_object_unref, NULL);
  g_list_free (target->profiles);
}

static void
gst_encoding_target_class_init (GObjectClass * klass)
{
  klass->finalize = gst_encoding_target_finalize;
}

/**
 * gst_encoding_target_get_name:
 * @target: a #GstEncodingTarget
 *
 * Returns: (transfer none): The name of the @target.
 */
const gchar *
gst_encoding_target_get_name (GstEncodingTarget * target)
{
  return target->name;
}

/**
 * gst_encoding_target_get_category:
 * @target: a #GstEncodingTarget
 *
 * Returns: (transfer none): The category of the @target. For example:
 * #GST_ENCODING_CATEGORY_DEVICE.
 */
const gchar *
gst_encoding_target_get_category (GstEncodingTarget * target)
{
  return target->category;
}

/**
 * gst_encoding_target_get_description:
 * @target: a #GstEncodingTarget
 *
 * Returns: (transfer none): The description of the @target.
 */
const gchar *
gst_encoding_target_get_description (GstEncodingTarget * target)
{
  return target->description;
}

/**
 * gst_encoding_target_get_profiles:
 * @target: a #GstEncodingTarget
 *
 * Returns: (transfer none) (element-type GstPbutils.EncodingProfile): A list of
 * #GstEncodingProfile(s) this @target handles.
 */
const GList *
gst_encoding_target_get_profiles (GstEncodingTarget * target)
{
  return target->profiles;
}

/**
 * gst_encoding_target_get_profile:
 * @target: a #GstEncodingTarget
 * @name: the name of the profile to retrieve
 *
 * Returns: (transfer full): The matching #GstEncodingProfile, or %NULL.
 */
GstEncodingProfile *
gst_encoding_target_get_profile (GstEncodingTarget * target, const gchar * name)
{
  GList *tmp;

  g_return_val_if_fail (GST_IS_ENCODING_TARGET (target), NULL);
  g_return_val_if_fail (name != NULL, NULL);

  for (tmp = target->profiles; tmp; tmp = tmp->next) {
    GstEncodingProfile *tprof = (GstEncodingProfile *) tmp->data;

    if (!g_strcmp0 (gst_encoding_profile_get_name (tprof), name)) {
      gst_encoding_profile_ref (tprof);
      return tprof;
    }
  }

  return NULL;
}

static inline gboolean
validate_name (const gchar * name)
{
  guint i, len;

  len = strlen (name);
  if (len == 0)
    return FALSE;

  /* First character can only be a lower case ASCII character */
  if (!g_ascii_isalpha (name[0]) || !g_ascii_islower (name[0]))
    return FALSE;

  /* All following characters can only by:
   * either a lower case ASCII character
   * or an hyphen
   * or a numeric */
  for (i = 1; i < len; i++) {
    /* if uppercase ASCII letter, return */
    if (g_ascii_isupper (name[i]))
      return FALSE;
    /* if a digit, continue */
    if (g_ascii_isdigit (name[i]))
      continue;
    /* if an hyphen, continue */
    if (name[i] == '-')
      continue;
    /* if an ';', continue (list delimiter) */
    if (name[i] == ';') {
      continue;
    }
    /* remaining should only be ascii letters */
    if (!g_ascii_isalpha (name[i]))
      return FALSE;
  }

  return TRUE;
}

/**
 * gst_encoding_target_new:
 * @name: The name of the target.
 * @category: (transfer none): The name of the category to which this @target
 * belongs. For example: #GST_ENCODING_CATEGORY_DEVICE.
 * @description: (transfer none): A description of #GstEncodingTarget in the
 * current locale.
 * @profiles: (transfer none) (element-type GstPbutils.EncodingProfile): A #GList of
 * #GstEncodingProfile.
 *
 * Creates a new #GstEncodingTarget.
 *
 * The name and category can only consist of lowercase ASCII letters for the
 * first character, followed by either lowercase ASCII letters, digits or
 * hyphens ('-').
 *
 * The @category <emphasis>should</emphasis> be one of the existing
 * well-defined categories, like #GST_ENCODING_CATEGORY_DEVICE, but it
 * <emphasis>can</emphasis> be a application or user specific category if
 * needed.
 *
 * Returns: (transfer full): The newly created #GstEncodingTarget or %NULL if
 * there was an error.
 */

GstEncodingTarget *
gst_encoding_target_new (const gchar * name, const gchar * category,
    const gchar * description, const GList * profiles)
{
  GstEncodingTarget *res;

  g_return_val_if_fail (name != NULL, NULL);
  g_return_val_if_fail (category != NULL, NULL);
  g_return_val_if_fail (description != NULL, NULL);

  /* Validate name */
  if (!validate_name (name))
    goto invalid_name;
  if (category && !validate_name (category))
    goto invalid_category;

  res = (GstEncodingTarget *) g_object_new (GST_TYPE_ENCODING_TARGET, NULL);
  res->name = g_strdup (name);
  res->category = g_strdup (category);
  res->description = g_strdup (description);

  while (profiles) {
    GstEncodingProfile *prof = (GstEncodingProfile *) profiles->data;

    res->profiles =
        g_list_append (res->profiles, gst_encoding_profile_ref (prof));
    profiles = profiles->next;
  }

  return res;

invalid_name:
  {
    GST_ERROR ("Invalid name for encoding target : '%s'", name);
    return NULL;
  }

invalid_category:
  {
    GST_ERROR ("Invalid name for encoding category : '%s'", category);
    return NULL;
  }
}

/**
 * gst_encoding_target_add_profile:
 * @target: the #GstEncodingTarget to add a profile to
 * @profile: (transfer full): the #GstEncodingProfile to add
 *
 * Adds the given @profile to the @target. Each added profile must have
 * a unique name within the profile.
 *
 * The @target will steal a reference to the @profile. If you wish to use
 * the profile after calling this method, you should increase its reference
 * count.
 *
 * Returns: %TRUE if the profile was added, else %FALSE.
 **/

gboolean
gst_encoding_target_add_profile (GstEncodingTarget * target,
    GstEncodingProfile * profile)
{
  GList *tmp;

  g_return_val_if_fail (GST_IS_ENCODING_TARGET (target), FALSE);
  g_return_val_if_fail (GST_IS_ENCODING_PROFILE (profile), FALSE);

  /* Make sure profile isn't already controlled by this target */
  for (tmp = target->profiles; tmp; tmp = tmp->next) {
    GstEncodingProfile *prof = (GstEncodingProfile *) tmp->data;

    if (!g_strcmp0 (gst_encoding_profile_get_name (profile),
            gst_encoding_profile_get_name (prof))) {
      GST_WARNING ("Profile already present in target");
      return FALSE;
    }
  }

  target->profiles = g_list_append (target->profiles, profile);

  return TRUE;
}

static gboolean
serialize_stream_profiles (GKeyFile * out, GstEncodingProfile * sprof,
    const gchar * profilename, guint id)
{
  gchar *sprofgroupname;
  gchar *tmpc;
  GstCaps *format, *restriction;
  const gchar *preset, *name, *description;

  sprofgroupname = g_strdup_printf ("streamprofile-%s-%d", profilename, id);

  /* Write the parent profile */
  g_key_file_set_value (out, sprofgroupname, "parent", profilename);

  g_key_file_set_value (out, sprofgroupname, "type",
      gst_encoding_profile_get_type_nick (sprof));

  format = gst_encoding_profile_get_format (sprof);
  if (format) {
    tmpc = gst_caps_to_string (format);
    g_key_file_set_value (out, sprofgroupname, "format", tmpc);
    g_free (tmpc);
  }

  name = gst_encoding_profile_get_name (sprof);
  if (name)
    g_key_file_set_string (out, sprofgroupname, "name", name);

  description = gst_encoding_profile_get_description (sprof);
  if (description)
    g_key_file_set_string (out, sprofgroupname, "description", description);

  preset = gst_encoding_profile_get_preset (sprof);
  if (preset)
    g_key_file_set_string (out, sprofgroupname, "preset", preset);

  restriction = gst_encoding_profile_get_restriction (sprof);
  if (restriction) {
    tmpc = gst_caps_to_string (restriction);
    g_key_file_set_value (out, sprofgroupname, "restriction", tmpc);
    g_free (tmpc);
  }
  g_key_file_set_integer (out, sprofgroupname, "presence",
      gst_encoding_profile_get_presence (sprof));

  if (GST_IS_ENCODING_VIDEO_PROFILE (sprof)) {
    GstEncodingVideoProfile *vp = (GstEncodingVideoProfile *) sprof;

    g_key_file_set_integer (out, sprofgroupname, "pass",
        gst_encoding_video_profile_get_pass (vp));
    g_key_file_set_boolean (out, sprofgroupname, "variableframerate",
        gst_encoding_video_profile_get_variableframerate (vp));
  }

  g_free (sprofgroupname);
  if (format)
    gst_caps_unref (format);
  if (restriction)
    gst_caps_unref (restriction);
  return TRUE;
}

static gchar *
get_locale (void)
{
  const char *loc = NULL;
  gchar *ret;

  gst_pb_utils_init_locale_text_domain ();

#ifdef ENABLE_NLS
#if defined(LC_MESSAGES)
  loc = setlocale (LC_MESSAGES, NULL);
  GST_LOG ("LC_MESSAGES: %s", GST_STR_NULL (loc));
#elif defined(LC_ALL)
  loc = setlocale (LC_ALL, NULL);
  GST_LOG ("LC_ALL: %s", GST_STR_NULL (loc));
#else
  GST_LOG ("Neither LC_ALL nor LC_MESSAGES defined");
#endif
#else /* !ENABLE_NLS */
  GST_LOG ("i18n disabled");
#endif

  if (loc == NULL || g_ascii_strncasecmp (loc, "en", 2) == 0)
    return NULL;

  /* en_GB.UTF-8 => en */
  ret = g_ascii_strdown (loc, -1);
  ret = g_strcanon (ret, "abcdefghijklmnopqrstuvwxyz", '\0');
  GST_LOG ("using locale: %s", ret);
  return ret;
}

/* Serialize the top-level profiles
 * Note: They don't have to be containerprofiles */
static gboolean
serialize_encoding_profile (GKeyFile * out, GstEncodingProfile * prof)
{
  gchar *profgroupname;
  const GList *tmp;
  guint i;
  const gchar *profname, *profdesc, *profpreset, *proftype;
  GstCaps *profformat;

  profname = gst_encoding_profile_get_name (prof);
  profdesc = gst_encoding_profile_get_description (prof);
  profformat = gst_encoding_profile_get_format (prof);
  profpreset = gst_encoding_profile_get_preset (prof);
  proftype = gst_encoding_profile_get_type_nick (prof);

  profgroupname = g_strdup_printf ("profile-%s", profname);

  g_key_file_set_string (out, profgroupname, "name", profname);

  g_key_file_set_value (out, profgroupname, "type", proftype);

  if (profdesc) {
    gchar *locale;

    locale = get_locale ();
    if (locale != NULL) {
      g_key_file_set_locale_string (out, profgroupname, "description",
          locale, profdesc);
      g_free (locale);
    } else {
      g_key_file_set_string (out, profgroupname, "description", profdesc);
    }
  }
  if (profformat) {
    gchar *tmpc = gst_caps_to_string (profformat);
    g_key_file_set_string (out, profgroupname, "format", tmpc);
    g_free (tmpc);
  }
  if (profpreset)
    g_key_file_set_string (out, profgroupname, "preset", profpreset);

  /* stream profiles */
  if (GST_IS_ENCODING_CONTAINER_PROFILE (prof)) {
    for (tmp =
        gst_encoding_container_profile_get_profiles
        (GST_ENCODING_CONTAINER_PROFILE (prof)), i = 0; tmp;
        tmp = tmp->next, i++) {
      GstEncodingProfile *sprof = (GstEncodingProfile *) tmp->data;

      if (!serialize_stream_profiles (out, sprof, profname, i))
        return FALSE;
    }
  }
  if (profformat)
    gst_caps_unref (profformat);
  g_free (profgroupname);
  return TRUE;
}

static gboolean
serialize_target (GKeyFile * out, GstEncodingTarget * target)
{
  GList *tmp;

  g_key_file_set_string (out, GST_ENCODING_TARGET_HEADER, "name", target->name);
  g_key_file_set_string (out, GST_ENCODING_TARGET_HEADER, "category",
      target->category);
  g_key_file_set_string (out, GST_ENCODING_TARGET_HEADER, "description",
      target->description);

  for (tmp = target->profiles; tmp; tmp = tmp->next) {
    GstEncodingProfile *prof = (GstEncodingProfile *) tmp->data;
    if (!serialize_encoding_profile (out, prof))
      return FALSE;
  }

  return TRUE;
}

/**
 * parse_encoding_profile:
 * @in: a #GKeyFile
 * @parentprofilename: the parent profile name (including 'profile-' or 'streamprofile-' header)
 * @profilename: the profile name group to parse
 * @nbgroups: the number of top-level groups
 * @groups: the top-level groups
 */
static GstEncodingProfile *
parse_encoding_profile (GKeyFile * in, gchar * parentprofilename,
    gchar * profilename, gsize nbgroups, gchar ** groups)
{
  GstEncodingProfile *sprof = NULL;
  gchar **parent;
  gchar *proftype, *format, *preset, *restriction, *pname, *description,
      *locale;
  GstCaps *formatcaps = NULL;
  GstCaps *restrictioncaps = NULL;
  gboolean variableframerate;
  gint pass, presence;
  gsize i, nbencprofiles;

  GST_DEBUG ("parentprofilename : %s , profilename : %s",
      parentprofilename, profilename);

  if (parentprofilename) {
    gboolean found = FALSE;

    parent =
        g_key_file_get_string_list (in, profilename, "parent",
        &nbencprofiles, NULL);
    if (!parent || !nbencprofiles) {
      return NULL;
    }

    /* Check if this streamprofile is used in <profilename> */
    for (i = 0; i < nbencprofiles; i++) {
      if (!g_strcmp0 (parent[i], parentprofilename)) {
        found = TRUE;
        break;
      }
    }
    g_strfreev (parent);

    if (!found) {
      GST_DEBUG ("Stream profile '%s' isn't used in profile '%s'",
          profilename, parentprofilename);
      return NULL;
    }
  }

  pname = g_key_file_get_value (in, profilename, "name", NULL);

  locale = get_locale ();
  /* will try to fall back to untranslated string if no translation found */
  description = g_key_file_get_locale_string (in, profilename,
      "description", locale, NULL);
  g_free (locale);

  /* Note: a missing description is normal for non-container profiles */
  if (description == NULL) {
    GST_LOG ("Missing 'description' field for streamprofile %s", profilename);
  }

  /* Parse the remaining fields */
  proftype = g_key_file_get_value (in, profilename, "type", NULL);
  if (!proftype) {
    GST_WARNING ("Missing 'type' field for streamprofile %s", profilename);
    return NULL;
  }

  format = g_key_file_get_value (in, profilename, "format", NULL);
  if (format) {
    formatcaps = gst_caps_from_string (format);
    g_free (format);
  }

  preset = g_key_file_get_value (in, profilename, "preset", NULL);

  restriction = g_key_file_get_value (in, profilename, "restriction", NULL);
  if (restriction) {
    restrictioncaps = gst_caps_from_string (restriction);
    g_free (restriction);
  }

  presence = g_key_file_get_integer (in, profilename, "presence", NULL);
  pass = g_key_file_get_integer (in, profilename, "pass", NULL);
  variableframerate =
      g_key_file_get_boolean (in, profilename, "variableframerate", NULL);

  /* Build the streamprofile ! */
  if (!g_strcmp0 (proftype, "container")) {
    GstEncodingProfile *pprof;

    sprof =
        (GstEncodingProfile *) gst_encoding_container_profile_new (pname,
        description, formatcaps, preset);
    /* Now look for the stream profiles */
    for (i = 0; i < nbgroups; i++) {
      if (!g_ascii_strncasecmp (groups[i], "streamprofile-", 13)) {
        pprof = parse_encoding_profile (in, pname, groups[i], nbgroups, groups);
        if (pprof) {
          gst_encoding_container_profile_add_profile (
              (GstEncodingContainerProfile *) sprof, pprof);
        }
      }
    }
  } else if (!g_strcmp0 (proftype, "video")) {
    sprof =
        (GstEncodingProfile *) gst_encoding_video_profile_new (formatcaps,
        preset, restrictioncaps, presence);
    gst_encoding_video_profile_set_variableframerate ((GstEncodingVideoProfile
            *) sprof, variableframerate);
    gst_encoding_video_profile_set_pass ((GstEncodingVideoProfile *) sprof,
        pass);
    gst_encoding_profile_set_name (sprof, pname);
    gst_encoding_profile_set_description (sprof, description);
  } else if (!g_strcmp0 (proftype, "audio")) {
    sprof =
        (GstEncodingProfile *) gst_encoding_audio_profile_new (formatcaps,
        preset, restrictioncaps, presence);
    gst_encoding_profile_set_name (sprof, pname);
    gst_encoding_profile_set_description (sprof, description);
  } else
    GST_ERROR ("Unknown profile format '%s'", proftype);

  if (restrictioncaps)
    gst_caps_unref (restrictioncaps);
  if (formatcaps)
    gst_caps_unref (formatcaps);

  g_free (pname);
  g_free (description);
  g_free (preset);
  g_free (proftype);

  return sprof;
}

static GstEncodingTarget *
parse_keyfile (GKeyFile * in, gchar * targetname, gchar * categoryname,
    gchar * description)
{
  GstEncodingTarget *res = NULL;
  GstEncodingProfile *prof;
  gchar **groups;
  gsize i, nbgroups;

  res = gst_encoding_target_new (targetname, categoryname, description, NULL);

  /* Figure out the various profiles */
  groups = g_key_file_get_groups (in, &nbgroups);
  for (i = 0; i < nbgroups; i++) {
    if (!g_ascii_strncasecmp (groups[i], "profile-", 8)) {
      prof = parse_encoding_profile (in, NULL, groups[i], nbgroups, groups);
      if (prof)
        gst_encoding_target_add_profile (res, prof);
    }
  }

  g_strfreev (groups);

  g_free (targetname);
  g_free (categoryname);
  g_free (description);

  return res;
}

static GKeyFile *
load_file_and_read_header (const gchar * path, gchar ** targetname,
    gchar ** categoryname, gchar ** description, GError ** error)
{
  GKeyFile *in;
  gboolean res;
  GError *key_error = NULL;

  g_return_val_if_fail (error == NULL || *error == NULL, NULL);

  in = g_key_file_new ();

  GST_DEBUG ("path:%s", path);

  res =
      g_key_file_load_from_file (in, path,
      G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS, &key_error);
  if (!res || key_error != NULL)
    goto load_error;

  key_error = NULL;
  *targetname =
      g_key_file_get_value (in, GST_ENCODING_TARGET_HEADER, "name", &key_error);
  if (!*targetname)
    goto empty_name;

  *categoryname =
      g_key_file_get_value (in, GST_ENCODING_TARGET_HEADER, "category", NULL);
  *description =
      g_key_file_get_value (in, GST_ENCODING_TARGET_HEADER, "description",
      NULL);

  return in;

load_error:
  {
    GST_WARNING ("Unable to read GstEncodingTarget file %s: %s",
        path, key_error->message);
    g_propagate_error (error, key_error);
    g_key_file_free (in);
    return NULL;
  }

empty_name:
  {
    GST_WARNING ("Wrong header in file %s: %s", path, key_error->message);
    g_propagate_error (error, key_error);
    g_key_file_free (in);
    return NULL;
  }
}

/**
 * gst_encoding_target_load_from_file:
 * @filepath: (type filename): The file location to load the #GstEncodingTarget from
 * @error: If an error occured, this field will be filled in.
 *
 * Opens the provided file and returns the contained #GstEncodingTarget.
 *
 * Returns: (transfer full): The #GstEncodingTarget contained in the file, else
 * %NULL
 */

GstEncodingTarget *
gst_encoding_target_load_from_file (const gchar * filepath, GError ** error)
{
  GKeyFile *in;
  gchar *targetname, *categoryname, *description;
  GstEncodingTarget *res = NULL;

  in = load_file_and_read_header (filepath, &targetname, &categoryname,
      &description, error);
  if (!in)
    goto beach;

  res = parse_keyfile (in, targetname, categoryname, description);

  g_key_file_free (in);

beach:
  return res;
}

/*
 * returned list contents must be freed
 */
static GList *
get_matching_filenames (gchar * path, gchar * filename)
{
  GList *res = NULL;
  GDir *topdir;
  const gchar *subdirname;
  gchar *tmp;

  topdir = g_dir_open (path, 0, NULL);
  if (G_UNLIKELY (topdir == NULL))
    return NULL;

  tmp = g_build_filename (path, filename, NULL);
  if (g_file_test (tmp, G_FILE_TEST_EXISTS))
    res = g_list_append (res, tmp);
  else
    g_free (tmp);

  while ((subdirname = g_dir_read_name (topdir))) {
    gchar *ltmp = g_build_filename (path, subdirname, NULL);

    if (g_file_test (ltmp, G_FILE_TEST_IS_DIR)) {
      gchar *tmp = g_build_filename (path, subdirname, filename, NULL);
      /* Test to see if we have a file named like that in that directory */
      if (g_file_test (tmp, G_FILE_TEST_EXISTS))
        res = g_list_append (res, tmp);
      else
        g_free (tmp);
    }
    g_free (ltmp);
  }

  g_dir_close (topdir);

  return res;
}

static GstEncodingTarget *
gst_encoding_target_subload (gchar * path, const gchar * category,
    gchar * lfilename, GError ** error)
{
  GstEncodingTarget *target = NULL;

  if (category) {
    gchar *filename;

    filename = g_build_filename (path, category, lfilename, NULL);
    target = gst_encoding_target_load_from_file (filename, error);
    g_free (filename);
  } else {
    GList *tmp, *tries = get_matching_filenames (path, lfilename);

    /* Try to find a file named %s.gstprofile in any subdirectories */
    for (tmp = tries; tmp; tmp = tmp->next) {
      target = gst_encoding_target_load_from_file ((gchar *) tmp->data, NULL);
      if (target)
        break;
    }
    g_list_foreach (tries, (GFunc) g_free, NULL);
    if (tries)
      g_list_free (tries);
  }

  return target;
}

/**
 * gst_encoding_target_load:
 * @name: the name of the #GstEncodingTarget to load (automatically
 * converted to lower case internally as capital letters are not
 * valid for target names).
 * @category: (allow-none): the name of the target category, like
 * #GST_ENCODING_CATEGORY_DEVICE. Can be %NULL
 * @error: If an error occured, this field will be filled in.
 *
 * Searches for the #GstEncodingTarget with the given name, loads it
 * and returns it.
 *
 * If the category name is specified only targets from that category will be
 * searched for.
 *
 * Returns: (transfer full): The #GstEncodingTarget if available, else %NULL.
 */
GstEncodingTarget *
gst_encoding_target_load (const gchar * name, const gchar * category,
    GError ** error)
{
  gint i;
  gchar *p, *lname, *lfilename = NULL, *tldir, **encoding_target_dirs;
  const gchar *envvar;
  GstEncodingTarget *target = NULL;

  g_return_val_if_fail (name != NULL, NULL);

  p = lname = g_str_to_ascii (name, NULL);
  for (; *p; ++p)
    *p = g_ascii_tolower (*p);

  if (!validate_name (lname))
    goto invalid_name;

  if (category && !validate_name (category))
    goto invalid_category;

  lfilename = g_strdup_printf ("%s" GST_ENCODING_TARGET_SUFFIX, lname);

  envvar = g_getenv ("GST_ENCODING_TARGET_PATH");
  if (envvar) {
    encoding_target_dirs = g_strsplit (envvar, G_SEARCHPATH_SEPARATOR_S, -1);
    for (i = 0; encoding_target_dirs[i]; i++) {
      target = gst_encoding_target_subload (encoding_target_dirs[i],
          category, lfilename, error);

      if (target)
        break;
    }
    g_strfreev (encoding_target_dirs);
    if (target)
      goto done;
  }

  /* Try from local profiles */

  tldir =
      g_build_filename (g_get_user_data_dir (), "gstreamer-" GST_API_VERSION,
      GST_ENCODING_TARGET_DIRECTORY, NULL);
  target = gst_encoding_target_subload (tldir, category, lfilename, error);
  g_free (tldir);

  if (target == NULL) {
    /* Try from system-wide profiles */
    tldir =
        g_build_filename (GST_DATADIR, "gstreamer-" GST_API_VERSION,
        GST_ENCODING_TARGET_DIRECTORY, NULL);
    target = gst_encoding_target_subload (tldir, category, lfilename, error);
    g_free (tldir);
  }

  if (!target) {
    GList *tmp, *targets = gst_encoding_list_all_targets (NULL);

    for (tmp = targets; tmp; tmp = tmp->next) {
      gint i;
      GstEncodingTarget *tmptarget = tmp->data;
      gchar **names = g_strsplit (tmptarget->name, ";", -1);

      for (i = 0; names[i]; i++) {
        if (!g_strcmp0 (names[i], lname) && (!category ||
                !g_strcmp0 (tmptarget->category, category))) {
          target = gst_object_ref (tmptarget);

          break;
        }
      }
      g_strfreev (names);

      if (target)
        break;
    }

    g_list_free_full (targets, gst_object_unref);
  }


done:
  g_free (lfilename);
  g_free (lname);

  return target;

invalid_name:
  {
    GST_ERROR ("Invalid name for encoding target : '%s'", name);
    goto done;
  }
invalid_category:
  {
    GST_ERROR ("Invalid name for encoding category : '%s'", category);
    goto done;
  }
}

/**
 * gst_encoding_target_save_to_file:
 * @target: a #GstEncodingTarget
 * @filepath: (type filename): the location to store the @target at.
 * @error: If an error occured, this field will be filled in.
 *
 * Saves the @target to the provided file location.
 *
 * Returns: %TRUE if the target was correctly saved, else %FALSE.
 **/

gboolean
gst_encoding_target_save_to_file (GstEncodingTarget * target,
    const gchar * filepath, GError ** error)
{
  GKeyFile *out;
  gchar *data;
  gsize data_size;

  g_return_val_if_fail (GST_IS_ENCODING_TARGET (target), FALSE);
  g_return_val_if_fail (filepath != NULL, FALSE);

  /* FIXME : Check filepath is valid and writable
   * FIXME : Strip out profiles already present in system target */

  /* Get unique name... */

  /* Create output GKeyFile */
  out = g_key_file_new ();

  if (!serialize_target (out, target))
    goto serialize_failure;

  if (!(data = g_key_file_to_data (out, &data_size, error)))
    goto convert_failed;

  if (!g_file_set_contents (filepath, data, data_size, error))
    goto write_failed;

  g_key_file_free (out);
  g_free (data);

  return TRUE;

serialize_failure:
  {
    GST_ERROR ("Failure serializing target");
    g_key_file_free (out);
    return FALSE;
  }

convert_failed:
  {
    GST_ERROR ("Failure converting keyfile: %s", (*error)->message);
    g_key_file_free (out);
    g_free (data);
    return FALSE;
  }

write_failed:
  {
    GST_ERROR ("Unable to write file %s: %s", filepath, (*error)->message);
    g_key_file_free (out);
    g_free (data);
    return FALSE;
  }
}

/**
 * gst_encoding_target_save:
 * @target: a #GstEncodingTarget
 * @error: If an error occured, this field will be filled in.
 *
 * Saves the @target to a default user-local directory.
 *
 * Returns: %TRUE if the target was correctly saved, else %FALSE.
 **/

gboolean
gst_encoding_target_save (GstEncodingTarget * target, GError ** error)
{
  gchar *filename;
  gchar *lfilename;
  gchar *dirname;

  g_return_val_if_fail (GST_IS_ENCODING_TARGET (target), FALSE);
  g_return_val_if_fail (target->category != NULL, FALSE);

  lfilename = g_strdup_printf ("%s" GST_ENCODING_TARGET_SUFFIX, target->name);
  dirname =
      g_build_filename (g_get_user_data_dir (), "gstreamer-" GST_API_VERSION,
      GST_ENCODING_TARGET_DIRECTORY, target->category, NULL);
  errno = 0;
  if (g_mkdir_with_parents (dirname, 0755)) {
    GST_ERROR_OBJECT (target, "Could not create directory to save %s into: %s",
        target->name, g_strerror (errno));

    return FALSE;
  }
  filename = g_build_filename (dirname, lfilename, NULL);
  g_free (dirname);
  g_free (lfilename);

  gst_encoding_target_save_to_file (target, filename, error);
  g_free (filename);

  return TRUE;
}

static GList *
get_categories (gchar * path)
{
  GList *res = NULL;
  GDir *topdir;
  const gchar *subdirname;

  topdir = g_dir_open (path, 0, NULL);
  if (G_UNLIKELY (topdir == NULL))
    return NULL;

  while ((subdirname = g_dir_read_name (topdir))) {
    gchar *ltmp = g_build_filename (path, subdirname, NULL);

    if (g_file_test (ltmp, G_FILE_TEST_IS_DIR)) {
      res = g_list_append (res, (gpointer) g_strdup (subdirname));
    }
    g_free (ltmp);
  }

  g_dir_close (topdir);

  return res;
}

/**
 * gst_encoding_list_available_categories:
 *
 * Lists all #GstEncodingTarget categories present on disk.
 *
 * Returns: (transfer full) (element-type gchar*): A list
 * of #GstEncodingTarget categories.
 */
GList *
gst_encoding_list_available_categories (void)
{
  GList *res = NULL;
  GList *tmp1, *tmp2;
  gchar *topdir;

  /* First try user-local categories */
  topdir =
      g_build_filename (g_get_user_data_dir (), "gstreamer-" GST_API_VERSION,
      GST_ENCODING_TARGET_DIRECTORY, NULL);
  res = get_categories (topdir);
  g_free (topdir);

  /* Extend with system-wide categories */
  topdir = g_build_filename (GST_DATADIR, "gstreamer-" GST_API_VERSION,
      GST_ENCODING_TARGET_DIRECTORY, NULL);
  tmp1 = get_categories (topdir);
  g_free (topdir);

  for (tmp2 = tmp1; tmp2; tmp2 = tmp2->next) {
    gchar *name = (gchar *) tmp2->data;
    if (!g_list_find_custom (res, name, (GCompareFunc) g_strcmp0))
      res = g_list_append (res, (gpointer) name);
    else
      g_free (name);
  }
  g_list_free (tmp1);

  return res;
}

static inline GList *
sub_get_all_targets (gchar * subdir)
{
  GList *res = NULL;
  const gchar *filename;
  GDir *dir;
  GstEncodingTarget *target;

  dir = g_dir_open (subdir, 0, NULL);
  if (G_UNLIKELY (dir == NULL))
    return NULL;

  while ((filename = g_dir_read_name (dir))) {
    gchar *fullname;

    /* Only try files ending with .gstprofile */
    if (!g_str_has_suffix (filename, GST_ENCODING_TARGET_SUFFIX))
      continue;

    fullname = g_build_filename (subdir, filename, NULL);
    target = gst_encoding_target_load_from_file (fullname, NULL);
    if (target) {
      res = g_list_append (res, target);
    } else
      GST_WARNING ("Failed to get a target from %s", fullname);
    g_free (fullname);
  }
  g_dir_close (dir);

  return res;
}

static inline GList *
get_all_targets (gchar * topdir, const gchar * categoryname)
{
  GList *res = NULL;

  if (categoryname) {
    gchar *subdir = g_build_filename (topdir, categoryname, NULL);
    /* Try to open the directory */
    res = sub_get_all_targets (subdir);
    g_free (subdir);
  } else {
    const gchar *subdirname;
    GDir *dir = g_dir_open (topdir, 0, NULL);

    if (G_UNLIKELY (dir == NULL))
      return NULL;

    while ((subdirname = g_dir_read_name (dir))) {
      gchar *ltmp = g_build_filename (topdir, subdirname, NULL);

      if (g_file_test (ltmp, G_FILE_TEST_IS_DIR)) {
        res = g_list_concat (res, sub_get_all_targets (ltmp));
      }
      g_free (ltmp);
    }
    g_dir_close (dir);
  }

  return res;
}

static guint
compare_targets (const GstEncodingTarget * ta, const GstEncodingTarget * tb)
{
  if (g_strcmp0 (ta->name, tb->name)
      || g_strcmp0 (ta->category, tb->category))
    return -1;

  return 0;
}

static GList *
merge_targets (GList * res, GList * extra)
{
  GList *tmp;

  /* FIXME : We should merge the system-wide profiles into the user-locals
   * instead of stopping at identical target names */
  for (tmp = extra; tmp; tmp = tmp->next) {
    GstEncodingTarget *target = (GstEncodingTarget *) tmp->data;
    if (g_list_find_custom (res, target, (GCompareFunc) compare_targets))
      gst_encoding_target_unref (target);
    else
      res = g_list_append (res, target);
  }

  g_list_free (extra);

  return res;
}

/**
 * gst_encoding_list_all_targets:
 * @categoryname: (allow-none): The category, for ex: #GST_ENCODING_CATEGORY_DEVICE.
 * Can be %NULL.
 *
 * List all available #GstEncodingTarget for the specified category, or all categories
 * if @categoryname is %NULL.
 *
 * Returns: (transfer full) (element-type GstEncodingTarget): The list of #GstEncodingTarget
 */
GList *
gst_encoding_list_all_targets (const gchar * categoryname)
{
  GList *res = NULL;
  gchar *topdir;
  gchar **encoding_target_dirs;

  const gchar *envvar = g_getenv ("GST_ENCODING_TARGET_PATH");
  if (envvar) {
    gint i;

    encoding_target_dirs = g_strsplit (envvar, G_SEARCHPATH_SEPARATOR_S, -1);
    for (i = 0; encoding_target_dirs[i]; i++)
      res =
          merge_targets (res, get_all_targets (encoding_target_dirs[i],
              categoryname));

    g_strfreev (encoding_target_dirs);
  }

  /* Get user-locals */
  topdir =
      g_build_filename (g_get_user_data_dir (), "gstreamer-" GST_API_VERSION,
      GST_ENCODING_TARGET_DIRECTORY, NULL);
  res = merge_targets (res, get_all_targets (topdir, categoryname));
  g_free (topdir);

  /* Get system-wide */
  topdir = g_build_filename (GST_DATADIR, "gstreamer-" GST_API_VERSION,
      GST_ENCODING_TARGET_DIRECTORY, NULL);
  res = merge_targets (res, get_all_targets (topdir, categoryname));
  g_free (topdir);

  return res;
}
