/* GStreamer
 * Copyright (C) 2006 Stefan Kost <ensonic@users.sf.net>
 *
 * gstpreset.c: helper interface for element presets
 *
 * 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:gstpreset
 * @title: GstPreset
 * @short_description: helper interface for element presets
 *
 * This interface offers methods to query and manipulate parameter preset sets.
 * A preset is a bunch of property settings, together with meta data and a name.
 * The name of a preset serves as key for subsequent method calls to manipulate
 * single presets.
 * All instances of one type will share the list of presets. The list is created
 * on demand, if presets are not used, the list is not created.
 *
 * The interface comes with a default implementation that serves most plugins.
 * Wrapper plugins will override most methods to implement support for the
 * native preset format of those wrapped plugins.
 * One method that is useful to be overridden is gst_preset_get_property_names().
 * With that one can control which properties are saved and in which order.
 * When implementing support for read-only presets, one should set the vmethods
 * for gst_preset_save_preset() and gst_preset_delete_preset() to %NULL.
 * Applications can use gst_preset_is_editable() to check for that.
 *
 * The default implementation supports presets located in a system directory,
 * application specific directory and in the users home directory. When getting
 * a list of presets individual presets are read and overlaid in 1) system,
 * 2) application and 3) user order. Whenever an earlier entry is newer, the
 * later entries will be updated. Since 1.8 you can also provide extra paths
 * where to find presets through the GST_PRESET_PATH environment variable.
 * Presets found in those paths will be concidered as "app presets".
 */
/* FIXME:
 * - non racyness
 *   - we need to avoid two instances writing the preset file
 *     -> flock(fileno()), http://www.ecst.csuchico.edu/~beej/guide/ipc/flock.html
 *     -> open exclusive
 *     -> better save the new file to a tempfile and then rename?
 *   - we like to know when any other instance makes changes to the keyfile
 *     - then ui can be updated
 *     - and we make sure that we don't lose edits
 *   -> its the same problem actually, once for inside a process, once system-
 *      wide
 *     - can we use a lock inside a names shared memory segment?
 *
 * - should there be a 'preset-list' property to get the preset list
 *   (and to connect a notify:: to to listen for changes)
 *   we could use gnome_vfs_monitor_add() to monitor the user preset_file.
 *
 * - should there be a 'preset-name' property so that we can set a preset via
 *   gst-launch, or should we handle this with special syntax in gst-launch:
 *   gst-launch element preset:<preset-name> property=value ...
 *   - this would allow to have preset-bundles too (a preset on bins that
 *     specifies presets for children
 */

#include "gst_private.h"

#include "gstpreset.h"
#include "gstchildproxy.h"
#include "gstinfo.h"
#include "gstvalue.h"

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <glib/gstdio.h>

#ifdef G_OS_WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

extern HMODULE _priv_gst_dll_handle;
#endif

#define GST_CAT_DEFAULT preset_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);

/* defines for keyfile usage, this group contains the element type name and
 * version these presets belong to. */
#define PRESET_HEADER "_presets_"

/* keys of the preset header section */
#define PRESET_HEADER_ELEMENT_NAME "element-name"
#define PRESET_HEADER_VERSION "version"

static GQuark preset_user_path_quark = 0;
static GQuark preset_app_path_quark = 0;
static GQuark preset_system_path_quark = 0;
static GQuark preset_quark = 0;

/* the application can set a custom path that is checked in addition to standard
 * system and user dirs. This helps to develop new presets first local to the
 * application.
 */
static gchar *preset_app_dir = NULL;

/* default iface implementation */

static gboolean gst_preset_default_save_presets_file (GstPreset * preset);

/*
 * preset_get_paths:
 * @preset: a #GObject that implements #GstPreset
 * @preset_user_path: (out) (allow-none): location for path or %NULL
 * @preset_app_path: (out) (allow-none): location for path or %NULL
 * @preset_system_path: (out) (allow-none): location for path or %NULL
 *
 * Fetch the preset_path for user local, application specific and system wide
 * settings. Don't free after use.
 *
 * Returns: %FALSE if no paths could be found.
 */
