/*
 * Copyright © 2010 Codethink Limited
 * Copyright © 2010 Novell, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 *
 * Authors: Vincent Untz <vuntz@gnome.org>
 *          Ryan Lortie <desrt@desrt.ca>
 */

#include "config.h"

#include <glib.h>
#include <glibintl.h>

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

#include "gfile.h"
#include "gfileinfo.h"
#include "gfileenumerator.h"
#include "gfilemonitor.h"
#include "gsimplepermission.h"
#include "gsettingsbackendinternal.h"
#include "giomodule-priv.h"
#include "gportalsupport.h"


#define G_TYPE_KEYFILE_SETTINGS_BACKEND      (g_keyfile_settings_backend_get_type ())
#define G_KEYFILE_SETTINGS_BACKEND(inst)     (G_TYPE_CHECK_INSTANCE_CAST ((inst),      \
                                              G_TYPE_KEYFILE_SETTINGS_BACKEND,         \
                                              GKeyfileSettingsBackend))
#define G_IS_KEYFILE_SETTINGS_BACKEND(inst)  (G_TYPE_CHECK_INSTANCE_TYPE ((inst),      \
                                              G_TYPE_KEYFILE_SETTINGS_BACKEND))


typedef GSettingsBackendClass GKeyfileSettingsBackendClass;

typedef enum {
  PROP_FILENAME = 1,
  PROP_ROOT_PATH,
  PROP_ROOT_GROUP,
  PROP_DEFAULTS_DIR
} GKeyfileSettingsBackendProperty;

typedef struct
{
  GSettingsBackend   parent_instance;

  GKeyFile          *keyfile;
  GPermission       *permission;
  gboolean           writable;
  char              *defaults_dir;
  GKeyFile          *system_keyfile;
  GHashTable        *system_locks; /* Used as a set, owning the strings it contains */

  gchar             *prefix;
  gint               prefix_len;
  gchar             *root_group;
  gint               root_group_len;

  GFile             *file;
  GFileMonitor      *file_monitor;
  guint8             digest[32];
  GFile             *dir;
  GFileMonitor      *dir_monitor;
} GKeyfileSettingsBackend;

#ifdef G_OS_WIN32
#define EXTENSION_PRIORITY 10
#else
#define EXTENSION_PRIORITY (glib_should_use_portal () && !glib_has_dconf_access_in_sandbox () ? 110 : 10)
#endif

G_DEFINE_TYPE_WITH_CODE (GKeyfileSettingsBackend,
                         g_keyfile_settings_backend,
                         G_TYPE_SETTINGS_BACKEND,
                         _g_io_modules_ensure_extension_points_registered ();
                         g_io_extension_point_implement (G_SETTINGS_BACKEND_EXTENSION_POINT_NAME,
                                                         g_define_type_id, "keyfile", EXTENSION_PRIORITY))

static void
compute_checksum (guint8        *digest,
                  gconstpointer  contents,
                  gsize          length)
{
  GChecksum *checksum;
  gsize len = 32;

  checksum = g_checksum_new (G_CHECKSUM_SHA256);
  g_checksum_update (checksum, contents, length);
  g_checksum_get_digest (checksum, digest, &len);
  g_checksum_free (checksum);
  g_assert (len == 32);
}

static gboolean
g_keyfile_settings_backend_keyfile_write (GKeyfileSettingsBackend  *kfsb,
                                          GError                  **error)
{
  gchar *contents;
  gsize length;
  gboolean success;

  contents = g_key_file_to_data (kfsb->keyfile, &length, NULL);
  success = g_file_replace_contents (kfsb->file, contents, length, NULL, FALSE,
                                     G_FILE_CREATE_REPLACE_DESTINATION |
                                     G_FILE_CREATE_PRIVATE,
                                     NULL, NULL, error);

  compute_checksum (kfsb->digest, contents, length);
  g_free (contents);

  return success;
}

static gboolean
group_name_matches (const gchar *group_name,
                    const gchar *prefix)
{
  /* sort of like g_str_has_prefix() except that it must be an exact
   * match or the prefix followed by '/'.
   *
   * for example 'a' is a prefix of 'a' and 'a/b' but not 'ab'.
   */
  gint i;

  for (i = 0; prefix[i]; i++)
    if (prefix[i] != group_name[i])
      return FALSE;

  return group_name[i] == '\0' || group_name[i] == '/';
}

