/*
 * Copyright © 2010 Codethink Limited
 * Copyright © 2011 Canonical Limited
 *
 * 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 of the licence, 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/>.
 */

#include "config.h"

#include "gsettingsschema-internal.h"
#include "gsettings.h"

#include "gvdb/gvdb-reader.h"
#include "strinfo.c"

#include <glibintl.h>
#include <locale.h>
#include <string.h>

/**
 * SECTION:gsettingsschema
 * @short_description: Introspecting and controlling the loading
 *     of GSettings schemas
 * @include: gio/gio.h
 *
 * The #GSettingsSchemaSource and #GSettingsSchema APIs provide a
 * mechanism for advanced control over the loading of schemas and a
 * mechanism for introspecting their content.
 *
 * Plugin loading systems that wish to provide plugins a way to access
 * settings face the problem of how to make the schemas for these
 * settings visible to GSettings.  Typically, a plugin will want to ship
 * the schema along with itself and it won't be installed into the
 * standard system directories for schemas.
 *
 * #GSettingsSchemaSource provides a mechanism for dealing with this by
 * allowing the creation of a new 'schema source' from which schemas can
 * be acquired.  This schema source can then become part of the metadata
 * associated with the plugin and queried whenever the plugin requires
 * access to some settings.
 *
 * Consider the following example:
 *
 * |[<!-- language="C" -->
 * typedef struct
 * {
 *    ...
 *    GSettingsSchemaSource *schema_source;
 *    ...
 * } Plugin;
 *
 * Plugin *
 * initialise_plugin (const gchar *dir)
 * {
 *   Plugin *plugin;
 *
 *   ...
 *
 *   plugin->schema_source =
 *     g_settings_new_schema_source_from_directory (dir,
 *       g_settings_schema_source_get_default (), FALSE, NULL);
 *
 *   ...
 *
 *   return plugin;
 * }
 *
 * ...
 *
 * GSettings *
 * plugin_get_settings (Plugin      *plugin,
 *                      const gchar *schema_id)
 * {
 *   GSettingsSchema *schema;
 *
 *   if (schema_id == NULL)
 *     schema_id = plugin->identifier;
 *
 *   schema = g_settings_schema_source_lookup (plugin->schema_source,
 *                                             schema_id, FALSE);
 *
 *   if (schema == NULL)
 *     {
 *       ... disable the plugin or abort, etc ...
 *     }
 *
 *   return g_settings_new_full (schema, NULL, NULL);
 * }
 * ]|
 *
 * The code above shows how hooks should be added to the code that
 * initialises (or enables) the plugin to create the schema source and
 * how an API can be added to the plugin system to provide a convenient
 * way for the plugin to access its settings, using the schemas that it
 * ships.
 *
 * From the standpoint of the plugin, it would need to ensure that it
 * ships a gschemas.compiled file as part of itself, and then simply do
 * the following:
 *
 * |[<!-- language="C" -->
 * {
 *   GSettings *settings;
 *   gint some_value;
 *
 *   settings = plugin_get_settings (self, NULL);
 *   some_value = g_settings_get_int (settings, "some-value");
 *   ...
 * }
 * ]|
 *
 * It's also possible that the plugin system expects the schema source
 * files (ie: .gschema.xml files) instead of a gschemas.compiled file.
 * In that case, the plugin loading system must compile the schemas for
 * itself before attempting to create the settings source.
 *
 * Since: 2.32
 **/

/**
 * GSettingsSchemaKey:
 *
 * #GSettingsSchemaKey is an opaque data structure and can only be accessed
 * using the following functions.
 **/

/**
 * GSettingsSchema:
 *
 * This is an opaque structure type.  You may not access it directly.
 *
 * Since: 2.32
 **/
struct _GSettingsSchema
{
  GSettingsSchemaSource *source;
  const gchar *gettext_domain;
  const gchar *path;
  GQuark *items;
  gint n_items;
  GvdbTable *table;
  gchar *id;

  GSettingsSchema *extends;

  gint ref_count;
};

/**
 * G_TYPE_SETTINGS_SCHEMA_SOURCE:
 *
 * A boxed #GType corresponding to #GSettingsSchemaSource.
 *
 * Since: 2.32
 **/
G_DEFINE_BOXED_TYPE (GSettingsSchemaSource, g_settings_schema_source, g_settings_schema_source_ref, g_settings_schema_source_unref)

/**
 * G_TYPE_SETTINGS_SCHEMA:
 *
 * A boxed #GType corresponding to #GSettingsSchema.
 *
 * Since: 2.32
 **/
G_DEFINE_BOXED_TYPE (GSettingsSchema, g_settings_schema, g_settings_schema_ref, g_settings_schema_unref)

/**
 * GSettingsSchemaSource:
 *
 * This is an opaque structure type.  You may not access it directly.
 *
 * Since: 2.32
 **/
struct _GSettingsSchemaSource
{
  GSettingsSchemaSource *parent;
  gchar *directory;
  GvdbTable *table;
  GHashTable **text_tables;

  gint ref_count;
};

static GSettingsSchemaSource *schema_sources;

/**
 * g_settings_schema_source_ref:
 * @source: a #GSettingsSchemaSource
 *
 * Increase the reference count of @source, returning a new reference.
 *
 * Returns: a new reference to @source
 *
 * Since: 2.32
 **/
GSettingsSchemaSource *
g_settings_schema_source_ref (GSettingsSchemaSource *source)
{
  g_atomic_int_inc (&source->ref_count);

  return source;
}

/**
 * g_settings_schema_source_unref:
 * @source: a #GSettingsSchemaSource
 *
 * Decrease the reference count of @source, possibly freeing it.
 *
 * Since: 2.32
 **/
void
g_settings_schema_source_unref (GSettingsSchemaSource *source)
{
  if (g_atomic_int_dec_and_test (&source->ref_count))
    {
      if (source == schema_sources)
        g_error ("g_settings_schema_source_unref() called too many times on the default schema source");

      if (source->parent)
        g_settings_schema_source_unref (source->parent);
      gvdb_table_unref (source->table);
      g_free (source->directory);

      if (source->text_tables)
        {
          g_hash_table_unref (source->text_tables[0]);
          g_hash_table_unref (source->text_tables[1]);
          g_free (source->text_tables);
        }

      g_slice_free (GSettingsSchemaSource, source);
    }
}