static gboolean
preset_get_paths (GstPreset * preset, const gchar ** preset_user_path,
    const gchar ** preset_app_path, const gchar ** preset_system_path)
{
  GType type = G_TYPE_FROM_INSTANCE (preset);
  gchar *preset_path;
  const gchar *element_name;

  /* we use the element name when we must construct the paths */
  element_name = G_OBJECT_TYPE_NAME (preset);
  GST_INFO_OBJECT (preset, "element_name: '%s'", element_name);

  if (preset_user_path) {
    /* preset user path requested, see if we have it cached in the qdata */
    if (!(preset_path = g_type_get_qdata (type, preset_user_path_quark))) {
      gchar *preset_dir;

      /* user presets go in  user's XDG data directory. */
      preset_dir = g_build_filename (g_get_user_data_dir (),
          "gstreamer-" GST_API_VERSION, "presets", NULL);
      GST_INFO_OBJECT (preset, "user_preset_dir: '%s'", preset_dir);
      preset_path =
          g_strdup_printf ("%s" G_DIR_SEPARATOR_S "%s.prs", preset_dir,
          element_name);
      GST_INFO_OBJECT (preset, "user_preset_path: '%s'", preset_path);
      /* create dirs */
      g_mkdir_with_parents (preset_dir, 0755);
      g_free (preset_dir);

      /* cache the preset path to the type */
      g_type_set_qdata (type, preset_user_path_quark, preset_path);
    }
    *preset_user_path = preset_path;
  }

  if (preset_app_path) {
    if (preset_app_dir) {
      if (!(preset_path = g_type_get_qdata (type, preset_system_path_quark))) {
        preset_path = g_strdup_printf ("%s" G_DIR_SEPARATOR_S "%s.prs",
            preset_app_dir, element_name);
        GST_INFO_OBJECT (preset, "application_preset_path: '%s'", preset_path);

        /* cache the preset path to the type */
        g_type_set_qdata (type, preset_app_path_quark, preset_path);
      }
      *preset_app_path = preset_path;
    } else {
      *preset_app_path = NULL;
    }
  }

  if (preset_system_path) {
    /* preset system path requested, see if we have it cached in the qdata */
    if (!(preset_path = g_type_get_qdata (type, preset_system_path_quark))) {
      gchar *preset_dir;

      /* system presets in '$GST_DATADIR/gstreamer-1.0/presets/GstAudioPanorama.prs' */
#ifdef G_OS_WIN32
      gchar *basedir =
          g_win32_get_package_installation_directory_of_module
          (_priv_gst_dll_handle);
      preset_dir =
          g_build_filename (basedir, "share", "gstreamer-" GST_API_VERSION,
          "presets", NULL);
      g_free (basedir);
#else
      preset_dir = g_build_filename (GST_DATADIR, "gstreamer-" GST_API_VERSION,
          "presets", NULL);
#endif
      GST_INFO_OBJECT (preset, "system_preset_dir: '%s'", preset_dir);
      preset_path = g_strdup_printf ("%s" G_DIR_SEPARATOR_S "%s.prs",
          preset_dir, element_name);
      GST_INFO_OBJECT (preset, "system_preset_path: '%s'", preset_path);
      /* create dirs */
      g_mkdir_with_parents (preset_dir, 0755);
      g_free (preset_dir);

      /* cache the preset path to the type */
      g_type_set_qdata (type, preset_system_path_quark, preset_path);
    }
    *preset_system_path = preset_path;
  }
  return TRUE;
}

static gboolean
preset_skip_property (GParamSpec * property)
{
  if (((property->flags & G_PARAM_READWRITE) != G_PARAM_READWRITE) ||
      (property->flags & G_PARAM_CONSTRUCT_ONLY))
    return TRUE;
  /* FIXME: skip GST_PARAM_NOT_PRESETABLE, see #522205 */
  return FALSE;
}

static guint64
preset_parse_version (const gchar * str_version)
{
  guint major, minor, micro, nano;
  gint num;

  major = minor = micro = nano = 0;

  /* parse version (e.g. 0.10.15.1) to guint64 */
  num = sscanf (str_version, "%u.%u.%u.%u", &major, &minor, &micro, &nano);
  /* make sure we have at least "major.minor" */
  if (num > 1) {
    guint64 version;

    version = ((((major << 8 | minor) << 8) | micro) << 8) | nano;
    GST_DEBUG ("version %s -> %" G_GUINT64_FORMAT, str_version, version);
    return version;
  }
  return G_GUINT64_CONSTANT (0);
}

static GKeyFile *
preset_open_and_parse_header (GstPreset * preset, const gchar * preset_path,
    guint64 * preset_version)
{
  GKeyFile *in;
  GError *error = NULL;
  gboolean res;
  const gchar *element_name;
  gchar *name;

  in = g_key_file_new ();

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

  /* element type name and preset name must match or we are dealing with a wrong
   * preset file */
  element_name = G_OBJECT_TYPE_NAME (preset);
  name =
      g_key_file_get_value (in, PRESET_HEADER, PRESET_HEADER_ELEMENT_NAME,
      NULL);

  if (!name || strcmp (name, element_name))
    goto wrong_name;

  g_free (name);

  /* get the version now so that the caller can check it */
  if (preset_version) {
    gchar *str =
        g_key_file_get_value (in, PRESET_HEADER, PRESET_HEADER_VERSION, NULL);
    *preset_version = preset_parse_version (str);
    g_free (str);
  }

  return in;

  /* ERRORS */
load_error:
  {
    GST_INFO_OBJECT (preset, "Unable to read preset file %s: %s",
        preset_path, error->message);
    g_error_free (error);
    g_key_file_free (in);
    return NULL;
  }
wrong_name:
  {
    GST_WARNING_OBJECT (preset,
        "Wrong element name in preset file %s. Expected %s, got %s",
        preset_path, element_name, GST_STR_NULL (name));
    g_free (name);
    g_key_file_free (in);
    return NULL;
  }
}

