/*
 * 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.
 *
 * Authors: Ryan Lortie <desrt@desrt.ca>
 *          Rodrigo Moya <rodrigo@gnome.org>
 */

#include "config.h"

#include "gsimplepermission.h"
#include "gsettingsbackendinternal.h"
#include "giomodule.h"


#define G_TYPE_MEMORY_SETTINGS_BACKEND  (g_memory_settings_backend_get_type())
#define G_MEMORY_SETTINGS_BACKEND(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
                                         G_TYPE_MEMORY_SETTINGS_BACKEND,     \
                                         GMemorySettingsBackend))

typedef GSettingsBackendClass GMemorySettingsBackendClass;
typedef struct
{
  GSettingsBackend parent_instance;
  GHashTable *table;
} GMemorySettingsBackend;

G_DEFINE_TYPE_WITH_CODE (GMemorySettingsBackend,
                         g_memory_settings_backend,
                         G_TYPE_SETTINGS_BACKEND,
                         g_io_extension_point_implement (G_SETTINGS_BACKEND_EXTENSION_POINT_NAME,
                                                         g_define_type_id, "memory", 10))

static GHashTable *
g_memory_settings_backend_get_table (GHashTable   *table,
                                     const gchar **key_ptr)
{
  const gchar *key = *key_ptr;
  gchar *prefix;
  gchar *name;
  gint i, j;

  for (i = 2; key[i - 2] != ':' || key[i - 1] != '/'; i++)
    if (key[i - 2] == '\0')
      /* no :/ in the string -- pass through */
      return table;

  for (j = i + 1; key[j - 1] != '/'; j++)
    if (key[j - 1] == '\0')
      /* string of form /some/path:/child -- definitely invalid */
      return NULL;

  /* We now have this situation:
   *
   *   /some/path:/child/item
   *   ^0          ^i    ^j
   *
   * So we can split the string into 3 parts:
   *
   *   prefix   = /some/path:/
   *   child    = child/
   *   *key_ptr = item
   */
  prefix = g_strndup (key, i);
  name = g_strndup (key + i, j - i);

  /* name is either like 'foo' or ':foo'
   *
   * If it doesn't start with a colon, it's in the schema.
   */
  if (name[0] == ':')
    {
      table = g_hash_table_lookup (table, prefix);
      if (table)
        table = g_hash_table_lookup (table, name);
    }
  else
    {
      gpointer value;

      if (!g_hash_table_lookup_extended (table, prefix, NULL, &value))
        g_hash_table_insert (table, prefix,
                             value = g_hash_table_new_full (g_str_hash, g_str_equal,
                                                            g_free, (GDestroyNotify) g_hash_table_unref));

      table = value;

      if (!g_hash_table_lookup_extended (table, prefix, NULL, &value))
        g_hash_table_insert (table, prefix,
                             value = g_hash_table_new_full (g_str_hash, g_str_equal,
                                                            g_free, (GDestroyNotify) g_hash_table_unref));
    }

    if (key[i] == ':' && key[i + 1] == '/')
      {
        gchar *prefix;
        gchar *name;
        gint j;

        i += 2;

        for (j = i; key[j] != '/'; j++)
          /* found a path of the form /a:/b
           * which is never a valid spot for a key.
           */
          if (key[j] == '\0')
            return NULL;

        name = g_strndup ((const gchar *) key + i, j - i);
        prefix = g_strndup (key, i);
        table = g_hash_table_lookup (table, prefix);
        g_free (prefix);
      }

  return table;
}

static GVariant *
g_memory_settings_backend_read (GSettingsBackend   *backend,
                                const gchar        *key,
                                const GVariantType *expected_type,
                                gboolean            default_value)
{
  GMemorySettingsBackend *memory = G_MEMORY_SETTINGS_BACKEND (backend);
  GVariant *value;
  GHashTable *table;

  if (default_value)
    return NULL;

  table = g_memory_settings_backend_get_table (memory->table, &key);
  if (!table)
    return NULL;

  value = g_hash_table_lookup (table, key);

  if (value != NULL)
    g_variant_ref (value);

  return value;
}

static gboolean
g_memory_settings_backend_write (GSettingsBackend *backend,
                                 const gchar      *key,
                                 GVariant         *value,
                                 gpointer          origin_tag)
{
  GMemorySettingsBackend *memory = G_MEMORY_SETTINGS_BACKEND (backend);
  GVariant *old_value;
  GHashTable *table;

  table = g_memory_settings_backend_get_table (memory->table, &key);
  if (!table)
    return FALSE;

  old_value = g_hash_table_lookup (table, key);
  g_variant_ref_sink (value);

  if (old_value == NULL || !g_variant_equal (value, old_value))
    {
      g_hash_table_insert (memory->table, g_strdup (key), value);
      g_settings_backend_changed (backend, key, origin_tag);
    }
  else
    g_variant_unref (value);

  return TRUE;
}