static gboolean
convert_path (GKeyfileSettingsBackend  *kfsb,
              const gchar              *key,
              gchar                   **group,
              gchar                   **basename)
{
  gsize key_len = strlen (key);
  const gchar *last_slash;

  if (key_len < kfsb->prefix_len ||
      memcmp (key, kfsb->prefix, kfsb->prefix_len) != 0)
    return FALSE;

  key_len -= kfsb->prefix_len;
  key += kfsb->prefix_len;

  last_slash = strrchr (key, '/');

  /* Disallow empty group names or key names */
  if (key_len == 0 ||
      (last_slash != NULL &&
       (*(last_slash + 1) == '\0' ||
        last_slash == key)))
    return FALSE;

  if (kfsb->root_group)
    {
      /* if a root_group was specified, make sure the user hasn't given
       * a path that ghosts that group name
       */
      if (last_slash != NULL && (last_slash - key) == kfsb->root_group_len && memcmp (key, kfsb->root_group, last_slash - key) == 0)
        return FALSE;
    }
  else
    {
      /* if no root_group was given, ensure that the user gave a path */
      if (last_slash == NULL)
        return FALSE;
    }

  if (group)
    {
      if (last_slash != NULL)
        {
          *group = g_memdup2 (key, (last_slash - key) + 1);
          (*group)[(last_slash - key)] = '\0';
        }
      else
        *group = g_strdup (kfsb->root_group);
    }

  if (basename)
    {
      if (last_slash != NULL)
        *basename = g_memdup2 (last_slash + 1, key_len - (last_slash - key));
      else
        *basename = g_strdup (key);
    }

  return TRUE;
}

static gboolean
path_is_valid (GKeyfileSettingsBackend *kfsb,
               const gchar             *path)
{
  return convert_path (kfsb, path, NULL, NULL);
}

static GVariant *
get_from_keyfile (GKeyfileSettingsBackend *kfsb,
                  const GVariantType      *type,
                  const gchar             *key)
{
  GVariant *return_value = NULL;
  gchar *group, *name;

  if (convert_path (kfsb, key, &group, &name))
    {
      gchar *str;
      gchar *sysstr;

      g_assert (*name);

      sysstr = g_key_file_get_value (kfsb->system_keyfile, group, name, NULL);
      str = g_key_file_get_value (kfsb->keyfile, group, name, NULL);
      if (sysstr &&
          (g_hash_table_contains (kfsb->system_locks, key) ||
           str == NULL))
        {
          g_free (str);
          str = g_steal_pointer (&sysstr);
        }

      if (str)
        {
          return_value = g_variant_parse (type, str, NULL, NULL, NULL);

          /* As a special case, support values of type %G_VARIANT_TYPE_STRING
           * not being quoted, since users keep forgetting to do it and then
           * getting confused. */
          if (return_value == NULL &&
              g_variant_type_equal (type, G_VARIANT_TYPE_STRING) &&
              str[0] != '\"')
            {
              GString *s = g_string_sized_new (strlen (str) + 2);
              char *p = str;

              g_string_append_c (s, '\"');
              while (*p)
                {
                  if (*p == '\"')
                    g_string_append_c (s, '\\');
                  g_string_append_c (s, *p);
                  p++;
                }
              g_string_append_c (s, '\"');
              return_value = g_variant_parse (type, s->str, NULL, NULL, NULL);
              g_string_free (s, TRUE);
            }
          g_free (str);
        }

      g_free (sysstr);

      g_free (group);
      g_free (name);
    }

  return return_value;
}

static gboolean
set_to_keyfile (GKeyfileSettingsBackend *kfsb,
                const gchar             *key,
                GVariant                *value)
{
  gchar *group, *name;

  if (g_hash_table_contains (kfsb->system_locks, key))
    return FALSE;

  if (convert_path (kfsb, key, &group, &name))
    {
      if (value)
        {
          gchar *str = g_variant_print (value, FALSE);
          g_key_file_set_value (kfsb->keyfile, group, name, str);
          g_variant_unref (g_variant_ref_sink (value));
          g_free (str);
        }
      else
        {
          if (*name == '\0')
            {
              gchar **groups;
              gint i;

              groups = g_key_file_get_groups (kfsb->keyfile, NULL);

              for (i = 0; groups[i]; i++)
                if (group_name_matches (groups[i], group))
                  g_key_file_remove_group (kfsb->keyfile, groups[i], NULL);

              g_strfreev (groups);
            }
          else
            g_key_file_remove_key (kfsb->keyfile, group, name, NULL);
        }

      g_free (group);
      g_free (name);

      return TRUE;
    }

  return FALSE;
}