static void
preset_merge (GKeyFile * system, GKeyFile * user)
{
  gchar *str;
  gchar **groups, **keys;
  gsize i, j, num_groups, num_keys;

  /* copy file comment if there is any */
  if ((str = g_key_file_get_comment (user, NULL, NULL, NULL))) {
    g_key_file_set_comment (system, NULL, NULL, str, NULL);
    g_free (str);
  }

  /* get groups in user and copy into system */
  groups = g_key_file_get_groups (user, &num_groups);
  for (i = 0; i < num_groups; i++) {
    /* copy group comment if there is any */
    if ((str = g_key_file_get_comment (user, groups[i], NULL, NULL))) {
      g_key_file_set_comment (system, groups[i], NULL, str, NULL);
      g_free (str);
    }

    /* ignore private groups */
    if (groups[i][0] == '_')
      continue;

    /* if group already exists in system, remove and re-add keys from user */
    if (g_key_file_has_group (system, groups[i])) {
      g_key_file_remove_group (system, groups[i], NULL);
    }

    keys = g_key_file_get_keys (user, groups[i], &num_keys, NULL);
    for (j = 0; j < num_keys; j++) {
      /* copy key comment if there is any */
      if ((str = g_key_file_get_comment (user, groups[i], keys[j], NULL))) {
        g_key_file_set_comment (system, groups[i], keys[j], str, NULL);
        g_free (str);
      }
      str = g_key_file_get_value (user, groups[i], keys[j], NULL);
      g_key_file_set_value (system, groups[i], keys[j], str);
      g_free (str);
    }
    g_strfreev (keys);
  }
  g_strfreev (groups);
}

typedef struct
{
  GKeyFile *preset;
  guint64 version;
} PresetAndVersion;

static gint
compare_preset_and_version (gconstpointer a, gconstpointer b,
    gpointer user_data)
{
  const PresetAndVersion *pa = a, *pb = b;

  if (pa->version > pb->version)
    return -1;
  if (pa->version < pb->version)
    return 1;
  else
    return 0;
}

/* reads the user and system presets files and merges them together. This
 * function caches the GKeyFile on the element type. If there is no existing
 * preset file, a new in-memory GKeyFile will be created. */
static GKeyFile *
preset_get_keyfile (GstPreset * preset)
{
  GKeyFile *presets;
  GType type = G_TYPE_FROM_INSTANCE (preset);

  /* first see if the have a cached version for the type */
  if (!(presets = g_type_get_qdata (type, preset_quark))) {
    const gchar *preset_user_path, *preset_app_path, *preset_system_path;
    guint64 version_system = G_GUINT64_CONSTANT (0);
    guint64 version_app = G_GUINT64_CONSTANT (0);
    guint64 version_user = G_GUINT64_CONSTANT (0);
    guint64 version = G_GUINT64_CONSTANT (0);
    gboolean merged = FALSE;
    GKeyFile *in_user, *in_app = NULL, *in_system;
    GQueue in_env = G_QUEUE_INIT;
    gboolean have_env = FALSE;
    const gchar *envvar;

    /* try to load the user, app and system presets, we do this to get the
     * versions of all files. */
    preset_get_paths (preset, &preset_user_path, &preset_app_path,
        &preset_system_path);
    in_user = preset_open_and_parse_header (preset, preset_user_path,
        &version_user);

    if (preset_app_path) {
      in_app = preset_open_and_parse_header (preset, preset_app_path,
          &version_app);
    }

    envvar = g_getenv ("GST_PRESET_PATH");
    if (envvar) {
      gint i;
      gchar **preset_dirs = g_strsplit (envvar, G_SEARCHPATH_SEPARATOR_S, -1);

      for (i = 0; preset_dirs[i]; i++) {
        gchar *preset_path = g_strdup_printf ("%s" G_DIR_SEPARATOR_S "%s.prs",
            preset_dirs[i], G_OBJECT_TYPE_NAME (preset));
        GKeyFile *env_file;
        guint64 env_version;

        env_file = preset_open_and_parse_header (preset, preset_path,
            &env_version);
        g_free (preset_path);
        if (env_file) {
          PresetAndVersion *pv = g_new (PresetAndVersion, 1);
          pv->preset = env_file;
          pv->version = env_version;
          g_queue_push_tail (&in_env, pv);
          have_env = TRUE;
        }
      }
      g_strfreev (preset_dirs);
    }

    in_system = preset_open_and_parse_header (preset, preset_system_path,
        &version_system);

    /* compare version to check for merge */
    if (in_system) {
      presets = in_system;
      version = version_system;
    }

    if (have_env) {
      GList *l;

      /* merge the ones from the environment paths. If any of them has a
       * higher version, take that as the "master" version. Lower versions are
       * then just merged in. */
      g_queue_sort (&in_env, compare_preset_and_version, NULL);
      /* highest version to lowest */
      for (l = in_env.head; l; l = l->next) {
        PresetAndVersion *pv = l->data;

        if (version > pv->version) {
          preset_merge (presets, pv->preset);
          g_key_file_free (pv->preset);
        } else {
          if (presets)
            g_key_file_free (presets);
          presets = pv->preset;
          version = pv->version;
        }
        g_free (pv);
      }
      g_queue_clear (&in_env);
    }

    if (in_app) {
      /* if system/env version is higher, merge */
      if (version > version_app) {
        preset_merge (presets, in_app);
        g_key_file_free (in_app);
      } else {
        if (presets)
          g_key_file_free (presets);
        presets = in_app;
        version = version_app;
      }
    }
    if (in_user) {
      /* if system/env or app version is higher, merge */
      if (version > version_user) {
        preset_merge (presets, in_user);
        g_key_file_free (in_user);
        merged = TRUE;
      } else {
        if (presets)
          g_key_file_free (presets);
        presets = in_user;
      }
    }

    if (!presets) {
      /* we did not load a user, app or system presets file, create a new one */
      presets = g_key_file_new ();
      g_key_file_set_string (presets, PRESET_HEADER, PRESET_HEADER_ELEMENT_NAME,
          G_OBJECT_TYPE_NAME (preset));
    }

    /* attach the preset to the type */
    g_type_set_qdata (type, preset_quark, (gpointer) presets);

    if (merged) {
      gst_preset_default_save_presets_file (preset);
    }
  }
  return presets;
}

