/*
 * 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.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/>.
 *
 * Author: Ryan Lortie <desrt@desrt.ca>
 */

#include "gvdb-reader.h"
#include "gvdb-format.h"

#include <string.h>

struct _GvdbTable {
  GBytes *bytes;

  const gchar *data;
  gsize size;

  gboolean byteswapped;
  gboolean trusted;

  const guint32_le *bloom_words;
  guint32 n_bloom_words;
  guint bloom_shift;

  const guint32_le *hash_buckets;
  guint32 n_buckets;

  struct gvdb_hash_item *hash_items;
  guint32 n_hash_items;
};

static const gchar *
gvdb_table_item_get_key (GvdbTable                   *file,
                         const struct gvdb_hash_item *item,
                         gsize                       *size)
{
  guint32 start, end;

  start = guint32_from_le (item->key_start);
  *size = guint16_from_le (item->key_size);
  end = start + *size;

  if G_UNLIKELY (start > end || end > file->size)
    return NULL;

  return file->data + start;
}

static gconstpointer
gvdb_table_dereference (GvdbTable                 *file,
                        const struct gvdb_pointer *pointer,
                        gint                       alignment,
                        gsize                     *size)
{
  guint32 start, end;

  start = guint32_from_le (pointer->start);
  end = guint32_from_le (pointer->end);

  if G_UNLIKELY (start > end || end > file->size || start & (alignment - 1))
    return NULL;

  *size = end - start;

  return file->data + start;
}

static void
gvdb_table_setup_root (GvdbTable                 *file,
                       const struct gvdb_pointer *pointer)
{
  const struct gvdb_hash_header *header;
  guint32 n_bloom_words;
  guint32 n_buckets;
  gsize size;

  header = gvdb_table_dereference (file, pointer, 4, &size);

  if G_UNLIKELY (header == NULL || size < sizeof *header)
    return;

  size -= sizeof *header;

  n_bloom_words = guint32_from_le (header->n_bloom_words);
  n_buckets = guint32_from_le (header->n_buckets);
  n_bloom_words &= (1u << 27) - 1;

  if G_UNLIKELY (n_bloom_words * sizeof (guint32_le) > size)
    return;

  file->bloom_words = (gpointer) (header + 1);
  size -= n_bloom_words * sizeof (guint32_le);
  file->n_bloom_words = n_bloom_words;

  if G_UNLIKELY (n_buckets > G_MAXUINT / sizeof (guint32_le) ||
                 n_buckets * sizeof (guint32_le) > size)
    return;

  file->hash_buckets = file->bloom_words + file->n_bloom_words;
  size -= n_buckets * sizeof (guint32_le);
  file->n_buckets = n_buckets;

  if G_UNLIKELY (size % sizeof (struct gvdb_hash_item))
    return;

  file->hash_items = (gpointer) (file->hash_buckets + n_buckets);
  file->n_hash_items = size / sizeof (struct gvdb_hash_item);
}

/**
 * gvdb_table_new_from_bytes:
 * @bytes: the #GBytes with the data
 * @trusted: if the contents of @bytes are trusted
 * @error: %NULL, or a pointer to a %NULL #GError
 *
 * Creates a new #GvdbTable from the contents of @bytes.
 *
 * This call can fail if the header contained in @bytes is invalid or if @bytes
 * is empty; if so, %G_FILE_ERROR_INVAL will be returned.
 *
 * You should call gvdb_table_free() on the return result when you no
 * longer require it.
 *
 * Returns: a new #GvdbTable
 **/
