/*
 * Copyright 2011 Collabora Ltd.
 *
 * This program 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.
 *
 * See the included COPYING file for more information.
 */

#undef G_DISABLE_ASSERT

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "glib.h"

/* Keep in sync with glib/gbytes.c */
struct _GBytes
{
  gconstpointer data;
  gsize size;
  gint ref_count;
  GDestroyNotify free_func;
  gpointer user_data;
};

static const gchar *NYAN = "nyannyan";
static const gsize N_NYAN = 8;

static void
test_new (void)
{
  const gchar *data;
  GBytes *bytes;
  gsize size;

  data = "test";
  bytes = g_bytes_new (data, 4);
  g_assert_nonnull (bytes);
  g_assert_true (g_bytes_get_data (bytes, &size) != data);
  g_assert_cmpuint (size, ==, 4);
  g_assert_cmpuint (g_bytes_get_size (bytes), ==, 4);
  g_assert_cmpmem (data, 4, g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes));

  g_bytes_unref (bytes);
}

static void
test_new_take (void)
{
  gchar *data;
  GBytes *bytes;
  gsize size;

  data = g_strdup ("test");
  bytes = g_bytes_new_take (data, 4);
  g_assert_nonnull (bytes);
  g_assert_true (g_bytes_get_data (bytes, &size) == data);
  g_assert_cmpuint (size, ==, 4);
  g_assert_cmpuint (g_bytes_get_size (bytes), ==, 4);

  g_bytes_unref (bytes);
}

static void
test_new_static (void)
{
  const gchar *data;
  GBytes *bytes;
  gsize size;

  data = "test";
  bytes = g_bytes_new_static (data, 4);
  g_assert_nonnull (bytes);
  g_assert_true (g_bytes_get_data (bytes, &size) == data);
  g_assert_cmpuint (size, ==, 4);
  g_assert_cmpuint (g_bytes_get_size (bytes), ==, 4);

  g_bytes_unref (bytes);
}

static void
test_new_from_bytes (void)
{
  const gchar *data = "smile and wave";
  GBytes *bytes;
  GBytes *sub;

  bytes = g_bytes_new (data, 14);
  sub = g_bytes_new_from_bytes (bytes, 10, 4);

  g_assert_nonnull (sub);
  g_assert_true (g_bytes_get_data (sub, NULL) == ((gchar *)g_bytes_get_data (bytes, NULL)) + 10);
  g_bytes_unref (bytes);

  g_assert_cmpmem (g_bytes_get_data (sub, NULL), g_bytes_get_size (sub), "wave", 4);
  g_bytes_unref (sub);
}

/* Verify that creating slices of GBytes reference the top-most bytes
 * at the correct offset. Ensure that intermediate GBytes are not referenced.
 */
static void
test_new_from_bytes_slice (void)
{
  GBytes *bytes = g_bytes_new_static ("Some stupid data", strlen ("Some stupid data") + 1);
  GBytes *bytes1 = g_bytes_new_from_bytes (bytes, 4, 13);
  GBytes *bytes2 = g_bytes_new_from_bytes (bytes1, 1, 12);
  GBytes *bytes3 = g_bytes_new_from_bytes (bytes2, 0, 6);

  g_assert_cmpint (bytes->ref_count, ==, 4);
  g_assert_cmpint (bytes1->ref_count, ==, 1);
  g_assert_cmpint (bytes2->ref_count, ==, 1);
  g_assert_cmpint (bytes3->ref_count, ==, 1);

  g_assert_null (bytes->user_data);
  g_assert_true (bytes1->user_data == bytes);
  g_assert_true (bytes2->user_data == bytes);
  g_assert_true (bytes3->user_data == bytes);

  g_assert_cmpint (17, ==, g_bytes_get_size (bytes));
  g_assert_cmpint (13, ==, g_bytes_get_size (bytes1));
  g_assert_cmpint (12, ==, g_bytes_get_size (bytes2));
  g_assert_cmpint (6, ==, g_bytes_get_size (bytes3));

  g_assert_cmpint (0, ==, strncmp ("Some stupid data", (gchar *)bytes->data, 17));
  g_assert_cmpint (0, ==, strncmp (" stupid data", (gchar *)bytes1->data, 13));
  g_assert_cmpint (0, ==, strncmp ("stupid data", (gchar *)bytes2->data, 12));
  g_assert_cmpint (0, ==, strncmp ("stupid", (gchar *)bytes3->data, 6));

  g_bytes_unref (bytes);
  g_bytes_unref (bytes1);
  g_bytes_unref (bytes2);
  g_bytes_unref (bytes3);
}