/**
 * g_settings_schema_source_new_from_directory:
 * @directory: (type filename): the filename of a directory
 * @parent: (allow-none): a #GSettingsSchemaSource, or %NULL
 * @trusted: %TRUE, if the directory is trusted
 * @error: a pointer to a #GError pointer set to %NULL, or %NULL
 *
 * Attempts to create a new schema source corresponding to the contents
 * of the given directory.
 *
 * This function is not required for normal uses of #GSettings but it
 * may be useful to authors of plugin management systems.
 *
 * The directory should contain a file called `gschemas.compiled` as
 * produced by the [glib-compile-schemas][glib-compile-schemas] tool.
 *
 * If @trusted is %TRUE then `gschemas.compiled` is trusted not to be
 * corrupted. This assumption has a performance advantage, but can result
 * in crashes or inconsistent behaviour in the case of a corrupted file.
 * Generally, you should set @trusted to %TRUE for files installed by the
 * system and to %FALSE for files in the home directory.
 *
 * If @parent is non-%NULL then there are two effects.
 *
 * First, if g_settings_schema_source_lookup() is called with the
 * @recursive flag set to %TRUE and the schema can not be found in the
 * source, the lookup will recurse to the parent.
 *
 * Second, any references to other schemas specified within this
 * source (ie: `child` or `extends`) references may be resolved
 * from the @parent.
 *
 * For this second reason, except in very unusual situations, the
 * @parent should probably be given as the default schema source, as
 * returned by g_settings_schema_source_get_default().
 *
 * Since: 2.32
 **/
GSettingsSchemaSource *
g_settings_schema_source_new_from_directory (const gchar            *directory,
                                             GSettingsSchemaSource  *parent,
                                             gboolean                trusted,
                                             GError                **error)
{
  GSettingsSchemaSource *source;
  GvdbTable *table;
  gchar *filename;

  filename = g_build_filename (directory, "gschemas.compiled", NULL);
  table = gvdb_table_new (filename, trusted, error);
  g_free (filename);

  if (table == NULL)
    return NULL;

  source = g_slice_new (GSettingsSchemaSource);
  source->directory = g_strdup (directory);
  source->parent = parent ? g_settings_schema_source_ref (parent) : NULL;
  source->text_tables = NULL;
  source->table = table;
  source->ref_count = 1;

  return source;
}

static void
try_prepend_dir (const gchar *directory)
{
  GSettingsSchemaSource *source;

  source = g_settings_schema_source_new_from_directory (directory, schema_sources, TRUE, NULL);

  /* If we successfully created it then prepend it to the global list */
  if (source != NULL)
    schema_sources = source;
}

static void
initialise_schema_sources (void)
{
  static gsize initialised;

  /* need a separate variable because 'schema_sources' may legitimately
   * be null if we have zero valid schema sources
   */
  if G_UNLIKELY (g_once_init_enter (&initialised))
    {
      const gchar * const *dirs;
      const gchar *path;
      gint i;

      /* iterate in reverse: count up, then count down */
      dirs = g_get_system_data_dirs ();
      for (i = 0; dirs[i]; i++);

      while (i--)
        {
          gchar *dirname;

          dirname = g_build_filename (dirs[i], "glib-2.0", "schemas", NULL);
          try_prepend_dir (dirname);
          g_free (dirname);
        }

      if ((path = g_getenv ("GSETTINGS_SCHEMA_DIR")) != NULL)
        try_prepend_dir (path);

      g_once_init_leave (&initialised, TRUE);
    }
}

/**
 * g_settings_schema_source_get_default:
 *
 * Gets the default system schema source.
 *
 * This function is not required for normal uses of #GSettings but it
 * may be useful to authors of plugin management systems or to those who
 * want to introspect the content of schemas.
 *
 * If no schemas are installed, %NULL will be returned.
 *
 * The returned source may actually consist of multiple schema sources
 * from different directories, depending on which directories were given
 * in `XDG_DATA_DIRS` and `GSETTINGS_SCHEMA_DIR`. For this reason, all
 * lookups performed against the default source should probably be done
 * recursively.
 *
 * Returns: (transfer none): the default schema source
 *
 * Since: 2.32
 **/
 GSettingsSchemaSource *
g_settings_schema_source_get_default (void)
{
  initialise_schema_sources ();

  return schema_sources;
}

/**
 * g_settings_schema_source_lookup:
 * @source: a #GSettingsSchemaSource
 * @schema_id: a schema ID
 * @recursive: %TRUE if the lookup should be recursive
 *
 * Looks up a schema with the identifier @schema_id in @source.
 *
 * This function is not required for normal uses of #GSettings but it
 * may be useful to authors of plugin management systems or to those who
 * want to introspect the content of schemas.
 *
 * If the schema isn't found directly in @source and @recursive is %TRUE
 * then the parent sources will also be checked.
 *
 * If the schema isn't found, %NULL is returned.
 *
 * Returns: (nullable) (transfer full): a new #GSettingsSchema
 *
 * Since: 2.32
 **/
GSettingsSchema *
g_settings_schema_source_lookup (GSettingsSchemaSource *source,
                                 const gchar           *schema_id,
                                 gboolean               recursive)
{
  GSettingsSchema *schema;
  GvdbTable *table;
  const gchar *extends;

  g_return_val_if_fail (source != NULL, NULL);
  g_return_val_if_fail (schema_id != NULL, NULL);

  table = gvdb_table_get_table (source->table, schema_id);

  if (table == NULL && recursive)
    for (source = source->parent; source; source = source->parent)
      if ((table = gvdb_table_get_table (source->table, schema_id)))
        break;

  if (table == NULL)
    return NULL;

  schema = g_slice_new0 (GSettingsSchema);
  schema->source = g_settings_schema_source_ref (source);
  schema->ref_count = 1;
  schema->id = g_strdup (schema_id);
  schema->table = table;
  schema->path = g_settings_schema_get_string (schema, ".path");
  schema->gettext_domain = g_settings_schema_get_string (schema, ".gettext-domain");

  if (schema->gettext_domain)
    bind_textdomain_codeset (schema->gettext_domain, "UTF-8");

  extends = g_settings_schema_get_string (schema, ".extends");
  if (extends)
    {
      schema->extends = g_settings_schema_source_lookup (source, extends, TRUE);
      if (schema->extends == NULL)
        g_warning ("Schema '%s' extends schema '%s' but we could not find it", schema_id, extends);
    }

  return schema;
}