static gint
compare_strings (gchar ** a, gchar ** b, gpointer user_data)
{
  return g_strcmp0 (*a, *b);
}

/* get a list of all supported preset names for an element */
static gchar **
gst_preset_default_get_preset_names (GstPreset * preset)
{
  GKeyFile *presets;
  gsize i, num_groups;
  gchar **groups;

  /* get the presets from the type */
  if (!(presets = preset_get_keyfile (preset)))
    goto no_presets;

  /* get the groups, which are also the preset names */
  if (!(groups = g_key_file_get_groups (presets, &num_groups)))
    goto no_groups;

  /* remove all private group names starting with '_' from the array */
  for (i = 0; i < num_groups; i++) {
    if (groups[i][0] == '_') {
      /* free private group */
      g_free (groups[i]);
      /* move last element of list down */
      num_groups--;
      /* move last element into removed element */
      groups[i] = groups[num_groups];
      groups[num_groups] = NULL;
    }
  }
  if (!num_groups) {
    GST_INFO_OBJECT (preset, "Empty preset file");
    g_strfreev (groups);
    return NULL;
  }

  /* sort the array now */
  g_qsort_with_data (groups, num_groups, sizeof (gchar *),
      (GCompareDataFunc) compare_strings, NULL);

  return groups;

  /* ERRORS */
no_presets:
  {
    GST_WARNING_OBJECT (preset, "Could not load presets");
    return NULL;
  }
no_groups:
  {
    GST_WARNING_OBJECT (preset, "Could not find preset groups");
    return NULL;
  }
}

/* get a list of all property names that are used for presets */
static gchar **
gst_preset_default_get_property_names (GstPreset * preset)
{
  GParamSpec **props;
  guint i, j = 0, n_props;
  GObjectClass *gclass;
  gboolean is_child_proxy;
  gchar **result = NULL;

  gclass = G_OBJECT_CLASS (GST_ELEMENT_GET_CLASS (preset));
  is_child_proxy = GST_IS_CHILD_PROXY (preset);

  /* get a list of object properties */
  props = g_object_class_list_properties (gclass, &n_props);
  if (props) {
    /* allocate array big enough to hold the worst case, including a terminating
     * NULL pointer. */
    result = g_new (gchar *, n_props + 1);

    /* now filter out the properties that we can use for presets */
    GST_DEBUG_OBJECT (preset, "  filtering properties: %u", n_props);
    for (i = 0; i < n_props; i++) {
      if (preset_skip_property (props[i]))
        continue;
      GST_DEBUG_OBJECT (preset, "    using: %s", props[i]->name);
      result[j++] = g_strdup (props[i]->name);
    }
    g_free (props);
  }

  if (is_child_proxy) {
    guint c, n_children;
    GObject *child;

    n_children = gst_child_proxy_get_children_count ((GstChildProxy *) preset);
    for (c = 0; c < n_children; c++) {
      child = gst_child_proxy_get_child_by_index ((GstChildProxy *) preset, c);
      gclass = G_OBJECT_CLASS (GST_ELEMENT_GET_CLASS (child));

      props = g_object_class_list_properties (gclass, &n_props);
      if (props) {
        /* resize property name array */
        result = g_renew (gchar *, result, j + n_props + 1);

        /* now filter out the properties that we can use for presets */
        GST_DEBUG_OBJECT (preset, "  filtering properties: %u", n_props);
        for (i = 0; i < n_props; i++) {
          if (preset_skip_property (props[i]))
            continue;
          GST_DEBUG_OBJECT (preset, "    using: %s::%s",
              GST_OBJECT_NAME (child), props[i]->name);
          result[j++] = g_strdup_printf ("%s::%s", GST_OBJECT_NAME (child),
              props[i]->name);
        }
        g_free (props);
      }

      g_object_unref (child);
    }
  }
  if (!result) {
    GST_INFO_OBJECT (preset, "object has no properties");
  } else {
    result[j] = NULL;
  }
  return result;
}

/* load the presets of @name for the instance @preset. Returns %FALSE if something
 * failed. */