GvdbTable *
gvdb_table_new_from_bytes (GBytes    *bytes,
                           gboolean   trusted,
                           GError   **error)
{
  const struct gvdb_header *header;
  GvdbTable *file;

  file = g_slice_new0 (GvdbTable);
  file->bytes = g_bytes_ref (bytes);
  file->data = g_bytes_get_data (bytes, &file->size);
  file->trusted = trusted;

  if (file->size < sizeof (struct gvdb_header))
    goto invalid;

  header = (gpointer) file->data;

  if (header->signature[0] == GVDB_SIGNATURE0 &&
      header->signature[1] == GVDB_SIGNATURE1 &&
      guint32_from_le (header->version) == 0)
    file->byteswapped = FALSE;

  else if (header->signature[0] == GVDB_SWAPPED_SIGNATURE0 &&
           header->signature[1] == GVDB_SWAPPED_SIGNATURE1 &&
           guint32_from_le (header->version) == 0)
    file->byteswapped = TRUE;

  else
    goto invalid;

  gvdb_table_setup_root (file, &header->root);

  return file;

invalid:
  g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_INVAL, "invalid gvdb header");

  g_bytes_unref (file->bytes);

  g_slice_free (GvdbTable, file);

  return NULL;
}

/**
 * gvdb_table_new:
 * @filename: a filename
 * @trusted: if the contents of @bytes are trusted
 * @error: %NULL, or a pointer to a %NULL #GError
 *
 * Creates a new #GvdbTable using the #GMappedFile for @filename as the
 * #GBytes.
 *
 * This function will fail if the file cannot be opened.
 * In that case, the #GError that is returned will be an error from
 * g_mapped_file_new().
 *
 * An empty or corrupt file will result in %G_FILE_ERROR_INVAL.
 *
 * Returns: a new #GvdbTable
 **/
GvdbTable *
gvdb_table_new (const gchar  *filename,
                gboolean      trusted,
                GError      **error)
{
  GMappedFile *mapped;
  GvdbTable *table;
  GBytes *bytes;

  mapped = g_mapped_file_new (filename, FALSE, error);
  if (!mapped)
    return NULL;

  bytes = g_mapped_file_get_bytes (mapped);
  table = gvdb_table_new_from_bytes (bytes, trusted, error);
  g_mapped_file_unref (mapped);
  g_bytes_unref (bytes);

  g_prefix_error (error, "%s: ", filename);

  return table;
}

static gboolean
gvdb_table_bloom_filter (GvdbTable *file,
                          guint32    hash_value)
{
  guint32 word, mask;

  if (file->n_bloom_words == 0)
    return TRUE;

  word = (hash_value / 32) % file->n_bloom_words;
  mask = 1 << (hash_value & 31);
  mask |= 1 << ((hash_value >> file->bloom_shift) & 31);

  return (guint32_from_le (file->bloom_words[word]) & mask) == mask;
}

static gboolean
gvdb_table_check_name (GvdbTable             *file,
                       struct gvdb_hash_item *item,
                       const gchar           *key,
                       guint                  key_length)
{
  const gchar *this_key;
  gsize this_size;
  guint32 parent;

  this_key = gvdb_table_item_get_key (file, item, &this_size);

  if G_UNLIKELY (this_key == NULL || this_size > key_length)
    return FALSE;

  key_length -= this_size;

  if G_UNLIKELY (memcmp (this_key, key + key_length, this_size) != 0)
    return FALSE;

  parent = guint32_from_le (item->parent);
  if (key_length == 0 && parent == 0xffffffffu)
    return TRUE;

  if G_LIKELY (parent < file->n_hash_items && this_size > 0)
    return gvdb_table_check_name (file,
                                   &file->hash_items[parent],
                                   key, key_length);

  return FALSE;
}

static const struct gvdb_hash_item *
gvdb_table_lookup (GvdbTable   *file,
                   const gchar *key,
                   gchar        type)
{
  guint32 hash_value = 5381;
  guint key_length;
  guint32 bucket;
  guint32 lastno;
  guint32 itemno;

  if G_UNLIKELY (file->n_buckets == 0 || file->n_hash_items == 0)
    return NULL;

  for (key_length = 0; key[key_length]; key_length++)
    hash_value = (hash_value * 33) + ((signed char *) key)[key_length];

  if (!gvdb_table_bloom_filter (file, hash_value))
    return NULL;

  bucket = hash_value % file->n_buckets;
  itemno = guint32_from_le (file->hash_buckets[bucket]);

  if (bucket == file->n_buckets - 1 ||
      (lastno = guint32_from_le(file->hash_buckets[bucket + 1])) > file->n_hash_items)
    lastno = file->n_hash_items;

  while G_LIKELY (itemno < lastno)
    {
      struct gvdb_hash_item *item = &file->hash_items[itemno];

      if (hash_value == guint32_from_le (item->hash_value))
        if G_LIKELY (gvdb_table_check_name (file, item, key, key_length))
          if G_LIKELY (item->type == type)
            return item;

      itemno++;
    }

  return NULL;
}