static gboolean
g_memory_settings_backend_write_one (gpointer key,
                                     gpointer value,
                                     gpointer data)
{
  GMemorySettingsBackend *memory = data;
  GHashTable *table;

  table = g_memory_settings_backend_get_table (memory->table, &key);
  if (!table)
    return FALSE;

  if (value != NULL)
    g_hash_table_insert (table, g_strdup (key), g_variant_ref (value));
  else
    g_hash_table_remove (table, key);

  return FALSE;
}

static gboolean
g_memory_settings_backend_write_tree (GSettingsBackend *backend,
                                      GTree            *tree,
                                      gpointer          origin_tag)
{
  g_tree_foreach (tree, g_memory_settings_backend_write_one, backend);
  g_settings_backend_changed_tree (backend, tree, origin_tag);

  return TRUE;
}

static void
g_memory_settings_backend_reset (GSettingsBackend *backend,
                                 const gchar      *key,
                                 gpointer          origin_tag)
{
  GMemorySettingsBackend *memory = G_MEMORY_SETTINGS_BACKEND (backend);
  GHashTable *table;

  table = g_memory_settings_backend_get_table (memory->table, &key);
  if (!table)
    return;

  if (g_hash_table_lookup (table, key))
    {
      g_hash_table_remove (table, key);
      g_settings_backend_changed (backend, key, origin_tag);
    }
}

static gboolean
g_memory_settings_backend_get_writable (GSettingsBackend *backend,
                                        const gchar      *name)
{
  return TRUE;
}

static GPermission *
g_memory_settings_backend_get_permission (GSettingsBackend *backend,
                                          const gchar      *path)
{
  return g_simple_permission_new (TRUE);
}

static gchar **
g_memory_settings_backend_list (GSettingsBackend    *backend,
				const gchar         *path,
				const gchar * const *schema_items)
{
  gchar **result = NULL;
  GHashTable *table;
  GMemorySettingsBackend *memory = G_MEMORY_SETTINGS_BACKEND (backend);

  table = g_memory_settings_backend_get_table (memory->table, &path);
  if (table != NULL)
    {
      GHashTableIter iter;
      gchar *key_name;
      guint i;
      GSList *list = NULL;

      while (g_hash_table_iter_next (&iter, (gpointer *) &key_name, NULL))
        {
	  gboolean in_schema_items = FALSE;

	  for (i = 0; i < g_strv_length ((gchar **) schema_items); i++)
	    {
	      if (g_str_equal (key_name, schema_items[i]))
	        {
		  /* It's in both lists, so return it */
		  list = g_slist_append (list, key_name);
		  in_schema_items = TRUE;
		}
	    }
	  if (!in_schema_items)
	    {
	      /* Has been added by the user */
	      list = g_slist_append (list, key_name);
	    }
	}

      result = g_new0 (gchar *, g_slist_length (list) + 1);
      i = 0;
      while (list != NULL)
        {
	  result[i] = g_strdup ((const gchar *) list->data);
	  i++;

	  list = g_slist_remove (list, list->data);
	}

      result[i] = NULL;
    }

  return result;
}

static gboolean
g_memory_settings_backend_can_insert (GSettingsBackend *backend,
				      const gchar      *path)
{
  return FALSE;
}

static gboolean
g_memory_settings_backend_can_remove (GSettingsBackend *backend,
				      const gchar      *path,
				      const gchar      *id)
{
  return FALSE;
}

static gboolean
g_memory_settings_backend_insert (GSettingsBackend *backend,
				  const gchar      *path,
				  gint              index_,
				  const gchar      *prefix,
				  gchar           **name)
{
  return FALSE;
}

static gboolean
g_memory_settings_backend_remove (GSettingsBackend *backend,
				  const gchar      *path,
				  const gchar      *id)
{
  return FALSE;
}

static void
g_memory_settings_backend_finalize (GObject *object)
{
  GMemorySettingsBackend *memory = G_MEMORY_SETTINGS_BACKEND (object);

  g_hash_table_unref (memory->table);

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

static void
g_memory_settings_backend_init (GMemorySettingsBackend *memory)
{
  memory->table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
                                         (GDestroyNotify) g_variant_unref);
}

static void
g_memory_settings_backend_class_init (GMemorySettingsBackendClass *class)
{
  GSettingsBackendClass *backend_class = G_SETTINGS_BACKEND_CLASS (class);
  GObjectClass *object_class = G_OBJECT_CLASS (class);

  backend_class->read = g_memory_settings_backend_read;
  backend_class->write = g_memory_settings_backend_write;
  backend_class->write_tree = g_memory_settings_backend_write_tree;
  backend_class->reset = g_memory_settings_backend_reset;
  backend_class->get_writable = g_memory_settings_backend_get_writable;
  backend_class->get_permission = g_memory_settings_backend_get_permission;
  backend_class->list = g_memory_settings_backend_list;
  backend_class->can_insert = g_memory_settings_backend_can_insert;
  backend_class->can_remove = g_memory_settings_backend_can_remove;
  backend_class->insert = g_memory_settings_backend_insert;
  backend_class->remove = g_memory_settings_backend_remove;
  object_class->finalize = g_memory_settings_backend_finalize;
}

GSettingsBackend *
g_memory_settings_backend_new (void)
{
  return g_object_new (G_TYPE_MEMORY_SETTINGS_BACKEND, NULL);
}