static gboolean
gst_preset_default_load_preset (GstPreset * preset, const gchar * name)
{
  GKeyFile *presets;
  gchar **props;
  guint i;
  GObjectClass *gclass;
  gboolean is_child_proxy;

  /* get the presets from the type */
  if (!(presets = preset_get_keyfile (preset)))
    goto no_presets;

  /* get the preset name */
  if (!g_key_file_has_group (presets, name))
    goto no_group;

  GST_DEBUG_OBJECT (preset, "loading preset : '%s'", name);

  /* get the properties that we can configure in this element */
  if (!(props = gst_preset_get_property_names (preset)))
    goto no_properties;

  gclass = G_OBJECT_CLASS (GST_ELEMENT_GET_CLASS (preset));
  is_child_proxy = GST_IS_CHILD_PROXY (preset);

  /* for each of the property names, find the preset parameter and try to
   * configure the property with its value */
  for (i = 0; props[i]; i++) {
    gchar *str;
    GValue gvalue = { 0, };
    GParamSpec *property = NULL;

    /* check if we have a settings for this element property */
    if (!(str = g_key_file_get_value (presets, name, props[i], NULL))) {
      /* the element has a property but the parameter is not in the keyfile */
      GST_INFO_OBJECT (preset, "parameter '%s' not in preset", props[i]);
      continue;
    }

    GST_DEBUG_OBJECT (preset, "setting value '%s' for property '%s'", str,
        props[i]);

    if (is_child_proxy) {
      gst_child_proxy_lookup ((GstChildProxy *) preset, props[i], NULL,
          &property);
    } else {
      property = g_object_class_find_property (gclass, props[i]);
    }
    if (!property) {
      /* the parameter was in the keyfile, the element said it supported it but
       * then the property was not found in the element. This should not happen. */
      GST_WARNING_OBJECT (preset, "property '%s' not in object", props[i]);
      g_free (str);
      continue;
    }

    /* try to deserialize the property value from the keyfile and set it as
     * the object property */
    g_value_init (&gvalue, property->value_type);
    if (gst_value_deserialize (&gvalue, str)) {
      if (is_child_proxy) {
        gst_child_proxy_set_property ((GstChildProxy *) preset, props[i],
            &gvalue);
      } else {
        g_object_set_property ((GObject *) preset, props[i], &gvalue);
      }
    } else {
      GST_WARNING_OBJECT (preset,
          "deserialization of value '%s' for property '%s' failed", str,
          props[i]);
    }
    g_value_unset (&gvalue);
    g_free (str);
  }
  g_strfreev (props);

  return TRUE;

  /* ERRORS */
no_presets:
  {
    GST_WARNING_OBJECT (preset, "no presets");
    return FALSE;
  }
no_group:
  {
    GST_WARNING_OBJECT (preset, "no preset named '%s'", name);
    return FALSE;
  }
no_properties:
  {
    GST_INFO_OBJECT (preset, "no properties");
    return FALSE;
  }
}

/* save the presets file. A copy of the existing presets file is stored in a
 * .bak file */
static gboolean
gst_preset_default_save_presets_file (GstPreset * preset)
{
  GKeyFile *presets;
  const gchar *preset_path;
  GError *error = NULL;
  gchar *bak_file_name;
  gboolean backup = TRUE;
  gchar *data;
  gsize data_size;

  preset_get_paths (preset, &preset_path, NULL, NULL);

  /* get the presets from the type */
  if (!(presets = preset_get_keyfile (preset)))
    goto no_presets;

  GST_DEBUG_OBJECT (preset, "saving preset file: '%s'", preset_path);

  /* create backup if possible */
  bak_file_name = g_strdup_printf ("%s.bak", preset_path);
  if (g_file_test (bak_file_name, G_FILE_TEST_EXISTS)) {
    if (g_unlink (bak_file_name)) {
      backup = FALSE;
      GST_INFO_OBJECT (preset, "cannot remove old backup file : %s",
          bak_file_name);
    }
  }
  if (backup) {
    if (g_rename (preset_path, bak_file_name)) {
      GST_INFO_OBJECT (preset, "cannot backup file : %s -> %s", preset_path,
          bak_file_name);
    }
  }
  g_free (bak_file_name);

  /* update gstreamer version */
  g_key_file_set_string (presets, PRESET_HEADER, PRESET_HEADER_VERSION,
      PACKAGE_VERSION);

  /* get new contents, wee need this to save it */
  if (!(data = g_key_file_to_data (presets, &data_size, &error)))
    goto convert_failed;

  /* write presets */
  if (!g_file_set_contents (preset_path, data, data_size, &error))
    goto write_failed;

  g_free (data);

  return TRUE;

  /* ERRORS */
no_presets:
  {
    GST_WARNING_OBJECT (preset,
        "no presets, trying to unlink possibly existing preset file: '%s'",
        preset_path);
    g_unlink (preset_path);
    return FALSE;
  }
convert_failed:
  {
    GST_WARNING_OBJECT (preset, "can not get the keyfile contents: %s",
        error->message);
    g_error_free (error);
    g_free (data);
    return FALSE;
  }
write_failed:
  {
    GST_WARNING_OBJECT (preset, "Unable to store preset file %s: %s",
        preset_path, error->message);
    g_error_free (error);
    g_free (data);
    return FALSE;
  }
}