static gboolean
gvdb_table_list_from_item (GvdbTable                    *table,
                           const struct gvdb_hash_item  *item,
                           const guint32_le            **list,
                           guint                        *length)
{
  gsize size;

  *list = gvdb_table_dereference (table, &item->value.pointer, 4, &size);

  if G_LIKELY (*list == NULL || size % 4)
    return FALSE;

  *length = size / 4;

  return TRUE;
}

/**
 * gvdb_table_get_names:
 * @table: a #GvdbTable
 * @length: (out) (optional): the number of items returned, or %NULL
 *
 * Gets a list of all names contained in @table.
 *
 * No call to gvdb_table_get_table(), gvdb_table_list() or
 * gvdb_table_get_value() will succeed unless it is for one of the
 * names returned by this function.
 *
 * Note that some names that are returned may still fail for all of the
 * above calls in the case of the corrupted file.  Note also that the
 * returned strings may not be utf8.
 *
 * Returns: (array length=length): a %NULL-terminated list of strings, of length @length
 **/
gchar **
gvdb_table_get_names (GvdbTable *table,
                      gsize     *length)
{
  gchar **names;
  guint n_names;
  guint filled;
  guint total;
  guint i;

  /* We generally proceed by iterating over the list of items in the
   * hash table (in order of appearance) recording them into an array.
   *
   * Each item has a parent item (except root items).  The parent item
   * forms part of the name of the item.  We could go fetching the
   * parent item chain at the point that we encounter each item but then
   * we would need to implement some sort of recursion along with checks
   * for self-referential items.
   *
   * Instead, we do a number of passes.  Each pass will build up one
   * level of names (starting from the root).  We continue to do passes
   * until no more items are left.  The first pass will only add root
   * items and each further pass will only add items whose direct parent
   * is an item added in the immediately previous pass.  It's also
   * possible that items get filled if they follow their parent within a
   * particular pass.
   *
   * At most we will have a number of passes equal to the depth of the
   * tree.  Self-referential items will never be filled in (since their
   * parent will have never been filled in).  We continue until we have
   * a pass that fills in no additional items.
   *
   * This takes an O(n) algorithm and turns it into O(n*m) where m is
   * the depth of the tree, but in all sane cases the tree won't be very
   * deep and the constant factor of this algorithm is lower (and the
   * complexity of coding it, as well).
   */

  n_names = table->n_hash_items;
  names = g_new0 (gchar *, n_names + 1);

  /* 'names' starts out all-NULL.  On each pass we record the number
   * of items changed from NULL to non-NULL in 'filled' so we know if we
   * should repeat the loop.  'total' counts the total number of items
   * filled.  If 'total' ends up equal to 'n_names' then we know that
   * 'names' has been completely filled.
   */

  total = 0;
  do
    {
      /* Loop until we have filled no more entries */
      filled = 0;

      for (i = 0; i < n_names; i++)
        {
          const struct gvdb_hash_item *item = &table->hash_items[i];
          const gchar *name;
          gsize name_length;
          guint32 parent;

          /* already got it on a previous pass */
          if (names[i] != NULL)
            continue;

          parent = guint32_from_le (item->parent);

          if (parent == 0xffffffffu)
            {
              /* it's a root item */
              name = gvdb_table_item_get_key (table, item, &name_length);

              if (name != NULL)
                {
                  names[i] = g_strndup (name, name_length);
                  filled++;
                }
            }

          else if (parent < n_names && names[parent] != NULL)
            {
              /* It's a non-root item whose parent was filled in already.
               *
               * Calculate the name of this item by combining it with
               * its parent name.
               */
              name = gvdb_table_item_get_key (table, item, &name_length);

              if (name != NULL)
                {
                  const gchar *parent_name = names[parent];
                  gsize parent_length;
                  gchar *fullname;

                  parent_length = strlen (parent_name);
                  fullname = g_malloc (parent_length + name_length + 1);
                  memcpy (fullname, parent_name, parent_length);
                  memcpy (fullname + parent_length, name, name_length);
                  fullname[parent_length + name_length] = '\0';
                  names[i] = fullname;
                  filled++;
                }
            }
        }

      total += filled;
    }
  while (filled && total < n_names);

  /* If the table was corrupted then 'names' may have holes in it.
   * Collapse those.
   */
  if G_UNLIKELY (total != n_names)
    {
      GPtrArray *fixed_names;

      fixed_names = g_ptr_array_sized_new (n_names + 1  /* NULL terminator */);
      for (i = 0; i < n_names; i++)
        if (names[i] != NULL)
          g_ptr_array_add (fixed_names, names[i]);

      g_free (names);
      n_names = fixed_names->len;
      g_ptr_array_add (fixed_names, NULL);
      names = (gchar **) g_ptr_array_free (fixed_names, FALSE);
    }

  if (length)
    {
      G_STATIC_ASSERT (sizeof (*length) >= sizeof (n_names));
      *length = n_names;
    }

  return names;
}