static GVariant *
g_keyfile_settings_backend_read (GSettingsBackend   *backend,
                                 const gchar        *key,
                                 const GVariantType *expected_type,
                                 gboolean            default_value)
{
  GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (backend);

  if (default_value)
    return NULL;

  return get_from_keyfile (kfsb, expected_type, key);
}

typedef struct
{
  GKeyfileSettingsBackend *kfsb;
  gboolean failed;
} WriteManyData;

static gboolean
g_keyfile_settings_backend_write_one (gpointer key,
                                      gpointer value,
                                      gpointer user_data)
{
  WriteManyData *data = user_data;
  gboolean success G_GNUC_UNUSED  /* when compiling with G_DISABLE_ASSERT */;

  success = set_to_keyfile (data->kfsb, key, value);
  g_assert (success);

  return FALSE;
}

static gboolean
g_keyfile_settings_backend_check_one (gpointer key,
                                      gpointer value,
                                      gpointer user_data)
{
  WriteManyData *data = user_data;

  return data->failed = g_hash_table_contains (data->kfsb->system_locks, key) ||
                        !path_is_valid (data->kfsb, key);
}

static gboolean
g_keyfile_settings_backend_write_tree (GSettingsBackend *backend,
                                       GTree            *tree,
                                       gpointer          origin_tag)
{
  WriteManyData data = { G_KEYFILE_SETTINGS_BACKEND (backend), 0 };
  gboolean success;
  GError *error = NULL;

  if (!data.kfsb->writable)
    return FALSE;

  g_tree_foreach (tree, g_keyfile_settings_backend_check_one, &data);

  if (data.failed)
    return FALSE;

  g_tree_foreach (tree, g_keyfile_settings_backend_write_one, &data);
  success = g_keyfile_settings_backend_keyfile_write (data.kfsb, &error);
  if (error)
    {
      g_warning ("Failed to write keyfile to %s: %s", g_file_peek_path (data.kfsb->file), error->message);
      g_error_free (error);
    }

  g_settings_backend_changed_tree (backend, tree, origin_tag);

  return success;
}

static gboolean
g_keyfile_settings_backend_write (GSettingsBackend *backend,
                                  const gchar      *key,
                                  GVariant         *value,
                                  gpointer          origin_tag)
{
  GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (backend);
  gboolean success;
  GError *error = NULL;

  if (!kfsb->writable)
    return FALSE;

  success = set_to_keyfile (kfsb, key, value);

  if (success)
    {
      g_settings_backend_changed (backend, key, origin_tag);
      success = g_keyfile_settings_backend_keyfile_write (kfsb, &error);
      if (error)
        {
          g_warning ("Failed to write keyfile to %s: %s", g_file_peek_path (kfsb->file), error->message);
          g_error_free (error);
        }
    }

  return success;
}

static void
g_keyfile_settings_backend_reset (GSettingsBackend *backend,
                                  const gchar      *key,
                                  gpointer          origin_tag)
{
  GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (backend);
  GError *error = NULL;

  if (set_to_keyfile (kfsb, key, NULL))
    {
      g_keyfile_settings_backend_keyfile_write (kfsb, &error);
      if (error)
        {
          g_warning ("Failed to write keyfile to %s: %s", g_file_peek_path (kfsb->file), error->message);
          g_error_free (error);
        }
    }

  g_settings_backend_changed (backend, key, origin_tag);
}

static gboolean
g_keyfile_settings_backend_get_writable (GSettingsBackend *backend,
                                         const gchar      *name)
{
  GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (backend);

  return kfsb->writable &&
         !g_hash_table_contains (kfsb->system_locks, name) &&
         path_is_valid (kfsb, name);
}

static GPermission *
g_keyfile_settings_backend_get_permission (GSettingsBackend *backend,
                                           const gchar      *path)
{
  GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (backend);

  return g_object_ref (kfsb->permission);
}

