/* Regression test for DBusVariant
 *
 * Copyright © 2017 Collabora Ltd.
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation files
 * (the "Software"), to deal in the Software without restriction,
 * including without limitation the rights to use, copy, modify, merge,
 * publish, distribute, sublicense, and/or sell copies of the Software,
 * and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include <config.h>

#include <string.h>

#include <glib.h>
#include <glib-object.h>

#include <dbus/dbus.h>
#include <dbus/dbus-internals.h>
#include <dbus/dbus-string.h>
#include <dbus/dbus-message-internal.h>
#include "test-utils-glib.h"

typedef struct
{
  DBusMessage *original;
  DBusMessage *copy;
} Fixture;

/* Return TRUE on success, FALSE on OOM, abort on failure. */
static gboolean
setup (Fixture *f)
{
  dbus_int32_t fortytwo = 42;
  dbus_int64_t twentythree = 23;
  const char *s = "Hello, world!";
  DBusMessageIter iter;
  DBusMessageIter arr_iter;
  DBusMessageIter struct_iter;
  DBusMessageIter pair_iter;

  f->original = dbus_message_new_signal ("/", "a.b", "c");

  if (f->original == NULL)
    return FALSE;

  /* It ends up as:
   * (
   *  int32 42,
   *  "Hello, world!",
   *  int64 23,
   *  [int32 42, int32 42],
   *  (int32 42, "Hello, world!", int64 23),
   *  {int32 42: int64 23},
   * )
   */

  if (!dbus_message_append_args (f->original,
                                 DBUS_TYPE_INT32, &fortytwo,
                                 DBUS_TYPE_STRING, &s,
                                 DBUS_TYPE_INT64, &twentythree,
                                 DBUS_TYPE_INVALID))
    return FALSE;

  dbus_message_iter_init_append (f->original, &iter);

  if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY,
                                         DBUS_TYPE_INT32_AS_STRING, &arr_iter))
    return FALSE;

  {
    if (!dbus_message_iter_append_basic (&arr_iter, DBUS_TYPE_INT32, &fortytwo) ||
        !dbus_message_iter_append_basic (&arr_iter, DBUS_TYPE_INT32, &fortytwo))
      {
        dbus_message_iter_abandon_container (&iter, &arr_iter);
        return FALSE;
      }
  }

  if (!dbus_message_iter_close_container (&iter, &arr_iter))
    return FALSE;

  if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_STRUCT, NULL,
                                         &struct_iter))
    return FALSE;

  {
    if (!dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_INT32,
                                         &fortytwo) ||
        !dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_STRING, &s) ||
        !dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_INT64,
                                         &twentythree))
      {
        dbus_message_iter_abandon_container (&iter, &struct_iter);
        return FALSE;
      }
  }

  if (!dbus_message_iter_close_container (&iter, &struct_iter))
    return FALSE;

  if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "{ix}",
                                         &arr_iter))
    return FALSE;

  {
    if (!dbus_message_iter_open_container (&arr_iter, DBUS_TYPE_DICT_ENTRY,
                                           NULL, &pair_iter))
      {
        dbus_message_iter_abandon_container (&iter, &arr_iter);
        return FALSE;
      }

    {
      if (!dbus_message_iter_append_basic (&pair_iter, DBUS_TYPE_INT32,
                                           &fortytwo) ||
          !dbus_message_iter_append_basic (&pair_iter, DBUS_TYPE_INT64,
                                           &twentythree))
        {
          dbus_message_iter_abandon_container (&arr_iter, &pair_iter);
          dbus_message_iter_abandon_container (&iter, &arr_iter);
          return FALSE;
        }
    }

    if (!dbus_message_iter_close_container (&arr_iter, &pair_iter))
      {
        dbus_message_iter_abandon_container (&iter, &arr_iter);
        return FALSE;
      }
  }

  if (!dbus_message_iter_close_container (&iter, &arr_iter))
    return FALSE;

  return TRUE;
}

/* Assert that item_iter points to an int32 equal to expected_value.
 * Copy it into a DBusVariant and assert that the copy is done correctly.
 * Return TRUE on success, FALSE if libdbus pretends to run out of memory,
 * or abort on failure. */