/**
 * gvdb_table_list:
 * @file: a #GvdbTable
 * @key: a string
 *
 * List all of the keys that appear below @key.  The nesting of keys
 * within the hash file is defined by the program that created the hash
 * file.  One thing is constant: each item in the returned array can be
 * concatenated to @key to obtain the full name of that key.
 *
 * It is not possible to tell from this function if a given key is
 * itself a path, a value, or another hash table; you are expected to
 * know this for yourself.
 *
 * You should call g_strfreev() on the return result when you no longer
 * require it.
 *
 * Returns: a %NULL-terminated string array
 **/
gchar **
gvdb_table_list (GvdbTable   *file,
                 const gchar *key)
{
  const struct gvdb_hash_item *item;
  const guint32_le *list;
  gchar **strv;
  guint length;
  guint i;

  if ((item = gvdb_table_lookup (file, key, 'L')) == NULL)
    return NULL;

  if (!gvdb_table_list_from_item (file, item, &list, &length))
    return NULL;

  strv = g_new (gchar *, length + 1);
  for (i = 0; i < length; i++)
    {
      guint32 itemno = guint32_from_le (list[i]);

      if (itemno < file->n_hash_items)
        {
          const struct gvdb_hash_item *item;
          const gchar *string;
          gsize strsize;

          item = file->hash_items + itemno;

          string = gvdb_table_item_get_key (file, item, &strsize);

          if (string != NULL)
            strv[i] = g_strndup (string, strsize);
          else
            strv[i] = g_malloc0 (1);
        }
      else
        strv[i] = g_malloc0 (1);
    }

  strv[i] = NULL;

  return strv;
}

/**
 * gvdb_table_has_value:
 * @file: a #GvdbTable
 * @key: a string
 *
 * Checks for a value named @key in @file.
 *
 * Note: this function does not consider non-value nodes (other hash
 * tables, for example).
 *
 * Returns: %TRUE if @key is in the table
 **/
gboolean
gvdb_table_has_value (GvdbTable    *file,
                      const gchar  *key)
{
  static const struct gvdb_hash_item *item;
  gsize size;

  item = gvdb_table_lookup (file, key, 'v');

  if (item == NULL)
    return FALSE;

  return gvdb_table_dereference (file, &item->value.pointer, 8, &size) != NULL;
}