static void
keyfile_to_tree (GKeyfileSettingsBackend *kfsb,
                 GTree                   *tree,
                 GKeyFile                *keyfile,
                 gboolean                 dup_check)
{
  gchar **groups;
  gint i;

  groups = g_key_file_get_groups (keyfile, NULL);
  for (i = 0; groups[i]; i++)
    {
      gboolean is_root_group;
      gchar **keys;
      gint j;

      is_root_group = g_strcmp0 (kfsb->root_group, groups[i]) == 0;

      /* reject group names that will form invalid key names */
      if (!is_root_group &&
          (g_str_has_prefix (groups[i], "/") ||
           g_str_has_suffix (groups[i], "/") || strstr (groups[i], "//")))
        continue;

      keys = g_key_file_get_keys (keyfile, groups[i], NULL, NULL);
      g_assert (keys != NULL);

      for (j = 0; keys[j]; j++)
        {
          gchar *path, *value;

          /* reject key names with slashes in them */
          if (strchr (keys[j], '/'))
            continue;

          if (is_root_group)
            path = g_strdup_printf ("%s%s", kfsb->prefix, keys[j]);
          else
            path = g_strdup_printf ("%s%s/%s", kfsb->prefix, groups[i], keys[j]);

          value = g_key_file_get_value (keyfile, groups[i], keys[j], NULL);

          if (dup_check && g_strcmp0 (g_tree_lookup (tree, path), value) == 0)
            {
              g_tree_remove (tree, path);
              g_free (value);
              g_free (path);
            }
          else
            g_tree_insert (tree, path, value);
        }

      g_strfreev (keys);
    }
  g_strfreev (groups);
}

static void
g_keyfile_settings_backend_keyfile_reload (GKeyfileSettingsBackend *kfsb)
{
  guint8 digest[32];
  gchar *contents;
  gsize length;

  contents = NULL;
  length = 0;

  g_file_load_contents (kfsb->file, NULL, &contents, &length, NULL, NULL);
  compute_checksum (digest, contents, length);

  if (memcmp (kfsb->digest, digest, sizeof digest) != 0)
    {
      GKeyFile *keyfiles[2];
      GTree *tree;

      tree = g_tree_new_full ((GCompareDataFunc) strcmp, NULL,
                              g_free, g_free);

      keyfiles[0] = kfsb->keyfile;
      keyfiles[1] = g_key_file_new ();

      if (length > 0)
        g_key_file_load_from_data (keyfiles[1], contents, length,
                                   G_KEY_FILE_KEEP_COMMENTS |
                                   G_KEY_FILE_KEEP_TRANSLATIONS, NULL);

      keyfile_to_tree (kfsb, tree, keyfiles[0], FALSE);
      keyfile_to_tree (kfsb, tree, keyfiles[1], TRUE);
      g_key_file_free (keyfiles[0]);
      kfsb->keyfile = keyfiles[1];

      if (g_tree_nnodes (tree) > 0)
        g_settings_backend_changed_tree (&kfsb->parent_instance, tree, NULL);

      g_tree_unref (tree);

      memcpy (kfsb->digest, digest, sizeof digest);
    }

  g_free (contents);
}

static void
g_keyfile_settings_backend_keyfile_writable (GKeyfileSettingsBackend *kfsb)
{
  GFileInfo *fileinfo;
  gboolean writable;

  fileinfo = g_file_query_info (kfsb->dir, "access::*", 0, NULL, NULL);

  if (fileinfo)
    {
      writable =
        g_file_info_get_attribute_boolean (fileinfo, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE) &&
        g_file_info_get_attribute_boolean (fileinfo, G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE);
      g_object_unref (fileinfo);
    }
  else
    writable = FALSE;

  if (writable != kfsb->writable)
    {
      kfsb->writable = writable;
      g_settings_backend_path_writable_changed (&kfsb->parent_instance, "/");
    }
}

static void
g_keyfile_settings_backend_finalize (GObject *object)
{
  GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (object);

  g_key_file_free (kfsb->keyfile);
  g_object_unref (kfsb->permission);
  g_key_file_unref (kfsb->system_keyfile);
  g_hash_table_unref (kfsb->system_locks);
  g_free (kfsb->defaults_dir);

  if (kfsb->file_monitor)
    {
      g_file_monitor_cancel (kfsb->file_monitor);
      g_object_unref (kfsb->file_monitor);
    }
  g_object_unref (kfsb->file);

  if (kfsb->dir_monitor)
    {
      g_file_monitor_cancel (kfsb->dir_monitor);
      g_object_unref (kfsb->dir_monitor);
    }
  g_object_unref (kfsb->dir);

  g_free (kfsb->root_group);
  g_free (kfsb->prefix);

  G_OBJECT_CLASS (g_keyfile_settings_backend_parent_class)->finalize (object);
}