typedef struct
{
  GHashTable *summaries;
  GHashTable *descriptions;
  GSList     *gettext_domain;
  GSList     *schema_id;
  GSList     *key_name;
  GString    *string;
} TextTableParseInfo;

static const gchar *
get_attribute_value (GSList *list)
{
  GSList *node;

  for (node = list; node; node = node->next)
    if (node->data)
      return node->data;

  return NULL;
}

static void
pop_attribute_value (GSList **list)
{
  gchar *top;

  top = (*list)->data;
  *list = g_slist_remove (*list, top);

  g_free (top);
}

static void
push_attribute_value (GSList      **list,
                      const gchar  *value)
{
  *list = g_slist_prepend (*list, g_strdup (value));
}

static void
start_element (GMarkupParseContext  *context,
               const gchar          *element_name,
               const gchar         **attribute_names,
               const gchar         **attribute_values,
               gpointer              user_data,
               GError              **error)
{
  TextTableParseInfo *info = user_data;
  const gchar *gettext_domain = NULL;
  const gchar *schema_id = NULL;
  const gchar *key_name = NULL;
  gint i;

  for (i = 0; attribute_names[i]; i++)
    {
      if (g_str_equal (attribute_names[i], "gettext-domain"))
        gettext_domain = attribute_values[i];
      else if (g_str_equal (attribute_names[i], "id"))
        schema_id = attribute_values[i];
      else if (g_str_equal (attribute_names[i], "name"))
        key_name = attribute_values[i];
    }

  push_attribute_value (&info->gettext_domain, gettext_domain);
  push_attribute_value (&info->schema_id, schema_id);
  push_attribute_value (&info->key_name, key_name);

  if (info->string)
    {
      g_string_free (info->string, TRUE);
      info->string = NULL;
    }

  if (g_str_equal (element_name, "summary") || g_str_equal (element_name, "description"))
    info->string = g_string_new (NULL);
}

static gchar *
normalise_whitespace (const gchar *orig)
{
  /* We normalise by the same rules as in intltool:
   *
   *   sub cleanup {
   *       s/^\s+//;
   *       s/\s+$//;
   *       s/\s+/ /g;
   *       return $_;
   *   }
   *
   *   $message = join "\n\n", map &cleanup, split/\n\s*\n+/, $message;
   *
   * Where \s is an ascii space character.
   *
   * We aim for ease of implementation over efficiency -- this code is
   * not run in normal applications.
   */
  static GRegex *cleanup[3];
  static GRegex *splitter;
  gchar **lines;
  gchar *result;
  gint i;

  if (g_once_init_enter (&splitter))
    {
      GRegex *s;

      cleanup[0] = g_regex_new ("^\\s+", 0, 0, 0);
      cleanup[1] = g_regex_new ("\\s+$", 0, 0, 0);
      cleanup[2] = g_regex_new ("\\s+", 0, 0, 0);
      s = g_regex_new ("\\n\\s*\\n+", 0, 0, 0);

      g_once_init_leave (&splitter, s);
    }

  lines = g_regex_split (splitter, orig, 0);
  for (i = 0; lines[i]; i++)
    {
      gchar *a, *b, *c;

      a = g_regex_replace_literal (cleanup[0], lines[i], -1, 0, "", 0, 0);
      b = g_regex_replace_literal (cleanup[1], a, -1, 0, "", 0, 0);
      c = g_regex_replace_literal (cleanup[2], b, -1, 0, " ", 0, 0);
      g_free (lines[i]);
      g_free (a);
      g_free (b);
      lines[i] = c;
    }

  result = g_strjoinv ("\n\n", lines);
  g_strfreev (lines);

  return result;
}

static void
end_element (GMarkupParseContext *context,
             const gchar *element_name,
             gpointer user_data,
             GError **error)
{
  TextTableParseInfo *info = user_data;

  pop_attribute_value (&info->gettext_domain);
  pop_attribute_value (&info->schema_id);
  pop_attribute_value (&info->key_name);

  if (info->string)
    {
      GHashTable *source_table = NULL;
      const gchar *gettext_domain;
      const gchar *schema_id;
      const gchar *key_name;

      gettext_domain = get_attribute_value (info->gettext_domain);
      schema_id = get_attribute_value (info->schema_id);
      key_name = get_attribute_value (info->key_name);

      if (g_str_equal (element_name, "summary"))
        source_table = info->summaries;
      else if (g_str_equal (element_name, "description"))
        source_table = info->descriptions;

      if (source_table && schema_id && key_name)
        {
          GHashTable *schema_table;
          gchar *normalised;

          schema_table = g_hash_table_lookup (source_table, schema_id);

          if (schema_table == NULL)
            {
              schema_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
              g_hash_table_insert (source_table, g_strdup (schema_id), schema_table);
            }

          normalised = normalise_whitespace (info->string->str);

          if (gettext_domain && normalised[0])
            {
              gchar *translated;

              translated = g_strdup (g_dgettext (gettext_domain, normalised));
              g_free (normalised);
              normalised = translated;
            }

          g_hash_table_insert (schema_table, g_strdup (key_name), normalised);
        }

      g_string_free (info->string, TRUE);
      info->string = NULL;
    }
}

static void
text (GMarkupParseContext  *context,
      const gchar          *text,
      gsize                 text_len,
      gpointer              user_data,
      GError              **error)
{
  TextTableParseInfo *info = user_data;

  if (info->string)
    g_string_append_len (info->string, text, text_len);
}