static GVariant *
gvdb_table_value_from_item (GvdbTable                   *table,
                            const struct gvdb_hash_item *item)
{
  GVariant *variant, *value;
  gconstpointer data;
  GBytes *bytes;
  gsize size;

  data = gvdb_table_dereference (table, &item->value.pointer, 8, &size);

  if G_UNLIKELY (data == NULL)
    return NULL;

  bytes = g_bytes_new_from_bytes (table->bytes, ((gchar *) data) - table->data, size);
  variant = g_variant_new_from_bytes (G_VARIANT_TYPE_VARIANT, bytes, table->trusted);
  value = g_variant_get_variant (variant);
  g_variant_unref (variant);
  g_bytes_unref (bytes);

  return value;
}

/**
 * gvdb_table_get_value:
 * @file: a #GvdbTable
 * @key: a string
 *
 * Looks up a value named @key in @file.
 *
 * If the value is not found then %NULL is returned.  Otherwise, a new
 * #GVariant instance is returned.  The #GVariant does not depend on the
 * continued existence of @file.
 *
 * You should call g_variant_unref() on the return result when you no
 * longer require it.
 *
 * Returns: a #GVariant, or %NULL
 **/
GVariant *
gvdb_table_get_value (GvdbTable    *file,
                      const gchar  *key)
{
  const struct gvdb_hash_item *item;
  GVariant *value;

  if ((item = gvdb_table_lookup (file, key, 'v')) == NULL)
    return NULL;

  value = gvdb_table_value_from_item (file, item);

  if (value && file->byteswapped)
    {
      GVariant *tmp;

      tmp = g_variant_byteswap (value);
      g_variant_unref (value);
      value = tmp;
    }

  return value;
}

/**
 * gvdb_table_get_raw_value:
 * @table: a #GvdbTable
 * @key: a string
 *
 * Looks up a value named @key in @file.
 *
 * This call is equivalent to gvdb_table_get_value() except that it
 * never byteswaps the value.
 *
 * Returns: a #GVariant, or %NULL
 **/
GVariant *
gvdb_table_get_raw_value (GvdbTable   *table,
                          const gchar *key)
{
  const struct gvdb_hash_item *item;

  if ((item = gvdb_table_lookup (table, key, 'v')) == NULL)
    return NULL;

  return gvdb_table_value_from_item (table, item);
}

/**
 * gvdb_table_get_table:
 * @file: a #GvdbTable
 * @key: a string
 *
 * Looks up the hash table named @key in @file.
 *
 * The toplevel hash table in a #GvdbTable can contain reference to
 * child hash tables (and those can contain further references...).
 *
 * If @key is not found in @file then %NULL is returned.  Otherwise, a
 * new #GvdbTable is returned, referring to the child hashtable as
 * contained in the file.  This newly-created #GvdbTable does not depend
 * on the continued existence of @file.
 *
 * You should call gvdb_table_free() on the return result when you no
 * longer require it.
 *
 * Returns: a new #GvdbTable, or %NULL
 **/
GvdbTable *
gvdb_table_get_table (GvdbTable   *file,
                      const gchar *key)
{
  const struct gvdb_hash_item *item;
  GvdbTable *new;

  item = gvdb_table_lookup (file, key, 'H');

  if (item == NULL)
    return NULL;

  new = g_slice_new0 (GvdbTable);
  new->bytes = g_bytes_ref (file->bytes);
  new->byteswapped = file->byteswapped;
  new->trusted = file->trusted;
  new->data = file->data;
  new->size = file->size;

  gvdb_table_setup_root (new, &item->value.pointer);

  return new;
}

/**
 * gvdb_table_free:
 * @file: a #GvdbTable
 *
 * Frees @file.
 **/
void
gvdb_table_free (GvdbTable *file)
{
  g_bytes_unref (file->bytes);
  g_slice_free (GvdbTable, file);
}

/**
 * gvdb_table_is_valid:
 * @table: a #GvdbTable
 *
 * Checks if the table is still valid.
 *
 * An on-disk GVDB can be marked as invalid.  This happens when the file
 * has been replaced.  The appropriate action is typically to reopen the
 * file.
 *
 * Returns: %TRUE if @table is still valid
 **/
gboolean
gvdb_table_is_valid (GvdbTable *table)
{
  return !!*table->data;
}