/* Ensure that referencing an entire GBytes just returns the same bytes
 * instance (with incremented reference count) instead of a new instance.
 */
static void
test_new_from_bytes_shared_ref (void)
{
  GBytes *bytes = g_bytes_new_static ("Some data", strlen ("Some data") + 1);
  GBytes *other = g_bytes_new_from_bytes (bytes, 0, g_bytes_get_size (bytes));

  g_assert_true (bytes == other);
  g_assert_cmpint (bytes->ref_count, ==, 2);

  g_bytes_unref (bytes);
  g_bytes_unref (other);
}

static void
on_destroy_increment (gpointer data)
{
  gint *count = data;
  g_assert_nonnull (count);
  (*count)++;
}

static void
test_new_with_free_func (void)
{
  GBytes *bytes;
  gchar *data;
  gint count = 0;
  gsize size;

  data = "test";
  bytes = g_bytes_new_with_free_func (data, 4, on_destroy_increment, &count);
  g_assert_nonnull (bytes);
  g_assert_cmpint (count, ==, 0);
  g_assert_true (g_bytes_get_data (bytes, &size) == data);
  g_assert_cmpuint (size, ==, 4);
  g_assert_cmpuint (g_bytes_get_size (bytes), ==, 4);

  g_bytes_unref (bytes);
  g_assert_cmpuint (count, ==, 1);
}

static void
test_hash (void)
{
  GBytes *bytes1;
  GBytes *bytes2;
  guint hash1;
  guint hash2;

  bytes1 = g_bytes_new ("blah", 4);
  bytes2 = g_bytes_new ("blah", 4);

  hash1 = g_bytes_hash (bytes1);
  hash2 = g_bytes_hash (bytes2);
  g_assert_cmpuint (hash1,  ==, hash2);

  g_bytes_unref (bytes1);
  g_bytes_unref (bytes2);
}

static void
test_equal (void)
{
  GBytes *bytes;
  GBytes *bytes2;

  bytes = g_bytes_new ("blah", 4);

  bytes2 = g_bytes_new ("blah", 4);
  g_assert_true (g_bytes_equal (bytes, bytes2));
  g_assert_true (g_bytes_equal (bytes2, bytes));
  g_bytes_unref (bytes2);

  bytes2 = g_bytes_new ("bla", 3);
  g_assert_false (g_bytes_equal (bytes, bytes2));
  g_assert_false (g_bytes_equal (bytes2, bytes));
  g_bytes_unref (bytes2);

  bytes2 = g_bytes_new ("true", 4);
  g_assert_false (g_bytes_equal (bytes, bytes2));
  g_assert_false (g_bytes_equal (bytes2, bytes));
  g_bytes_unref (bytes2);

  g_bytes_unref (bytes);
}

static void
test_compare (void)
{
  GBytes *bytes;
  GBytes *bytes2;

  bytes = g_bytes_new ("blah", 4);

  bytes2 = g_bytes_new ("blah", 4);
  g_assert_cmpint (g_bytes_compare (bytes, bytes2), ==, 0);
  g_bytes_unref (bytes2);

  bytes2 = g_bytes_new ("bla", 3);
  g_assert_cmpint (g_bytes_compare (bytes, bytes2), >, 0);
  g_bytes_unref (bytes2);

  bytes2 = g_bytes_new ("abcd", 4);
  g_assert_cmpint (g_bytes_compare (bytes, bytes2), >, 0);
  g_bytes_unref (bytes2);

  bytes2 = g_bytes_new ("blahblah", 8);
  g_assert_cmpint (g_bytes_compare (bytes, bytes2), <, 0);
  g_bytes_unref (bytes2);

  bytes2 = g_bytes_new ("zyx", 3);
  g_assert_cmpint (g_bytes_compare (bytes, bytes2), <, 0);
  g_bytes_unref (bytes2);

  bytes2 = g_bytes_new ("zyxw", 4);
  g_assert_cmpint (g_bytes_compare (bytes, bytes2), <, 0);
  g_bytes_unref (bytes2);

  g_bytes_unref (bytes);
}

static void
test_to_data_transferred (void)
{
  gconstpointer memory;
  gpointer data;
  gsize size;
  GBytes *bytes;

  /* Memory transferred: one reference, and allocated with g_malloc */
  bytes = g_bytes_new (NYAN, N_NYAN);
  memory = g_bytes_get_data (bytes, NULL);
  data = g_bytes_unref_to_data (bytes, &size);
  g_assert_true (data == memory);
  g_assert_cmpmem (data, size, NYAN, N_NYAN);
  g_free (data);
}