/* save the preset with the given name */
static gboolean
gst_preset_default_save_preset (GstPreset * preset, const gchar * name)
{
  GKeyFile *presets;
  gchar **props;
  guint i;
  GObjectClass *gclass;
  gboolean is_child_proxy;

  GST_INFO_OBJECT (preset, "saving new preset: %s", name);

  /* get the presets from the type */
  if (!(presets = preset_get_keyfile (preset)))
    goto no_presets;

  /* take copies of current gobject properties from preset */
  if (!(props = gst_preset_get_property_names (preset)))
    goto no_properties;

  gclass = G_OBJECT_CLASS (GST_ELEMENT_GET_CLASS (preset));
  is_child_proxy = GST_IS_CHILD_PROXY (preset);

  /* loop over the object properties and store the property value in the
   * keyfile */
  for (i = 0; props[i]; i++) {
    GValue gvalue = { 0, };
    gchar *str;
    GParamSpec *property = NULL;

    if (is_child_proxy) {
      gst_child_proxy_lookup ((GstChildProxy *) preset, props[i], NULL,
          &property);
    } else {
      property = g_object_class_find_property (gclass, props[i]);
    }
    if (!property) {
      /* the element said it supported the property but then it does not have
       * that property. This should not happen. */
      GST_WARNING_OBJECT (preset, "property '%s' not in object", props[i]);
      continue;
    }

    g_value_init (&gvalue, property->value_type);
    if (is_child_proxy) {
      gst_child_proxy_get_property ((GstChildProxy *) preset, props[i],
          &gvalue);
    } else {
      g_object_get_property ((GObject *) preset, props[i], &gvalue);
    }

    if ((str = gst_value_serialize (&gvalue))) {
      g_key_file_set_string (presets, name, props[i], (gpointer) str);
      g_free (str);
    } else {
      GST_WARNING_OBJECT (preset, "serialization for property '%s' failed",
          props[i]);
    }
    g_value_unset (&gvalue);
  }
  GST_INFO_OBJECT (preset, "  saved");
  g_strfreev (props);

  /* save updated version */
  return gst_preset_default_save_presets_file (preset);

  /* ERRORS */
no_presets:
  {
    GST_WARNING_OBJECT (preset, "no presets");
    return FALSE;
  }
no_properties:
  {
    GST_INFO_OBJECT (preset, "no properties");
    return FALSE;
  }
}

/* copies all keys and comments from one group to another, deleting the old
 * group. */
static gboolean
gst_preset_default_rename_preset (GstPreset * preset, const gchar * old_name,
    const gchar * new_name)
{
  GKeyFile *presets;
  gchar *str;
  gchar **keys;
  gsize i, num_keys;

  /* get the presets from the type */
  if (!(presets = preset_get_keyfile (preset)))
    goto no_presets;

  if (!g_key_file_has_group (presets, old_name))
    goto no_group;

  /* copy group comment if there is any */
  if ((str = g_key_file_get_comment (presets, old_name, NULL, NULL))) {
    g_key_file_set_comment (presets, new_name, NULL, str, NULL);
    g_free (str);
  }

  /* get all keys from the old group and copy them in the new group */
  keys = g_key_file_get_keys (presets, old_name, &num_keys, NULL);
  for (i = 0; i < num_keys; i++) {
    /* copy key comment if there is any */
    if ((str = g_key_file_get_comment (presets, old_name, keys[i], NULL))) {
      g_key_file_set_comment (presets, new_name, keys[i], str, NULL);
      g_free (str);
    }
    /* copy key value */
    str = g_key_file_get_value (presets, old_name, keys[i], NULL);
    g_key_file_set_value (presets, new_name, keys[i], str);
    g_free (str);
  }
  g_strfreev (keys);

  /* remove old group */
  g_key_file_remove_group (presets, old_name, NULL);

  /* save updated version */
  return gst_preset_default_save_presets_file (preset);

  /* ERRORS */
no_presets:
  {
    GST_WARNING_OBJECT (preset, "no presets");
    return FALSE;
  }
no_group:
  {
    GST_WARNING_OBJECT (preset, "no preset named %s", old_name);
    return FALSE;
  }
}

/* delete a group from the keyfile */
static gboolean
gst_preset_default_delete_preset (GstPreset * preset, const gchar * name)
{
  GKeyFile *presets;

  /* get the presets from the type */
  if (!(presets = preset_get_keyfile (preset)))
    goto no_presets;

  /* get the group */
  if (!g_key_file_has_group (presets, name))
    goto no_group;

  /* remove the group */
  g_key_file_remove_group (presets, name, NULL);

  /* save updated version */
  return gst_preset_default_save_presets_file (preset);

  /* ERRORS */
no_presets:
  {
    GST_WARNING_OBJECT (preset, "no presets");
    return FALSE;
  }
no_group:
  {
    GST_WARNING_OBJECT (preset, "no preset named %s", name);
    return FALSE;
  }
}

static gboolean
gst_preset_default_set_meta (GstPreset * preset, const gchar * name,
    const gchar * tag, const gchar * value)
{
  GKeyFile *presets;
  gchar *key;

  /* get the presets from the type */
  if (!(presets = preset_get_keyfile (preset)))
    goto no_presets;

  key = g_strdup_printf ("_meta/%s", tag);
  if (value && *value) {
    g_key_file_set_value (presets, name, key, value);
  } else {
    g_key_file_remove_key (presets, name, key, NULL);
  }
  g_free (key);

  /* save updated keyfile */
  return gst_preset_default_save_presets_file (preset);

  /* ERRORS */
no_presets:
  {
    GST_WARNING_OBJECT (preset, "no presets");
    return FALSE;
  }
}