static gboolean
assert_int32 (DBusMessageIter *item_iter,
              dbus_int32_t expected_value)
{
  DBusVariant *v;
  const DBusString *s;
  const void *value_p;
  dbus_int32_t value;

  g_assert_cmpint (dbus_message_iter_get_arg_type (item_iter), ==,
                   DBUS_TYPE_INT32);
  dbus_message_iter_get_basic (item_iter, &value);
  g_assert_cmpint (value, ==, expected_value);

  v = _dbus_variant_read (item_iter);

  if (v == NULL)
    return FALSE;

  s = _dbus_variant_peek (v);
  g_assert (s != NULL);
  g_assert_cmpstr (_dbus_variant_get_signature (v), ==,
                   DBUS_TYPE_INT32_AS_STRING);

  /* Variant serialization of <int32 something> at offset 0:
   * 01 'i' 00                  signature
   *           00               padding
   *               vv vv vv vv  bytes of value
   */
  g_assert_cmpint (_dbus_variant_get_length (v), ==, 8);
  g_assert_cmpint (_dbus_string_get_length (s), ==, 8);
  g_assert_cmpint (_dbus_string_get_byte (s, 0), ==, 1);
  g_assert_cmpint (_dbus_string_get_byte (s, 1), ==, DBUS_TYPE_INT32);
  g_assert_cmpint (_dbus_string_get_byte (s, 2), ==, '\0');
  g_assert_cmpint (_dbus_string_get_byte (s, 3), ==, 0); /* padding */
  value_p = _dbus_string_get_const_data_len (s, 4, 4);
  memcpy (&value, value_p, 4);
  g_assert_cmpint (value, ==, expected_value);

  _dbus_variant_free (v);
  return TRUE;
}

/* Assert that item_iter points to an int64 equal to expected_value.
 * Copy it into a DBusVariant and assert that the copy is done correctly.
 * Return TRUE on success, FALSE if libdbus pretends to run out of memory,
 * or abort on failure. */
static gboolean
assert_int64 (DBusMessageIter *item_iter,
              dbus_int64_t expected_value)
{
  DBusVariant *v;
  const DBusString *s;
  const void *value_p;
  dbus_int64_t value;
  int i;

  g_assert_cmpint (dbus_message_iter_get_arg_type (item_iter), ==,
                   DBUS_TYPE_INT64);
  dbus_message_iter_get_basic (item_iter, &value);
  g_assert_cmpint (value, ==, expected_value);

  v = _dbus_variant_read (item_iter);

  if (v == NULL)
    return FALSE;

  s = _dbus_variant_peek (v);
  g_assert (s != NULL);
  g_assert_cmpstr (_dbus_variant_get_signature (v), ==,
                   DBUS_TYPE_INT64_AS_STRING);

  /* Variant serialization of <int64 something> at offset 0:
   * 01 'i' 00                  signature
   *          00  00 00 00 00  padding
   * vv vv vv vv  vv vv vv vv  bytes of value
   */
  g_assert_cmpint (_dbus_variant_get_length (v), ==, 16);
  g_assert_cmpint (_dbus_string_get_length (s), ==, 16);
  g_assert_cmpint (_dbus_string_get_byte (s, 0), ==, 1);
  g_assert_cmpint (_dbus_string_get_byte (s, 1), ==, DBUS_TYPE_INT64);
  g_assert_cmpint (_dbus_string_get_byte (s, 2), ==, '\0');

  for (i = 3; i < 8; i++)
    g_assert_cmpint (_dbus_string_get_byte (s, i), ==, 0); /* padding */

  value_p = _dbus_string_get_const_data_len (s, 8, 8);
  memcpy (&value, value_p, 8);
  g_assert_cmpint (value, ==, expected_value);

  _dbus_variant_free (v);
  return TRUE;
}

/* Assert that item_iter points to a string equal to expected_value.
 * Copy it into a DBusVariant and assert that the copy is done correctly.
 * Return TRUE on success, FALSE if libdbus pretends to run out of memory,
 * or abort on failure. */
static gboolean
assert_string (DBusMessageIter *item_iter,
               const char *expected_value)
{
  DBusVariant *v;
  const DBusString *s;
  const char *value;
  dbus_int32_t length;

  g_assert_cmpint (dbus_message_iter_get_arg_type (item_iter), ==,
                   DBUS_TYPE_STRING);
  dbus_message_iter_get_basic (item_iter, &value);
  g_assert_cmpstr (value, ==, expected_value);

  v = _dbus_variant_read (item_iter);

  if (v == NULL)
    return FALSE;

  s = _dbus_variant_peek (v);
  g_assert (s != NULL);
  g_assert_cmpstr (_dbus_variant_get_signature (v), ==,
                   DBUS_TYPE_STRING_AS_STRING);

  /* Variant serialization of <"something"> at offset 0:
   * 01 's' 00                  signature
   *          00                padding
   *              ll ll ll ll   bytes of length excluding \0
   * vv vv vv ... 00            bytes of value
   */
  g_assert_cmpint (_dbus_variant_get_length (v), ==,
                   (int) strlen (expected_value) + 9);
  g_assert_cmpint (_dbus_string_get_length (s), ==,
                   _dbus_variant_get_length (v));
  g_assert_cmpint (_dbus_string_get_byte (s, 0), ==, 1);
  g_assert_cmpint (_dbus_string_get_byte (s, 1), ==, DBUS_TYPE_STRING);
  g_assert_cmpint (_dbus_string_get_byte (s, 2), ==, '\0');
  g_assert_cmpint (_dbus_string_get_byte (s, 3), ==, 0); /* padding */

  value = _dbus_string_get_const_data_len (s, 4, 4);
  memcpy (&length, value, 4);
  g_assert_cmpuint (length, ==, (int) strlen (expected_value));
  value = _dbus_string_get_const_data_len (s, 8, length + 1);
  g_assert_cmpstr (value, ==, expected_value);

  _dbus_variant_free (v);
  return TRUE;
}