static void
test_to_data_two_refs (void)
{
  gconstpointer memory;
  gpointer data;
  gsize size;
  GBytes *bytes;

  /* Memory copied: two references */
  bytes = g_bytes_new (NYAN, N_NYAN);
  bytes = g_bytes_ref (bytes);
  memory = g_bytes_get_data (bytes, NULL);
  data = g_bytes_unref_to_data (bytes, &size);
  g_assert_true (data != memory);
  g_assert_cmpmem (data, size, NYAN, N_NYAN);
  g_free (data);
  g_assert_true (g_bytes_get_data (bytes, &size) == memory);
  g_assert_cmpuint (size, ==, N_NYAN);
  g_assert_cmpuint (g_bytes_get_size (bytes), ==, N_NYAN);
  g_bytes_unref (bytes);
}

static void
test_to_data_non_malloc (void)
{
  gpointer data;
  gsize size;
  GBytes *bytes;

  /* Memory copied: non malloc memory */
  bytes = g_bytes_new_static (NYAN, N_NYAN);
  g_assert_true (g_bytes_get_data (bytes, NULL) == NYAN);
  data = g_bytes_unref_to_data (bytes, &size);
  g_assert_true (data != (gpointer)NYAN);
  g_assert_cmpmem (data, size, NYAN, N_NYAN);
  g_free (data);
}

static void
test_to_data_different_free_func (void)
{
  gpointer data;
  gsize size;
  GBytes *bytes;
  gchar *sentinel = g_strdup ("hello");

  /* Memory copied: free func and user_data don’t point to the bytes data */
  bytes = g_bytes_new_with_free_func (NYAN, N_NYAN, g_free, sentinel);
  g_assert_true (g_bytes_get_data (bytes, NULL) == NYAN);

  data = g_bytes_unref_to_data (bytes, &size);
  g_assert_true (data != (gpointer)NYAN);
  g_assert_cmpmem (data, size, NYAN, N_NYAN);
  g_free (data);

  /* @sentinel should not be leaked; testing that requires this test to be run
   * under valgrind. We can’t use a custom free func to check it isn’t leaked,
   * as the point of this test is to hit a condition in `try_steal_and_unref()`
   * which is short-circuited if the free func isn’t g_free().
   * See discussion in https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2152 */
}

static void
test_to_array_transferred (void)
{
  gconstpointer memory;
  GByteArray *array;
  GBytes *bytes;

  /* Memory transferred: one reference, and allocated with g_malloc */
  bytes = g_bytes_new (NYAN, N_NYAN);
  memory = g_bytes_get_data (bytes, NULL);
  array = g_bytes_unref_to_array (bytes);
  g_assert_nonnull (array);
  g_assert_true (array->data == memory);
  g_assert_cmpmem (array->data, array->len, NYAN, N_NYAN);
  g_byte_array_unref (array);
}

static void
test_to_array_transferred_oversize (void)
{
  g_test_message ("g_bytes_unref_to_array() can only take GBytes up to "
                  "G_MAXUINT in length; test that longer ones are rejected");

  if (sizeof (guint) >= sizeof (gsize))
    {
      g_test_skip ("Skipping test as guint is not smaller than gsize");
    }
  else if (g_test_undefined ())
    {
      GByteArray *array = NULL;
      GBytes *bytes = NULL;
      gpointer data = g_memdup2 (NYAN, N_NYAN);
      gsize len = ((gsize) G_MAXUINT) + 1;

      bytes = g_bytes_new_take (data, len);
      g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
                             "g_byte_array_new_take: assertion 'len <= G_MAXUINT' failed");
      array = g_bytes_unref_to_array (g_steal_pointer (&bytes));
      g_test_assert_expected_messages ();
      g_assert_null (array);

      g_free (data);
    }
  else
    {
      g_test_skip ("Skipping test as testing undefined behaviour is disabled");
    }
}

static void
test_to_array_two_refs (void)
{
  gconstpointer memory;
  GByteArray *array;
  GBytes *bytes;
  gsize size;

  /* Memory copied: two references */
  bytes = g_bytes_new (NYAN, N_NYAN);
  bytes = g_bytes_ref (bytes);
  memory = g_bytes_get_data (bytes, NULL);
  array = g_bytes_unref_to_array (bytes);
  g_assert_nonnull (array);
  g_assert_true (array->data != memory);
  g_assert_cmpmem (array->data, array->len, NYAN, N_NYAN);
  g_byte_array_unref (array);
  g_assert_true (g_bytes_get_data (bytes, &size) == memory);
  g_assert_cmpuint (size, ==, N_NYAN);
  g_assert_cmpuint (g_bytes_get_size (bytes), ==, N_NYAN);
  g_bytes_unref (bytes);
}