static void
g_keyfile_settings_backend_init (GKeyfileSettingsBackend *kfsb)
{
}

static void
file_changed (GFileMonitor      *monitor,
              GFile             *file,
              GFile             *other_file,
              GFileMonitorEvent  event_type,
              gpointer           user_data)
{
  GKeyfileSettingsBackend *kfsb = user_data;

  /* Ignore file deletions, let the GKeyFile content remain in tact. */
  if (event_type != G_FILE_MONITOR_EVENT_DELETED)
    g_keyfile_settings_backend_keyfile_reload (kfsb);
}

static void
dir_changed (GFileMonitor       *monitor,
              GFile             *file,
              GFile             *other_file,
              GFileMonitorEvent  event_type,
              gpointer           user_data)
{
  GKeyfileSettingsBackend *kfsb = user_data;

  g_keyfile_settings_backend_keyfile_writable (kfsb);
}

static void
load_system_settings (GKeyfileSettingsBackend *kfsb)
{
  GError *error = NULL;
  const char *dir = "/etc/glib-2.0/settings";
  char *path;
  char *contents;

  kfsb->system_keyfile = g_key_file_new ();
  kfsb->system_locks = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);

  if (kfsb->defaults_dir)
    dir = kfsb->defaults_dir;

  path = g_build_filename (dir, "defaults", NULL);

  /* The defaults are in the same keyfile format that we use for the settings.
   * It can be produced from a dconf database using: dconf dump
   */
  if (!g_key_file_load_from_file (kfsb->system_keyfile, path, G_KEY_FILE_NONE, &error))
    {
      if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT))
        g_warning ("Failed to read %s: %s", path, error->message);
      g_clear_error (&error);
    }
  else
    g_debug ("Loading default settings from %s", path);

  g_free (path);

  path = g_build_filename (dir, "locks", NULL);

  /* The locks file is a text file containing a list paths to lock, one per line.
   * It can be produced from a dconf database using: dconf list-locks
   */
  if (!g_file_get_contents (path, &contents, NULL, &error))
    {
      if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT))
        g_warning ("Failed to read %s: %s", path, error->message);
      g_clear_error (&error);
    }
  else
    {
      char **lines;
      gsize i;

      g_debug ("Loading locks from %s", path);

      lines = g_strsplit (contents, "\n", 0);
      for (i = 0; lines[i]; i++)
        {
          char *line = lines[i];
          if (line[0] == '#' || line[0] == '\0')
            {
              g_free (line);
              continue;
            }

          g_debug ("Locking key %s", line);
          g_hash_table_add (kfsb->system_locks, g_steal_pointer (&line));
        }

      g_free (lines);
    }
  g_free (contents);

  g_free (path);
}

static void
g_keyfile_settings_backend_constructed (GObject *object)
{
  GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (object);
  GError *error = NULL;
  const char *path;

  if (kfsb->file == NULL)
    {
      char *filename = g_build_filename (g_get_user_config_dir (),
                                         "glib-2.0", "settings", "keyfile",
                                         NULL);
      kfsb->file = g_file_new_for_path (filename);
      g_free (filename);
    }

  if (kfsb->prefix == NULL)
    {
      kfsb->prefix = g_strdup ("/");
      kfsb->prefix_len = 1;
    }
  
  kfsb->keyfile = g_key_file_new ();
  kfsb->permission = g_simple_permission_new (TRUE);

  kfsb->dir = g_file_get_parent (kfsb->file);
  path = g_file_peek_path (kfsb->dir);
  if (g_mkdir_with_parents (path, 0700) == -1)
    g_warning ("Failed to create %s: %s", path, g_strerror (errno));

  kfsb->file_monitor = g_file_monitor (kfsb->file, G_FILE_MONITOR_NONE, NULL, &error);
  if (!kfsb->file_monitor)
    {
      g_warning ("Failed to create file monitor for %s: %s", g_file_peek_path (kfsb->file), error->message);
      g_clear_error (&error);
    }
  else
    {
      g_signal_connect (kfsb->file_monitor, "changed",
                        G_CALLBACK (file_changed), kfsb);
    }

  kfsb->dir_monitor = g_file_monitor (kfsb->dir, G_FILE_MONITOR_NONE, NULL, &error);
  if (!kfsb->dir_monitor)
    {
      g_warning ("Failed to create file monitor for %s: %s", g_file_peek_path (kfsb->file), error->message);
      g_clear_error (&error);
    }
  else
    {
      g_signal_connect (kfsb->dir_monitor, "changed",
                        G_CALLBACK (dir_changed), kfsb);
    }

  compute_checksum (kfsb->digest, NULL, 0);

  g_keyfile_settings_backend_keyfile_writable (kfsb);
  g_keyfile_settings_backend_keyfile_reload (kfsb);

  load_system_settings (kfsb);
}