static void
parse_into_text_tables (const gchar *directory,
                        GHashTable  *summaries,
                        GHashTable  *descriptions)
{
  GMarkupParser parser = { start_element, end_element, text };
  TextTableParseInfo info = { summaries, descriptions };
  const gchar *basename;
  GDir *dir;

  dir = g_dir_open (directory, 0, NULL);
  while ((basename = g_dir_read_name (dir)))
    {
      gchar *filename;
      gchar *contents;
      gsize size;

      filename = g_build_filename (directory, basename, NULL);
      if (g_file_get_contents (filename, &contents, &size, NULL))
        {
          GMarkupParseContext *context;

          context = g_markup_parse_context_new (&parser, G_MARKUP_TREAT_CDATA_AS_TEXT, &info, NULL);
          /* Ignore errors here, this is best effort only. */
          if (g_markup_parse_context_parse (context, contents, size, NULL))
            (void) g_markup_parse_context_end_parse (context, NULL);
          g_markup_parse_context_free (context);

          /* Clean up dangling stuff in case there was an error. */
          g_slist_free_full (info.gettext_domain, g_free);
          g_slist_free_full (info.schema_id, g_free);
          g_slist_free_full (info.key_name, g_free);

          info.gettext_domain = NULL;
          info.schema_id = NULL;
          info.key_name = NULL;

          if (info.string)
            {
              g_string_free (info.string, TRUE);
              info.string = NULL;
            }

          g_free (contents);
        }

      g_free (filename);
    }
  
  g_dir_close (dir);
}

static GHashTable **
g_settings_schema_source_get_text_tables (GSettingsSchemaSource *source)
{
  if (g_once_init_enter (&source->text_tables))
    {
      GHashTable **text_tables;

      text_tables = g_new (GHashTable *, 2);
      text_tables[0] = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_hash_table_unref);
      text_tables[1] = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_hash_table_unref);

      if (source->directory)
        parse_into_text_tables (source->directory, text_tables[0], text_tables[1]);

      g_once_init_leave (&source->text_tables, text_tables);
    }

  return source->text_tables;
}

/**
 * g_settings_schema_source_list_schemas:
 * @source: a #GSettingsSchemaSource
 * @recursive: if we should recurse
 * @non_relocatable: (out) (transfer full) (array zero-terminated=1): the
 *   list of non-relocatable schemas
 * @relocatable: (out) (transfer full) (array zero-terminated=1): the list
 *   of relocatable schemas
 *
 * Lists the schemas in a given source.
 *
 * If @recursive is %TRUE then include parent sources.  If %FALSE then
 * only include the schemas from one source (ie: one directory).  You
 * probably want %TRUE.
 *
 * Non-relocatable schemas are those for which you can call
 * g_settings_new().  Relocatable schemas are those for which you must
 * use g_settings_new_with_path().
 *
 * Do not call this function from normal programs.  This is designed for
 * use by database editors, commandline tools, etc.
 *
 * Since: 2.40
 **/
void
g_settings_schema_source_list_schemas (GSettingsSchemaSource   *source,
                                       gboolean                 recursive,
                                       gchar                 ***non_relocatable,
                                       gchar                 ***relocatable)
{
  GHashTable *single, *reloc;
  GSettingsSchemaSource *s;

  /* We use hash tables to avoid duplicate listings for schemas that
   * appear in more than one file.
   */
  single = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
  reloc = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);

  for (s = source; s; s = s->parent)
    {
      gchar **list;
      gint i;

      list = gvdb_table_list (s->table, "");

      /* empty schema cache file? */
      if (list == NULL)
        continue;

      for (i = 0; list[i]; i++)
        {
          if (!g_hash_table_lookup (single, list[i]) &&
              !g_hash_table_lookup (reloc, list[i]))
            {
              GvdbTable *table;

              table = gvdb_table_get_table (s->table, list[i]);
              g_assert (table != NULL);

              if (gvdb_table_has_value (table, ".path"))
                g_hash_table_insert (single, g_strdup (list[i]), NULL);
              else
                g_hash_table_insert (reloc, g_strdup (list[i]), NULL);

              gvdb_table_unref (table);
            }
        }

      g_strfreev (list);

      /* Only the first source if recursive not requested */
      if (!recursive)
        break;
    }

  if (non_relocatable)
    {
      *non_relocatable = (gchar **) g_hash_table_get_keys_as_array (single, NULL);
      g_hash_table_steal_all (single);
    }

  if (relocatable)
    {
      *relocatable = (gchar **) g_hash_table_get_keys_as_array (reloc, NULL);
      g_hash_table_steal_all (reloc);
    }

  g_hash_table_unref (single);
  g_hash_table_unref (reloc);
}

static gchar **non_relocatable_schema_list;
static gchar **relocatable_schema_list;
static gsize schema_lists_initialised;

static void
ensure_schema_lists (void)
{
  if (g_once_init_enter (&schema_lists_initialised))
    {
      initialise_schema_sources ();

      g_settings_schema_source_list_schemas (schema_sources, TRUE,
                                             &non_relocatable_schema_list,
                                             &relocatable_schema_list);

      g_once_init_leave (&schema_lists_initialised, TRUE);
    }
}

/**
 * g_settings_list_schemas:
 *
 * <!-- -->
 *
 * Returns: (element-type utf8) (transfer none):  a list of #GSettings
 *   schemas that are available.  The list must not be modified or
 *   freed.
 *
 * Since: 2.26
 *
 * Deprecated: 2.40: Use g_settings_schema_source_list_schemas() instead.
 * If you used g_settings_list_schemas() to check for the presence of
 * a particular schema, use g_settings_schema_source_lookup() instead
 * of your whole loop.
 **/
const gchar * const *
g_settings_list_schemas (void)
{
  ensure_schema_lists ();

  return (const gchar **) non_relocatable_schema_list;
}

/**
 * g_settings_list_relocatable_schemas:
 *
 * <!-- -->
 *
 * Returns: (element-type utf8) (transfer none): a list of relocatable
 *   #GSettings schemas that are available.  The list must not be
 *   modified or freed.
 *
 * Since: 2.28
 *
 * Deprecated: 2.40: Use g_settings_schema_source_list_schemas() instead
 **/