/* Assert that item_iter points to an array of n_values repetitions of the
 * int32 expected_value. Copy it into a DBusVariant and assert that the
 * copy is done correctly.
 * Return TRUE on success, FALSE if libdbus pretends to run out of memory,
 * or abort on failure. */
static gboolean
assert_array_of_int32 (DBusMessageIter *item_iter,
                       int n_values,
                       dbus_int32_t expected_value)
{
  DBusMessageIter arr_iter;
  DBusVariant *v;
  const DBusString *s;
  const void *value_p;
  dbus_int32_t value;
  int i;

  g_assert_cmpint (dbus_message_iter_get_arg_type (item_iter), ==,
                   DBUS_TYPE_ARRAY);

  dbus_message_iter_recurse (item_iter, &arr_iter);

  for (i = 0; i < n_values; i++)
    {
      assert_int32 (&arr_iter, expected_value);

      if (i == n_values - 1)
        g_assert_false (dbus_message_iter_next (&arr_iter));
      else
        g_assert_true (dbus_message_iter_next (&arr_iter));
    }

  v = _dbus_variant_read (item_iter);

  if (v == NULL)
    return FALSE;

  s = _dbus_variant_peek (v);
  g_assert (s != NULL);
  g_assert_cmpstr (_dbus_variant_get_signature (v), ==,
                   DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_INT32_AS_STRING);

  /* Variant serialization of <[int32 something, ...]> at offset 0:
   * 02 'a' 'i' 00              signature
   *               ll ll ll ll  total number of bytes in values
   * vv vv vv vv   ...          bytes of values
   */
  g_assert_cmpint (_dbus_variant_get_length (v), ==, 8 + (4 * n_values));
  g_assert_cmpint (_dbus_string_get_length (s), ==, 8 + (4 * n_values));
  g_assert_cmpint (_dbus_string_get_byte (s, 0), ==, 2);
  g_assert_cmpint (_dbus_string_get_byte (s, 1), ==, DBUS_TYPE_ARRAY);
  g_assert_cmpint (_dbus_string_get_byte (s, 2), ==, DBUS_TYPE_INT32);
  g_assert_cmpint (_dbus_string_get_byte (s, 3), ==, '\0');
  value_p = _dbus_string_get_const_data_len (s, 4, 4);
  memcpy (&value, value_p, 4);
  g_assert_cmpint (value, ==, n_values * 4);

  for (i = 0; i < n_values; i++)
    {
      value_p = _dbus_string_get_const_data_len (s, 8 + (4 * (n_values - 1)),
                                                 4);
      memcpy (&value, value_p, 4);
      g_assert_cmpint (value, ==, expected_value);
    }

  _dbus_variant_free (v);
  return TRUE;
}

/* Assert that m is (in GVariant notation):
 * (
 *  int32 42,
 *  "Hello, world!",
 *  int64 23,
 *  [int32 42, int32 42],
 *  (int32 42, "Hello, world!", int64 23),
 *  {int32 42: int64 23},
 * )
 *
 * Serialize some of those values into DBusVariants and assert that it is
 * done correctly.
 *
 * Return TRUE on success, FALSE if libdbus pretends to run out of memory,
 * or abort on failure. */