static void
g_keyfile_settings_backend_set_property (GObject      *object,
                                         guint         prop_id,
                                         const GValue *value,
                                         GParamSpec   *pspec)
{
  GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (object);

  switch ((GKeyfileSettingsBackendProperty)prop_id)
    {
    case PROP_FILENAME:
      /* Construct only. */
      g_assert (kfsb->file == NULL);
      if (g_value_get_string (value))
        kfsb->file = g_file_new_for_path (g_value_get_string (value));
      break;

    case PROP_ROOT_PATH:
      /* Construct only. */
      g_assert (kfsb->prefix == NULL);
      kfsb->prefix = g_value_dup_string (value);
      if (kfsb->prefix)
        kfsb->prefix_len = strlen (kfsb->prefix);
      break;

    case PROP_ROOT_GROUP:
      /* Construct only. */
      g_assert (kfsb->root_group == NULL);
      kfsb->root_group = g_value_dup_string (value);
      if (kfsb->root_group)
        kfsb->root_group_len = strlen (kfsb->root_group);
      break;

    case PROP_DEFAULTS_DIR:
      /* Construct only. */
      g_assert (kfsb->defaults_dir == NULL);
      kfsb->defaults_dir = g_value_dup_string (value);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

static void
g_keyfile_settings_backend_get_property (GObject    *object,
                                         guint       prop_id,
                                         GValue     *value,
                                         GParamSpec *pspec)
{
  GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (object);

  switch ((GKeyfileSettingsBackendProperty)prop_id)
    {
    case PROP_FILENAME:
      g_value_set_string (value, g_file_peek_path (kfsb->file));
      break;

    case PROP_ROOT_PATH:
      g_value_set_string (value, kfsb->prefix);
      break;

    case PROP_ROOT_GROUP:
      g_value_set_string (value, kfsb->root_group);
      break;

    case PROP_DEFAULTS_DIR:
      g_value_set_string (value, kfsb->defaults_dir);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

static void
g_keyfile_settings_backend_class_init (GKeyfileSettingsBackendClass *class)
{
  GObjectClass *object_class = G_OBJECT_CLASS (class);

  object_class->finalize = g_keyfile_settings_backend_finalize;
  object_class->constructed = g_keyfile_settings_backend_constructed;
  object_class->get_property = g_keyfile_settings_backend_get_property;
  object_class->set_property = g_keyfile_settings_backend_set_property;

  class->read = g_keyfile_settings_backend_read;
  class->write = g_keyfile_settings_backend_write;
  class->write_tree = g_keyfile_settings_backend_write_tree;
  class->reset = g_keyfile_settings_backend_reset;
  class->get_writable = g_keyfile_settings_backend_get_writable;
  class->get_permission = g_keyfile_settings_backend_get_permission;
  /* No need to implement subscribed/unsubscribe: the only point would be to
   * stop monitoring the file when there's no GSettings anymore, which is no
   * big win.
   */

  /**
   * GKeyfileSettingsBackend:filename:
   *
   * The location where the settings are stored on disk.
   *
   * Defaults to `$XDG_CONFIG_HOME/glib-2.0/settings/keyfile`.
   */
  g_object_class_install_property (object_class,
                                   PROP_FILENAME,
                                   g_param_spec_string ("filename",
                                                        P_("Filename"),
                                                        P_("The filename"),
                                                        NULL,
                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
                                                        G_PARAM_STATIC_STRINGS));

  /**
   * GKeyfileSettingsBackend:root-path:
   *
   * All settings read to or written from the backend must fall under the
   * path given in @root_path (which must start and end with a slash and
   * not contain two consecutive slashes).  @root_path may be "/".
   * 
   * Defaults to "/".
   */
  g_object_class_install_property (object_class,
                                   PROP_ROOT_PATH,
                                   g_param_spec_string ("root-path",
                                                        P_("Root path"),
                                                        P_("The root path"),
                                                        NULL,
                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
                                                        G_PARAM_STATIC_STRINGS));

  /**
   * GKeyfileSettingsBackend:root-group:
   *
   * If @root_group is non-%NULL then it specifies the name of the keyfile
   * group used for keys that are written directly below the root path.
   *
   * Defaults to NULL.
   */
  g_object_class_install_property (object_class,
                                   PROP_ROOT_GROUP,
                                   g_param_spec_string ("root-group",
                                                        P_("Root group"),
                                                        P_("The root group"),
                                                        NULL,
                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
                                                        G_PARAM_STATIC_STRINGS));

  /**
   * GKeyfileSettingsBackend:default-dir:
   *
   * The directory where the system defaults and locks are located.
   *
   * Defaults to `/etc/glib-2.0/settings`.
   */
  g_object_class_install_property (object_class,
                                   PROP_DEFAULTS_DIR,
                                   g_param_spec_string ("defaults-dir",
                                                        P_("Default dir"),
                                                        P_("Defaults dir"),
                                                        NULL,
                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
                                                        G_PARAM_STATIC_STRINGS));
}

/**
 * g_keyfile_settings_backend_new:
 * @filename: the filename of the keyfile
 * @root_path: the path under which all settings keys appear
 * @root_group: (nullable): the group name corresponding to
 *              @root_path, or %NULL
 *
 * Creates a keyfile-backed #GSettingsBackend.
 *
 * The filename of the keyfile to use is given by @filename.
 *
 * All settings read to or written from the backend must fall under the
 * path given in @root_path (which must start and end with a slash and
 * not contain two consecutive slashes).  @root_path may be "/".
 *
 * If @root_group is non-%NULL then it specifies the name of the keyfile
 * group used for keys that are written directly below @root_path.  For
 * example, if @root_path is "/apps/example/" and @root_group is
 * "toplevel", then settings the key "/apps/example/enabled" to a value
 * of %TRUE will cause the following to appear in the keyfile:
 *
 * |[
 *   [toplevel]
 *   enabled=true
 * ]|
 *
 * If @root_group is %NULL then it is not permitted to store keys
 * directly below the @root_path.
 *
 * For keys not stored directly below @root_path (ie: in a sub-path),
 * the name of the subpath (with the final slash stripped) is used as
 * the name of the keyfile group.  To continue the example, if
 * "/apps/example/profiles/default/font-size" were set to
 * 12 then the following would appear in the keyfile:
 *
 * |[
 *   [profiles/default]
 *   font-size=12
 * ]|
 *
 * The backend will refuse writes (and return writability as being
 * %FALSE) for keys outside of @root_path and, in the event that
 * @root_group is %NULL, also for keys directly under @root_path.
 * Writes will also be refused if the backend detects that it has the
 * inability to rewrite the keyfile (ie: the containing directory is not
 * writable).
 *
 * There is no checking done for your key namespace clashing with the
 * syntax of the key file format.  For example, if you have '[' or ']'
 * characters in your path names or '=' in your key names you may be in
 * trouble.
 *
 * The backend reads default values from a keyfile called `defaults` in
 * the directory specified by the #GKeyfileSettingsBackend:defaults-dir property,
 * and a list of locked keys from a text file with the name `locks` in
 * the same location.
 *
 * Returns: (transfer full): a keyfile-backed #GSettingsBackend
 **/
GSettingsBackend *
g_keyfile_settings_backend_new (const gchar *filename,
                                const gchar *root_path,
                                const gchar *root_group)
{
  g_return_val_if_fail (filename != NULL, NULL);
  g_return_val_if_fail (root_path != NULL, NULL);
  g_return_val_if_fail (g_str_has_prefix (root_path, "/"), NULL);
  g_return_val_if_fail (g_str_has_suffix (root_path, "/"), NULL);
  g_return_val_if_fail (strstr (root_path, "//") == NULL, NULL);

  return G_SETTINGS_BACKEND (g_object_new (G_TYPE_KEYFILE_SETTINGS_BACKEND,
                                           "filename", filename,
                                           "root-path", root_path,
                                           "root-group", root_group,
                                           NULL));
}