/* the caller must free @value after usage */
static gboolean
gst_preset_default_get_meta (GstPreset * preset, const gchar * name,
    const gchar * tag, gchar ** value)
{
  GKeyFile *presets;
  gchar *key;

  /* get the presets from the type */
  if (!(presets = preset_get_keyfile (preset)))
    goto no_presets;

  key = g_strdup_printf ("_meta/%s", tag);
  *value = g_key_file_get_value (presets, name, key, NULL);
  g_free (key);

  return TRUE;

  /* ERRORS */
no_presets:
  {
    GST_WARNING_OBJECT (preset, "no presets");
    *value = NULL;
    return FALSE;
  }
}

/* wrapper */

/**
 * gst_preset_get_preset_names:
 * @preset: a #GObject that implements #GstPreset
 *
 * Get a copy of preset names as a %NULL terminated string array.
 *
 * Returns: (transfer full) (array zero-terminated=1) (element-type gchar*):
 *     list with names, use g_strfreev() after usage.
 */
gchar **
gst_preset_get_preset_names (GstPreset * preset)
{
  g_return_val_if_fail (GST_IS_PRESET (preset), NULL);

  return (GST_PRESET_GET_INTERFACE (preset)->get_preset_names (preset));
}

/**
 * gst_preset_get_property_names:
 * @preset: a #GObject that implements #GstPreset
 *
 * Get a the names of the GObject properties that can be used for presets.
 *
 * Returns: (transfer full) (array zero-terminated=1) (element-type gchar*): an
 *   array of property names which should be freed with g_strfreev() after use.
 */
gchar **
gst_preset_get_property_names (GstPreset * preset)
{
  g_return_val_if_fail (GST_IS_PRESET (preset), NULL);

  return (GST_PRESET_GET_INTERFACE (preset)->get_property_names (preset));
}

/**
 * gst_preset_load_preset:
 * @preset: a #GObject that implements #GstPreset
 * @name: preset name to load
 *
 * Load the given preset.
 *
 * Returns: %TRUE for success, %FALSE if e.g. there is no preset with that @name
 */
gboolean
gst_preset_load_preset (GstPreset * preset, const gchar * name)
{
  g_return_val_if_fail (GST_IS_PRESET (preset), FALSE);
  g_return_val_if_fail (name, FALSE);

  return (GST_PRESET_GET_INTERFACE (preset)->load_preset (preset, name));
}

/**
 * gst_preset_save_preset:
 * @preset: a #GObject that implements #GstPreset
 * @name: preset name to save
 *
 * Save the current object settings as a preset under the given name. If there
 * is already a preset by this @name it will be overwritten.
 *
 * Returns: %TRUE for success, %FALSE
 */
gboolean
gst_preset_save_preset (GstPreset * preset, const gchar * name)
{
  g_return_val_if_fail (GST_IS_PRESET (preset), FALSE);
  g_return_val_if_fail (name, FALSE);

  return (GST_PRESET_GET_INTERFACE (preset)->save_preset (preset, name));
}

/**
 * gst_preset_rename_preset:
 * @preset: a #GObject that implements #GstPreset
 * @old_name: current preset name
 * @new_name: new preset name
 *
 * Renames a preset. If there is already a preset by the @new_name it will be
 * overwritten.
 *
 * Returns: %TRUE for success, %FALSE if e.g. there is no preset with @old_name
 */
gboolean
gst_preset_rename_preset (GstPreset * preset, const gchar * old_name,
    const gchar * new_name)
{
  g_return_val_if_fail (GST_IS_PRESET (preset), FALSE);
  g_return_val_if_fail (old_name, FALSE);
  g_return_val_if_fail (new_name, FALSE);

  return (GST_PRESET_GET_INTERFACE (preset)->rename_preset (preset, old_name,
          new_name));
}

/**
 * gst_preset_delete_preset:
 * @preset: a #GObject that implements #GstPreset
 * @name: preset name to remove
 *
 * Delete the given preset.
 *
 * Returns: %TRUE for success, %FALSE if e.g. there is no preset with that @name
 */
gboolean
gst_preset_delete_preset (GstPreset * preset, const gchar * name)
{
  g_return_val_if_fail (GST_IS_PRESET (preset), FALSE);
  g_return_val_if_fail (name, FALSE);

  return (GST_PRESET_GET_INTERFACE (preset)->delete_preset (preset, name));
}

/**
 * gst_preset_set_meta:
 * @preset: a #GObject that implements #GstPreset
 * @name: preset name
 * @tag: meta data item name
 * @value: (allow-none): new value
 *
 * Sets a new @value for an existing meta data item or adds a new item. Meta
 * data @tag names can be something like e.g. "comment". Supplying %NULL for the
 * @value will unset an existing value.
 *
 * Returns: %TRUE for success, %FALSE if e.g. there is no preset with that @name
 */