const gchar * const *
g_settings_list_relocatable_schemas (void)
{
  ensure_schema_lists ();

  return (const gchar **) relocatable_schema_list;
}

/**
 * g_settings_schema_ref:
 * @schema: a #GSettingsSchema
 *
 * Increase the reference count of @schema, returning a new reference.
 *
 * Returns: a new reference to @schema
 *
 * Since: 2.32
 **/
GSettingsSchema *
g_settings_schema_ref (GSettingsSchema *schema)
{
  g_atomic_int_inc (&schema->ref_count);

  return schema;
}

/**
 * g_settings_schema_unref:
 * @schema: a #GSettingsSchema
 *
 * Decrease the reference count of @schema, possibly freeing it.
 *
 * Since: 2.32
 **/
void
g_settings_schema_unref (GSettingsSchema *schema)
{
  if (g_atomic_int_dec_and_test (&schema->ref_count))
    {
      if (schema->extends)
        g_settings_schema_unref (schema->extends);

      g_settings_schema_source_unref (schema->source);
      gvdb_table_unref (schema->table);
      g_free (schema->items);
      g_free (schema->id);

      g_slice_free (GSettingsSchema, schema);
    }
}

const gchar *
g_settings_schema_get_string (GSettingsSchema *schema,
                              const gchar     *key)
{
  const gchar *result = NULL;
  GVariant *value;

  if ((value = gvdb_table_get_raw_value (schema->table, key)))
    {
      result = g_variant_get_string (value, NULL);
      g_variant_unref (value);
    }

  return result;
}

GVariantIter *
g_settings_schema_get_value (GSettingsSchema *schema,
                             const gchar     *key)
{
  GSettingsSchema *s = schema;
  GVariantIter *iter;
  GVariant *value = NULL;

  g_return_val_if_fail (schema != NULL, NULL);

  for (s = schema; s; s = s->extends)
    if ((value = gvdb_table_get_raw_value (s->table, key)))
      break;

  if G_UNLIKELY (value == NULL || !g_variant_is_of_type (value, G_VARIANT_TYPE_TUPLE))
    g_error ("Settings schema '%s' does not contain a key named '%s'", schema->id, key);

  iter = g_variant_iter_new (value);
  g_variant_unref (value);

  return iter;
}

/**
 * g_settings_schema_get_path:
 * @schema: a #GSettingsSchema
 *
 * Gets the path associated with @schema, or %NULL.
 *
 * Schemas may be single-instance or relocatable.  Single-instance
 * schemas correspond to exactly one set of keys in the backend
 * database: those located at the path returned by this function.
 *
 * Relocatable schemas can be referenced by other schemas and can
 * threfore describe multiple sets of keys at different locations.  For
 * relocatable schemas, this function will return %NULL.
 *
 * Returns: (transfer none): the path of the schema, or %NULL
 *
 * Since: 2.32
 **/
const gchar *
g_settings_schema_get_path (GSettingsSchema *schema)
{
  return schema->path;
}

const gchar *
g_settings_schema_get_gettext_domain (GSettingsSchema *schema)
{
  return schema->gettext_domain;
}

/**
 * g_settings_schema_has_key:
 * @schema: a #GSettingsSchema
 * @name: the name of a key
 *
 * Checks if @schema has a key named @name.
 *
 * Returns: %TRUE if such a key exists
 *
 * Since: 2.40
 **/
gboolean
g_settings_schema_has_key (GSettingsSchema *schema,
                           const gchar     *key)
{
  return gvdb_table_has_value (schema->table, key);
}

/**
 * g_settings_schema_list_children:
 * @schema: a #GSettingsSchema
 *
 * Gets the list of children in @schema.
 *
 * You should free the return value with g_strfreev() when you are done
 * with it.
 *
 * Returns: (transfer full) (element-type utf8): a list of the children on @settings
 *
 * Since: 2.44
 */
gchar **
g_settings_schema_list_children (GSettingsSchema *schema)
{
  const GQuark *keys;
  gchar **strv;
  gint n_keys;
  gint i, j;

  g_return_val_if_fail (schema != NULL, NULL);

  keys = g_settings_schema_list (schema, &n_keys);
  strv = g_new (gchar *, n_keys + 1);
  for (i = j = 0; i < n_keys; i++)
    {
      const gchar *key = g_quark_to_string (keys[i]);

      if (g_str_has_suffix (key, "/"))
        {
          gint length = strlen (key);

          strv[j] = g_memdup (key, length);
          strv[j][length - 1] = '\0';
          j++;
        }
    }
  strv[j] = NULL;

  return strv;
}

/**
 * g_settings_schema_list_keys:
 * @schema: a #GSettingsSchema
 *
 * Introspects the list of keys on @schema.
 *
 * You should probably not be calling this function from "normal" code
 * (since you should already know what keys are in your schema).  This
 * function is intended for introspection reasons.
 *
 * Returns: (transfer full) (element-type utf8): a list of the keys on
 *   @schema
 *
 * Since: 2.46
 */
gchar **
g_settings_schema_list_keys (GSettingsSchema *schema)
{
  const GQuark *keys;
  gchar **strv;
  gint n_keys;
  gint i, j;

  g_return_val_if_fail (schema != NULL, NULL);

  keys = g_settings_schema_list (schema, &n_keys);
  strv = g_new (gchar *, n_keys + 1);
  for (i = j = 0; i < n_keys; i++)
    {
      const gchar *key = g_quark_to_string (keys[i]);

      if (!g_str_has_suffix (key, "/"))
        strv[j++] = g_strdup (key);
    }
  strv[j] = NULL;

  return strv;
}

