/*
 * Copyright © 2010 Codethink 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, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include "config.h"

#include "gsettingsschema.h"
#include "gvdb/gvdb-reader.h"

#include <glibintl.h>

G_DEFINE_TYPE (GSettingsSchema, g_settings_schema, G_TYPE_OBJECT)

struct _GSettingsSchemaPrivate
{
  const gchar *gettext_domain;
  const gchar *path;
  GQuark *items;
  gint n_items;
  GvdbTable *table;
  gchar *name;
};

static GSList *schema_sources;

static void
initialise_schema_sources (void)
{
  static gsize initialised;

  if G_UNLIKELY (g_once_init_enter (&initialised))
    {
      const gchar * const *dir;
      const gchar *path;

      for (dir = g_get_system_data_dirs (); *dir; dir++)
        {
          gchar *filename;
          GvdbTable *table;

          filename = g_build_filename (*dir, "glib-2.0", "schemas",
                                       "gschemas.compiled", NULL);
          table = gvdb_table_new (filename, TRUE, NULL);

          if (table != NULL)
            schema_sources = g_slist_prepend (schema_sources, table);

          g_free (filename);
        }

      schema_sources = g_slist_reverse (schema_sources);

      if ((path = g_getenv ("GSETTINGS_SCHEMA_DIR")) != NULL)
        {
          gchar *filename;
          GvdbTable *table;

          filename = g_build_filename (path, "gschemas.compiled", NULL);
          table = gvdb_table_new (filename, TRUE, NULL);

          if (table != NULL)
            schema_sources = g_slist_prepend (schema_sources, table);

          g_free (filename);
        }

      g_once_init_leave (&initialised, TRUE);
    }
}

static gboolean
steal_item (gpointer key,
            gpointer value,
            gpointer user_data)
{
  gchar ***ptr = user_data;

  *(*ptr)++ = (gchar *) key;

  return TRUE;
}

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

static void
ensure_schema_lists (void)
{
  if (g_once_init_enter (&schema_lists_initialised))
    {
      GHashTable *single, *reloc;
      const gchar **ptr;
      GSList *source;
      gchar **list;
      gint i;

      initialise_schema_sources ();

      /* 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 (source = schema_sources; source; source = source->next)
        {
          list = gvdb_table_list (source->data, "");

          g_assert (list != NULL);

          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 (source->data, 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);
        }

      ptr = g_new (const gchar *, g_hash_table_size (single) + 1);
      non_relocatable_schema_list = ptr;
      g_hash_table_foreach_steal (single, steal_item, &ptr);
      g_hash_table_unref (single);
      *ptr = NULL;

      ptr = g_new (const gchar *, g_hash_table_size (reloc) + 1);
      relocatable_schema_list = ptr;
      g_hash_table_foreach_steal (reloc, steal_item, &ptr);
      g_hash_table_unref (reloc);
      *ptr = NULL;

      g_once_init_leave (&schema_lists_initialised, TRUE);
    }
}

/**
 * g_settings_list_schemas:
 *
 * Gets a list of the #GSettings schemas installed on the system.  The
 * returned list is exactly the list of schemas for which you may call
 * g_settings_new() without adverse effects.
 *
 * This function does not list the schemas that do not provide their own
 * paths (ie: schemas for which you must use
 * g_settings_new_with_path()).  See
 * g_settings_list_relocatable_schemas() for that.
 *
 * 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
 **/
const gchar * const *
g_settings_list_schemas (void)
{
  ensure_schema_lists ();

  return non_relocatable_schema_list;
}

/**
 * g_settings_list_relocatable_schemas:
 *
 * Gets a list of the relocatable #GSettings schemas installed on the
 * system.  These are schemas that do not provide their own path.  It is
 * usual to instantiate these schemas directly, but if you want to you
 * can use g_settings_new_with_path() to specify the path.
 *
 * The output of this function, tTaken together with the output of
 * g_settings_list_schemas() represents the complete list of all
 * installed 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
 **/
const gchar * const *
g_settings_list_relocatable_schemas (void)
{
  ensure_schema_lists ();

  return relocatable_schema_list;
}

static void
g_settings_schema_finalize (GObject *object)
{
  GSettingsSchema *schema = G_SETTINGS_SCHEMA (object);

  gvdb_table_unref (schema->priv->table);
  g_free (schema->priv->items);
  g_free (schema->priv->name);

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

static void
g_settings_schema_init (GSettingsSchema *schema)
{
  schema->priv = G_TYPE_INSTANCE_GET_PRIVATE (schema, G_TYPE_SETTINGS_SCHEMA,
                                              GSettingsSchemaPrivate);
}

static void
g_settings_schema_class_init (GSettingsSchemaClass *class)
{
  GObjectClass *object_class = G_OBJECT_CLASS (class);

  object_class->finalize = g_settings_schema_finalize;

  g_type_class_add_private (class, sizeof (GSettingsSchemaPrivate));
}

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->priv->table, key)))
    {
      result = g_variant_get_string (value, NULL);
      g_variant_unref (value);
    }

  return result;
}

GSettingsSchema *
g_settings_schema_new (const gchar *name)
{
  GSettingsSchema *schema;
  GvdbTable *table = NULL;
  GSList *source;

  initialise_schema_sources ();

  for (source = schema_sources; source; source = source->next)
    {
      GvdbTable *file = source->data;

      if ((table = gvdb_table_get_table (file, name)))
        break;
    }

  if (table == NULL)
    g_error ("Settings schema '%s' is not installed\n", name);

  schema = g_object_new (G_TYPE_SETTINGS_SCHEMA, NULL);
  schema->priv->name = g_strdup (name);
  schema->priv->table = table;
  schema->priv->path =
    g_settings_schema_get_string (schema, ".path");
  schema->priv->gettext_domain =
    g_settings_schema_get_string (schema, ".gettext-domain");

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

  return schema;
}

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

  value = gvdb_table_get_raw_value (schema->priv->table, key);

  if G_UNLIKELY (value == NULL)
    g_error ("schema does not contain a key named '%s'", key);

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

  return iter;
}

const gchar *
g_settings_schema_get_path (GSettingsSchema *schema)
{
  return schema->priv->path;
}

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

gboolean
g_settings_schema_has_key (GSettingsSchema *schema,
                           const gchar     *key)
{
  return gvdb_table_has_value (schema->priv->table, key);
}

const GQuark *
g_settings_schema_list (GSettingsSchema *schema,
                        gint            *n_items)
{
  gint i, j;

  if (schema->priv->items == NULL)
    {
      gchar **list;
      gint len;

      list = gvdb_table_list (schema->priv->table, "");
      len = g_strv_length (list);

      schema->priv->items = g_new (GQuark, len);
      j = 0;

      for (i = 0; i < len; i++)
        if (list[i][0] != '.')
          schema->priv->items[j++] = g_quark_from_string (list[i]);
      schema->priv->n_items = j;

      g_strfreev (list);
    }

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