gboolean
gst_preset_set_meta (GstPreset * preset, const gchar * name, const gchar * tag,
    const gchar * value)
{
  g_return_val_if_fail (GST_IS_PRESET (preset), FALSE);
  g_return_val_if_fail (name, FALSE);
  g_return_val_if_fail (tag, FALSE);

  return GST_PRESET_GET_INTERFACE (preset)->set_meta (preset, name, tag, value);
}

/**
 * gst_preset_get_meta:
 * @preset: a #GObject that implements #GstPreset
 * @name: preset name
 * @tag: meta data item name
 * @value: (out callee-allocates): value
 *
 * Gets the @value for an existing meta data @tag. Meta data @tag names can be
 * something like e.g. "comment". Returned values need to be released when done.
 *
 * Returns: %TRUE for success, %FALSE if e.g. there is no preset with that @name
 * or no value for the given @tag
 */
gboolean
gst_preset_get_meta (GstPreset * preset, const gchar * name, const gchar * tag,
    gchar ** value)
{
  g_return_val_if_fail (GST_IS_PRESET (preset), FALSE);
  g_return_val_if_fail (name, FALSE);
  g_return_val_if_fail (tag, FALSE);
  g_return_val_if_fail (value, FALSE);

  return GST_PRESET_GET_INTERFACE (preset)->get_meta (preset, name, tag, value);
}

/**
 * gst_preset_set_app_dir:
 * @app_dir: the application specific preset dir
 *
 * Sets an extra directory as an absolute path that should be considered when
 * looking for presets. Any presets in the application dir will shadow the
 * system presets.
 *
 * Returns: %TRUE for success, %FALSE if the dir already has been set
 */
gboolean
gst_preset_set_app_dir (const gchar * app_dir)
{
  g_return_val_if_fail (app_dir, FALSE);

  if (!preset_app_dir) {
    preset_app_dir = g_strdup (app_dir);
    return TRUE;
  }
  return FALSE;
}

/**
 * gst_preset_get_app_dir:
 *
 * Gets the directory for application specific presets if set by the
 * application.
 *
 * Returns: (nullable): the directory or %NULL, don't free or modify
 * the string
 */
const gchar *
gst_preset_get_app_dir (void)
{
  return preset_app_dir;
}

/**
 * gst_preset_is_editable:
 * @preset: a #GObject that implements #GstPreset
 *
 * Check if one can add new presets, change existing ones and remove presets.
 *
 * Returns: %TRUE if presets are editable or %FALSE if they are static
 *
 * Since: 1.6
 */
gboolean
gst_preset_is_editable (GstPreset * preset)
{
  GstPresetInterface *iface = GST_PRESET_GET_INTERFACE (preset);

  return iface->save_preset && iface->delete_preset;
}

/* class internals */

static void
gst_preset_class_init (GstPresetInterface * iface)
{
  iface->get_preset_names = gst_preset_default_get_preset_names;
  iface->get_property_names = gst_preset_default_get_property_names;

  iface->load_preset = gst_preset_default_load_preset;
  iface->save_preset = gst_preset_default_save_preset;
  iface->rename_preset = gst_preset_default_rename_preset;
  iface->delete_preset = gst_preset_default_delete_preset;

  iface->set_meta = gst_preset_default_set_meta;
  iface->get_meta = gst_preset_default_get_meta;
}

static void
gst_preset_base_init (gpointer g_class)
{
  static gboolean initialized = FALSE;

  if (!initialized) {
    /* init default implementation */
    GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "preset",
        GST_DEBUG_FG_WHITE | GST_DEBUG_BG_BLACK, "preset interface");

    /* create quarks for use with g_type_{g,s}et_qdata() */
    preset_quark = g_quark_from_static_string ("GstPreset::presets");
    preset_user_path_quark =
        g_quark_from_static_string ("GstPreset::user_path");
    preset_app_path_quark = g_quark_from_static_string ("GstPreset::app_path");
    preset_system_path_quark =
        g_quark_from_static_string ("GstPreset::system_path");

#if 0
    /* create interface properties, each element would need to override this
     *   g_object_class_override_property(gobject_class, PROP_PRESET_NAME, "preset-name");
     * and in _set_property() do
     *   case PROP_PRESET_NAME: {
     *     gchar *name = g_value_get_string (value);
     *     if (name)
     *       gst_preset_load_preset(preset, name);
     *   } break;
     */
    g_object_interface_install_property (g_class,
        g_param_spec_string ("preset-name",
            "preset-name property",
            "load given preset", NULL, G_PARAM_WRITABLE));
#endif

    initialized = TRUE;
  }
}

GType
gst_preset_get_type (void)
{
  static volatile gsize type = 0;

  if (g_once_init_enter (&type)) {
    GType _type;
    const GTypeInfo info = {
      sizeof (GstPresetInterface),
      (GBaseInitFunc) gst_preset_base_init,     /* base_init */
      NULL,                     /* base_finalize */
      (GClassInitFunc) gst_preset_class_init,   /* class_init */
      NULL,                     /* class_finalize */
      NULL,                     /* class_data */
      0,
      0,                        /* n_preallocs */
      NULL                      /* instance_init */
    };
    _type = g_type_register_static (G_TYPE_INTERFACE, "GstPreset", &info, 0);
    g_once_init_leave (&type, _type);
  }
  return type;
}