const GQuark *
g_settings_schema_list (GSettingsSchema *schema,
                        gint            *n_items)
{
  if (schema->items == NULL)
    {
      GSettingsSchema *s;
      GHashTableIter iter;
      GHashTable *items;
      gpointer name;
      gint len;
      gint i;

      items = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);

      for (s = schema; s; s = s->extends)
        {
          gchar **list;

          list = gvdb_table_list (s->table, "");

          if (list)
            {
              for (i = 0; list[i]; i++)
                g_hash_table_add (items, list[i]); /* transfer ownership */

              g_free (list); /* free container only */
            }
        }

      /* Do a first pass to eliminate child items that do not map to
       * valid schemas (ie: ones that would crash us if we actually
       * tried to create them).
       */
      g_hash_table_iter_init (&iter, items);
      while (g_hash_table_iter_next (&iter, &name, NULL))
        if (g_str_has_suffix (name, "/"))
          {
            GSettingsSchemaSource *source;
            GVariant *child_schema;
            GvdbTable *child_table;

            child_schema = gvdb_table_get_raw_value (schema->table, name);
            if (!child_schema)
              continue;

            child_table = NULL;

            for (source = schema->source; source; source = source->parent)
              if ((child_table = gvdb_table_get_table (source->table, g_variant_get_string (child_schema, NULL))))
                break;

            g_variant_unref (child_schema);

            /* Schema is not found -> remove it from the list */
            if (child_table == NULL)
              {
                g_hash_table_iter_remove (&iter);
                continue;
              }

            /* Make sure the schema is relocatable or at the
             * expected path
             */
            if (gvdb_table_has_value (child_table, ".path"))
              {
                GVariant *path;
                gchar *expected;
                gboolean same;

                path = gvdb_table_get_raw_value (child_table, ".path");
                expected = g_strconcat (schema->path, name, NULL);
                same = g_str_equal (expected, g_variant_get_string (path, NULL));
                g_variant_unref (path);
                g_free (expected);

                /* Schema is non-relocatable and did not have the
                 * expected path -> remove it from the list
                 */
                if (!same)
                  g_hash_table_iter_remove (&iter);
              }

            gvdb_table_unref (child_table);
          }

      /* Now create the list */
      len = g_hash_table_size (items);
      schema->items = g_new (GQuark, len);
      i = 0;
      g_hash_table_iter_init (&iter, items);

      while (g_hash_table_iter_next (&iter, &name, NULL))
        schema->items[i++] = g_quark_from_string (name);
      schema->n_items = i;
      g_assert (i == len);

      g_hash_table_unref (items);
    }

  *n_items = schema->n_items;
  return schema->items;
}

/**
 * g_settings_schema_get_id:
 * @schema: a #GSettingsSchema
 *
 * Get the ID of @schema.
 *
 * Returns: (transfer none): the ID
 **/
const gchar *
g_settings_schema_get_id (GSettingsSchema *schema)
{
  return schema->id;
}

static inline void
endian_fixup (GVariant **value)
{
#if G_BYTE_ORDER == G_BIG_ENDIAN
  GVariant *tmp;

  tmp = g_variant_byteswap (*value);
  g_variant_unref (*value);
  *value = tmp;
#endif
}

void
g_settings_schema_key_init (GSettingsSchemaKey *key,
                            GSettingsSchema    *schema,
                            const gchar        *name)
{
  GVariantIter *iter;
  GVariant *data;
  guchar code;

  memset (key, 0, sizeof *key);

  iter = g_settings_schema_get_value (schema, name);

  key->schema = g_settings_schema_ref (schema);
  key->default_value = g_variant_iter_next_value (iter);
  endian_fixup (&key->default_value);
  key->type = g_variant_get_type (key->default_value);
  key->name = g_intern_string (name);

  while (g_variant_iter_next (iter, "(y*)", &code, &data))
    {
      switch (code)
        {
        case 'l':
          /* translation requested */
          g_variant_get (data, "(y&s)", &key->lc_char, &key->unparsed);
          break;

        case 'e':
          /* enumerated types... */
          key->is_enum = TRUE;
          goto choice;

        case 'f':
          /* flags... */
          key->is_flags = TRUE;
          goto choice;

        choice: case 'c':
          /* ..., choices, aliases */
          key->strinfo = g_variant_get_fixed_array (data, &key->strinfo_length, sizeof (guint32));
          break;

        case 'r':
          g_variant_get (data, "(**)", &key->minimum, &key->maximum);
          endian_fixup (&key->minimum);
          endian_fixup (&key->maximum);
          break;

        default:
          g_warning ("unknown schema extension '%c'", code);
          break;
        }

      g_variant_unref (data);
    }

  g_variant_iter_free (iter);
}

void
g_settings_schema_key_clear (GSettingsSchemaKey *key)
{
  if (key->minimum)
    g_variant_unref (key->minimum);

  if (key->maximum)
    g_variant_unref (key->maximum);

  g_variant_unref (key->default_value);

  g_settings_schema_unref (key->schema);
}

gboolean
g_settings_schema_key_type_check (GSettingsSchemaKey *key,
                                  GVariant           *value)
{
  g_return_val_if_fail (value != NULL, FALSE);

  return g_variant_is_of_type (value, key->type);
}

GVariant *
g_settings_schema_key_range_fixup (GSettingsSchemaKey *key,
                                   GVariant           *value)
{
  const gchar *target;

  if (g_settings_schema_key_range_check (key, value))
    return g_variant_ref (value);

  if (key->strinfo == NULL)
    return NULL;

  if (g_variant_is_container (value))
    {
      GVariantBuilder builder;
      GVariantIter iter;
      GVariant *child;

      g_variant_iter_init (&iter, value);
      g_variant_builder_init (&builder, g_variant_get_type (value));

      while ((child = g_variant_iter_next_value (&iter)))
        {
          GVariant *fixed;

          fixed = g_settings_schema_key_range_fixup (key, child);
          g_variant_unref (child);

          if (fixed == NULL)
            {
              g_variant_builder_clear (&builder);
              return NULL;
            }

          g_variant_builder_add_value (&builder, fixed);
          g_variant_unref (fixed);
        }

      return g_variant_ref_sink (g_variant_builder_end (&builder));
    }

  target = strinfo_string_from_alias (key->strinfo, key->strinfo_length,
                                      g_variant_get_string (value, NULL));
  return target ? g_variant_ref_sink (g_variant_new_string (target)) : NULL;
}