static gboolean
assert_message_as_expected (DBusMessage *m)
{
  DBusMessageIter item_iter;
  DBusMessageIter arr_iter;
  DBusMessageIter struct_iter;
  DBusMessageIter pair_iter;

  g_assert_cmpstr (dbus_message_get_signature (m), ==, "isxai(isx)a{ix}");
  dbus_message_iter_init (m, &item_iter);

  {
    if (!assert_int32 (&item_iter, 42))
      return FALSE;

    g_assert_true (dbus_message_iter_next (&item_iter));

    if (!assert_string (&item_iter, "Hello, world!"))
      return FALSE;

    g_assert_true (dbus_message_iter_next (&item_iter));

    if (!assert_int64 (&item_iter, 23))
      return FALSE;

    g_assert_true (dbus_message_iter_next (&item_iter));

    g_assert_cmpint (dbus_message_iter_get_arg_type (&item_iter), ==,
                     DBUS_TYPE_ARRAY);
    if (!assert_array_of_int32 (&item_iter, 2, 42))
      return FALSE;

    g_assert_true (dbus_message_iter_next (&item_iter));

    g_assert_cmpint (dbus_message_iter_get_arg_type (&item_iter), ==,
                     DBUS_TYPE_STRUCT);
    dbus_message_iter_recurse (&item_iter, &struct_iter);

    {
      if (!assert_int32 (&struct_iter, 42))
        return FALSE;

      g_assert_true (dbus_message_iter_next (&struct_iter));

      if (!assert_string (&struct_iter, "Hello, world!"))
        return FALSE;

      g_assert_true (dbus_message_iter_next (&struct_iter));

      if (!assert_int64 (&struct_iter, 23))
        return FALSE;

      g_assert_false (dbus_message_iter_next (&struct_iter));
    }

    g_assert_true (dbus_message_iter_next (&item_iter));

    g_assert_cmpint (dbus_message_iter_get_arg_type (&item_iter), ==,
                     DBUS_TYPE_ARRAY);
    dbus_message_iter_recurse (&item_iter, &arr_iter);

    {
      g_assert_cmpint (dbus_message_iter_get_arg_type (&arr_iter), ==,
                       DBUS_TYPE_DICT_ENTRY);
      dbus_message_iter_recurse (&arr_iter, &pair_iter);

      {
        if (!assert_int32 (&pair_iter, 42))
          return FALSE;

        g_assert_true (dbus_message_iter_next (&pair_iter));

        if (!assert_int64 (&pair_iter, 23))
          return FALSE;

        g_assert_false (dbus_message_iter_next (&pair_iter));
      }

      g_assert_false (dbus_message_iter_next (&arr_iter));
    }
  }

  g_assert_false (dbus_message_iter_next (&item_iter));
  return TRUE;
}

/* Return TRUE on success or OOM, as per DBusTestMemoryFunction signature */
static dbus_bool_t
test_once (void *data)
{
  gboolean *really_succeeded = data;
  Fixture fixture = { NULL, NULL };
  Fixture *f = &fixture;
  DBusMessageIter item_iter;
  DBusMessageIter appender;
  int i;

  if (really_succeeded != NULL)
    *really_succeeded = FALSE;

  if (!setup (f))
    goto out;

  if (!assert_message_as_expected (f->original))
    goto out;

  dbus_message_iter_init (f->original, &item_iter);

  f->copy = dbus_message_new_signal ("/", "a.b", "c");

  if (f->copy == NULL)
    goto out;

  dbus_message_iter_init_append (f->copy, &appender);

  for (i = 0; i < 6; i++)
    {
      DBusVariant *var = _dbus_variant_read (&item_iter);

      if (var == NULL)
        goto out;

      if (!_dbus_variant_write (var, &appender))
        {
          _dbus_variant_free (var);
          goto out;
        }

      _dbus_variant_free (var);

      if (i == 5)
        g_assert_false (dbus_message_iter_next (&item_iter));
      else
        g_assert_true (dbus_message_iter_next (&item_iter));
    }

  if (!assert_message_as_expected (f->copy))
    goto out;

  if (really_succeeded != NULL)
    *really_succeeded = TRUE;
out:
  if (f->original)
    dbus_message_unref (f->original);

  if (f->copy)
    dbus_message_unref (f->copy);

  dbus_shutdown ();
  g_assert_cmpint (_dbus_get_malloc_blocks_outstanding (), ==, 0);

  return !g_test_failed ();
}

static void
test_simple (void)
{
  gboolean really_succeeded = FALSE;

  if (!test_once (&really_succeeded))
    g_error ("Test failed");

  if (!really_succeeded)
    g_error ("Out of memory");
}

static void
test_oom (void)
{
  if (!_dbus_test_oom_handling ("DBusVariant", test_once, NULL))
    g_error ("Test failed");
}

int
main (int argc,
      char **argv)
{
  test_init (&argc, &argv);

  g_test_add_func ("/variant/simple", test_simple);
  g_test_add_func ("/variant/oom", test_oom);

  return g_test_run ();
}