static void
test_to_array_non_malloc (void)
{
  GByteArray *array;
  GBytes *bytes;

  /* Memory copied: non malloc memory */
  bytes = g_bytes_new_static (NYAN, N_NYAN);
  g_assert_true (g_bytes_get_data (bytes, NULL) == NYAN);
  array = g_bytes_unref_to_array (bytes);
  g_assert_nonnull (array);
  g_assert_true (array->data != (gpointer)NYAN);
  g_assert_cmpmem (array->data, array->len, NYAN, N_NYAN);
  g_byte_array_unref (array);
}

static void
test_null (void)
{
  GBytes *bytes;
  gpointer data;
  gsize size;

  bytes = g_bytes_new (NULL, 0);

  data = g_bytes_unref_to_data (bytes, &size);

  g_assert_null (data);
  g_assert_cmpuint (size, ==, 0);
}

static void
test_get_region (void)
{
  GBytes *bytes;

  bytes = g_bytes_new_static (NYAN, N_NYAN);

  /* simple valid gets at the start */
  g_assert_true (g_bytes_get_region (bytes, 1, 0, 1) == NYAN);
  g_assert_true (g_bytes_get_region (bytes, 1, 0, N_NYAN) == NYAN);

  /* an invalid get because the range is too wide */
  g_assert_true (g_bytes_get_region (bytes, 1, 0, N_NYAN + 1) == NULL);

  /* an valid get, but of a zero-byte range at the end */
  g_assert_true (g_bytes_get_region (bytes, 1, N_NYAN, 0) == NYAN + N_NYAN);

  /* not a valid get because it overlap ones byte */
  g_assert_true (g_bytes_get_region (bytes, 1, N_NYAN, 1) == NULL);

  /* let's try some multiplication overflow now */
  g_assert_true (g_bytes_get_region (bytes, 32, 0, G_MAXSIZE / 32 + 1) == NULL);
  g_assert_true (g_bytes_get_region (bytes, G_MAXSIZE / 32 + 1, 0, 32) == NULL);

  /* and some addition overflow */
  g_assert_true (g_bytes_get_region (bytes, 1, G_MAXSIZE, -G_MAXSIZE) == NULL);
  g_assert_true (g_bytes_get_region (bytes, 1, G_MAXSSIZE, ((gsize) G_MAXSSIZE) + 1) == NULL);
  g_assert_true (g_bytes_get_region (bytes, 1, G_MAXSIZE, 1) == NULL);

  g_bytes_unref (bytes);
}

static void
test_unref_null (void)
{
  g_test_summary ("Test that calling g_bytes_unref() on NULL is a no-op");
  g_bytes_unref (NULL);
}

int
main (int argc, char *argv[])
{
  g_test_init (&argc, &argv, NULL);

  g_test_add_func ("/bytes/new", test_new);
  g_test_add_func ("/bytes/new-take", test_new_take);
  g_test_add_func ("/bytes/new-static", test_new_static);
  g_test_add_func ("/bytes/new-with-free-func", test_new_with_free_func);
  g_test_add_func ("/bytes/new-from-bytes", test_new_from_bytes);
  g_test_add_func ("/bytes/new-from-bytes-slice", test_new_from_bytes_slice);
  g_test_add_func ("/bytes/new-from-bytes-shared-ref", test_new_from_bytes_shared_ref);
  g_test_add_func ("/bytes/hash", test_hash);
  g_test_add_func ("/bytes/equal", test_equal);
  g_test_add_func ("/bytes/compare", test_compare);
  g_test_add_func ("/bytes/to-data/transferred", test_to_data_transferred);
  g_test_add_func ("/bytes/to-data/two-refs", test_to_data_two_refs);
  g_test_add_func ("/bytes/to-data/non-malloc", test_to_data_non_malloc);
  g_test_add_func ("/bytes/to-data/different-free-func", test_to_data_different_free_func);
  g_test_add_func ("/bytes/to-array/transferred", test_to_array_transferred);
  g_test_add_func ("/bytes/to-array/transferred/oversize", test_to_array_transferred_oversize);
  g_test_add_func ("/bytes/to-array/two-refs", test_to_array_two_refs);
  g_test_add_func ("/bytes/to-array/non-malloc", test_to_array_non_malloc);
  g_test_add_func ("/bytes/null", test_null);
  g_test_add_func ("/bytes/get-region", test_get_region);
  g_test_add_func ("/bytes/unref-null", test_unref_null);

  return g_test_run ();
}