GVariant *
g_settings_schema_key_get_translated_default (GSettingsSchemaKey *key)
{
  const gchar *translated;
  GError *error = NULL;
  const gchar *domain;
  GVariant *value;

  domain = g_settings_schema_get_gettext_domain (key->schema);

  if (key->lc_char == '\0')
    /* translation not requested for this key */
    return NULL;

  if (key->lc_char == 't')
    translated = g_dcgettext (domain, key->unparsed, LC_TIME);
  else
    translated = g_dgettext (domain, key->unparsed);

  if (translated == key->unparsed)
    /* the default value was not translated */
    return NULL;

  /* try to parse the translation of the unparsed default */
  value = g_variant_parse (key->type, translated, NULL, NULL, &error);

  if (value == NULL)
    {
      g_warning ("Failed to parse translated string '%s' for "
                 "key '%s' in schema '%s': %s", translated, key->name,
                 g_settings_schema_get_id (key->schema), error->message);
      g_warning ("Using untranslated default instead.");
      g_error_free (error);
    }

  else if (!g_settings_schema_key_range_check (key, value))
    {
      g_warning ("Translated default '%s' for key '%s' in schema '%s' "
                 "is outside of valid range", key->unparsed, key->name,
                 g_settings_schema_get_id (key->schema));
      g_variant_unref (value);
      value = NULL;
    }

  return value;
}

gint
g_settings_schema_key_to_enum (GSettingsSchemaKey *key,
                               GVariant           *value)
{
  gboolean it_worked;
  guint result;

  it_worked = strinfo_enum_from_string (key->strinfo, key->strinfo_length,
                                        g_variant_get_string (value, NULL),
                                        &result);

  /* 'value' can only come from the backend after being filtered for validity,
   * from the translation after being filtered for validity, or from the schema
   * itself (which the schema compiler checks for validity).  If this assertion
   * fails then it's really a bug in GSettings or the schema compiler...
   */
  g_assert (it_worked);

  return result;
}

GVariant *
g_settings_schema_key_from_enum (GSettingsSchemaKey *key,
                                 gint                value)
{
  const gchar *string;

  string = strinfo_string_from_enum (key->strinfo, key->strinfo_length, value);

  if (string == NULL)
    return NULL;

  return g_variant_new_string (string);
}

guint
g_settings_schema_key_to_flags (GSettingsSchemaKey *key,
                                GVariant           *value)
{
  GVariantIter iter;
  const gchar *flag;
  guint result;

  result = 0;
  g_variant_iter_init (&iter, value);
  while (g_variant_iter_next (&iter, "&s", &flag))
    {
      gboolean it_worked;
      guint flag_value;

      it_worked = strinfo_enum_from_string (key->strinfo, key->strinfo_length, flag, &flag_value);
      /* as in g_settings_to_enum() */
      g_assert (it_worked);

      result |= flag_value;
    }

  return result;
}

GVariant *
g_settings_schema_key_from_flags (GSettingsSchemaKey *key,
                                  guint               value)
{
  GVariantBuilder builder;
  gint i;

  g_variant_builder_init (&builder, G_VARIANT_TYPE ("as"));

  for (i = 0; i < 32; i++)
    if (value & (1u << i))
      {
        const gchar *string;

        string = strinfo_string_from_enum (key->strinfo, key->strinfo_length, 1u << i);

        if (string == NULL)
          {
            g_variant_builder_clear (&builder);
            return NULL;
          }

        g_variant_builder_add (&builder, "s", string);
      }

  return g_variant_builder_end (&builder);
}

G_DEFINE_BOXED_TYPE (GSettingsSchemaKey, g_settings_schema_key, g_settings_schema_key_ref, g_settings_schema_key_unref)

/**
 * g_settings_schema_key_ref:
 * @key: a #GSettingsSchemaKey
 *
 * Increase the reference count of @key, returning a new reference.
 *
 * Returns: a new reference to @key
 *
 * Since: 2.40
 **/
GSettingsSchemaKey *
g_settings_schema_key_ref (GSettingsSchemaKey *key)
{
  g_return_val_if_fail (key != NULL, NULL);

  g_atomic_int_inc (&key->ref_count);

  return key;
}

/**
 * g_settings_schema_key_unref:
 * @key: a #GSettingsSchemaKey
 *
 * Decrease the reference count of @key, possibly freeing it.
 *
 * Since: 2.40
 **/
void
g_settings_schema_key_unref (GSettingsSchemaKey *key)
{
  g_return_if_fail (key != NULL);

  if (g_atomic_int_dec_and_test (&key->ref_count))
    {
      g_settings_schema_key_clear (key);

      g_slice_free (GSettingsSchemaKey, key);
    }
}

/**
 * g_settings_schema_get_key:
 * @schema: a #GSettingsSchema
 * @name: the name of a key
 *
 * Gets the key named @name from @schema.
 *
 * It is a programmer error to request a key that does not exist.  See
 * g_settings_schema_list_keys().
 *
 * Returns: (transfer full): the #GSettingsSchemaKey for @name
 *
 * Since: 2.40
 **/
GSettingsSchemaKey *
g_settings_schema_get_key (GSettingsSchema *schema,
                           const gchar     *name)
{
  GSettingsSchemaKey *key;

  g_return_val_if_fail (schema != NULL, NULL);
  g_return_val_if_fail (name != NULL, NULL);

  key = g_slice_new (GSettingsSchemaKey);
  g_settings_schema_key_init (key, schema, name);
  key->ref_count = 1;

  return key;
}

/**
 * g_settings_schema_key_get_name:
 * @key: a #GSettingsSchemaKey
 *
 * Gets the name of @key.
 *
 * Returns: the name of @key.
 *
 * Since: 2.44
 */
const gchar *
g_settings_schema_key_get_name (GSettingsSchemaKey *key)
{
  g_return_val_if_fail (key != NULL, NULL);

  return key->name;
}

/**
 * g_settings_schema_key_get_summary:
 * @key: a #GSettingsSchemaKey
 *
 * Gets the summary for @key.
 *
 * If no summary has been provided in the schema for @key, returns
 * %NULL.
 *
 * The summary is a short description of the purpose of the key; usually
 * one short sentence.  Summaries can be translated and the value
 * returned from this function is is the current locale.
 *
 * This function is slow.  The summary and description information for
 * the schemas is not stored in the compiled schema database so this
 * function has to parse all of the source XML files in the schema
 * directory.
 *
 * Returns: the summary for @key, or %NULL
 *
 * Since: 2.34
 **/
const gchar *
g_settings_schema_key_get_summary (GSettingsSchemaKey *key)
{
  GHashTable **text_tables;
  GHashTable *summaries;

  text_tables = g_settings_schema_source_get_text_tables (key->schema->source);
  summaries = g_hash_table_lookup (text_tables[0], key->schema->id);

  return summaries ? g_hash_table_lookup (summaries, key->name) : NULL;
}

/**
 * g_settings_schema_key_get_description:
 * @key: a #GSettingsSchemaKey
 *
 * Gets the description for @key.
 *
 * If no description has been provided in the schema for @key, returns
 * %NULL.
 *
 * The description can be one sentence to several paragraphs in length.
 * Paragraphs are delimited with a double newline.  Descriptions can be
 * translated and the value returned from this function is is the
 * current locale.
 *
 * This function is slow.  The summary and description information for
 * the schemas is not stored in the compiled schema database so this
 * function has to parse all of the source XML files in the schema
 * directory.
 *
 * Returns: the description for @key, or %NULL
 *
 * Since: 2.34
 **/
const gchar *
g_settings_schema_key_get_description (GSettingsSchemaKey *key)
{
  GHashTable **text_tables;
  GHashTable *descriptions;

  text_tables = g_settings_schema_source_get_text_tables (key->schema->source);
  descriptions = g_hash_table_lookup (text_tables[1], key->schema->id);

  return descriptions ? g_hash_table_lookup (descriptions, key->name) : NULL;
}

/**
 * g_settings_schema_key_get_value_type:
 * @key: a #GSettingsSchemaKey
 *
 * Gets the #GVariantType of @key.
 *
 * Returns: (transfer none): the type of @key
 *
 * Since: 2.40
 **/
const GVariantType *
g_settings_schema_key_get_value_type (GSettingsSchemaKey *key)
{
  g_return_val_if_fail (key, NULL);

  return key->type;
}

/**
 * g_settings_schema_key_get_default_value:
 * @key: a #GSettingsSchemaKey
 *
 * Gets the default value for @key.
 *
 * Note that this is the default value according to the schema.  System
 * administrator defaults and lockdown are not visible via this API.
 *
 * Returns: (transfer full): the default value for the key
 *
 * Since: 2.40
 **/
GVariant *
g_settings_schema_key_get_default_value (GSettingsSchemaKey *key)
{
  GVariant *value;

  g_return_val_if_fail (key, NULL);

  value = g_settings_schema_key_get_translated_default (key);

  if (!value)
    value = g_variant_ref (key->default_value);

  return value;
}

/**
 * g_settings_schema_key_get_range:
 * @key: a #GSettingsSchemaKey
 *
 * Queries the range of a key.
 *
 * This function will return a #GVariant that fully describes the range
 * of values that are valid for @key.
 *
 * The type of #GVariant returned is `(sv)`. The string describes
 * the type of range restriction in effect. The type and meaning of
 * the value contained in the variant depends on the string.
 *
 * If the string is `'type'` then the variant contains an empty array.
 * The element type of that empty array is the expected type of value
 * and all values of that type are valid.
 *
 * If the string is `'enum'` then the variant contains an array
 * enumerating the possible values. Each item in the array is
 * a possible valid value and no other values are valid.
 *
 * If the string is `'flags'` then the variant contains an array. Each
 * item in the array is a value that may appear zero or one times in an
 * array to be used as the value for this key. For example, if the
 * variant contained the array `['x', 'y']` then the valid values for
 * the key would be `[]`, `['x']`, `['y']`, `['x', 'y']` and
 * `['y', 'x']`.
 *
 * Finally, if the string is `'range'` then the variant contains a pair
 * of like-typed values -- the minimum and maximum permissible values
 * for this key.
 *
 * This information should not be used by normal programs.  It is
 * considered to be a hint for introspection purposes.  Normal programs
 * should already know what is permitted by their own schema.  The
 * format may change in any way in the future -- but particularly, new
 * forms may be added to the possibilities described above.
 *
 * You should free the returned value with g_variant_unref() when it is
 * no longer needed.
 *
 * Returns: (transfer full): a #GVariant describing the range
 *
 * Since: 2.40
 **/
GVariant *
g_settings_schema_key_get_range (GSettingsSchemaKey *key)
{
  const gchar *type;
  GVariant *range;

  if (key->minimum)
    {
      range = g_variant_new ("(**)", key->minimum, key->maximum);
      type = "range";
    }
  else if (key->strinfo)
    {
      range = strinfo_enumerate (key->strinfo, key->strinfo_length);
      type = key->is_flags ? "flags" : "enum";
    }
  else
    {
      range = g_variant_new_array (key->type, NULL, 0);
      type = "type";
    }

  return g_variant_ref_sink (g_variant_new ("(sv)", type, range));
}

/**
 * g_settings_schema_key_range_check:
 * @key: a #GSettingsSchemaKey
 * @value: the value to check
 *
 * Checks if the given @value is of the correct type and within the
 * permitted range for @key.
 *
 * It is a programmer error if @value is not of the correct type -- you
 * must check for this first.
 *
 * Returns: %TRUE if @value is valid for @key
 *
 * Since: 2.40
 **/
gboolean
g_settings_schema_key_range_check (GSettingsSchemaKey *key,
                                   GVariant           *value)
{
  if (key->minimum == NULL && key->strinfo == NULL)
    return TRUE;

  if (g_variant_is_container (value))
    {
      gboolean ok = TRUE;
      GVariantIter iter;
      GVariant *child;

      g_variant_iter_init (&iter, value);
      while (ok && (child = g_variant_iter_next_value (&iter)))
        {
          ok = g_settings_schema_key_range_check (key, child);
          g_variant_unref (child);
        }

      return ok;
    }

  if (key->minimum)
    {
      return g_variant_compare (key->minimum, value) <= 0 &&
             g_variant_compare (value, key->maximum) <= 0;
    }

  return strinfo_is_string_valid (key->strinfo, key->strinfo_length,
                                  g_variant_get_string (value, NULL));
}
