/*
 * Copyright © 2011  Google, Inc.
 *
 *  This is part of HarfBuzz, a text shaping library.
 *
 * Permission is hereby granted, without written agreement and without
 * license or royalty fees, to use, copy, modify, and distribute this
 * software and its documentation for any purpose, provided that the
 * above copyright notice and the following two paragraphs appear in
 * all copies of this software.
 *
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 *
 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 *
 * Google Author(s): Behdad Esfahbod
 */

#include "hb-test.h"

/* Unit tests for hb-object-private.h */


static void *
create_blob (void)
{
  static char data[] = "test data";
  return hb_blob_create (data, sizeof (data), HB_MEMORY_MODE_READONLY, NULL, NULL);
}
static void *
create_blob_inert (void)
{
  return hb_blob_create (NULL, 0, HB_MEMORY_MODE_DUPLICATE, NULL, NULL);
}

static void *
create_buffer (void)
{
  return hb_buffer_create ();
}
static void *
create_buffer_inert (void)
{
  return NULL;
}

static void *
create_face (void)
{
  hb_blob_t *blob = (hb_blob_t *) create_blob ();
  hb_face_t *face = hb_face_create (blob, 0);
  hb_blob_destroy (blob);
  return face;
}
static void *
create_face_inert (void)
{
  return hb_face_create (hb_blob_get_empty (), 0);
}

static void *
create_font (void)
{
  hb_face_t *face = (hb_face_t *) create_face ();
  hb_font_t *font = hb_font_create (face);
  hb_face_destroy (face);
  return font;
}
static void *
create_font_inert (void)
{
  return hb_font_create (hb_face_get_empty ());
}

static void *
create_font_funcs (void)
{
  return hb_font_funcs_create ();
}
static void *
create_font_funcs_inert (void)
{
  return NULL;
}

static void *
create_unicode_funcs (void)
{
  return hb_unicode_funcs_create (NULL);
}
static void *
create_unicode_funcs_inert (void)
{
  return hb_unicode_funcs_get_default ();
}



typedef void     *(*create_func_t)         (void);
typedef void     *(*reference_func_t)      (void *obj);
typedef void      (*destroy_func_t)        (void *obj);
typedef hb_bool_t (*set_user_data_func_t)  (void *obj, hb_user_data_key_t *key, void *data, hb_destroy_func_t destroy, hb_bool_t replace);
typedef void *    (*get_user_data_func_t)  (void *obj, hb_user_data_key_t *key);
typedef void      (*make_immutable_func_t) (void *obj);
typedef hb_bool_t (*is_immutable_func_t)   (void *obj);

typedef struct {
  create_func_t          create;
  create_func_t          create_inert;
  create_func_t          get_empty;
  reference_func_t       reference;
  destroy_func_t         destroy;
  set_user_data_func_t   set_user_data;
  get_user_data_func_t   get_user_data;
  make_immutable_func_t  make_immutable;
  is_immutable_func_t    is_immutable;
  const char            *name;
} object_t;

#define OBJECT_WITHOUT_IMMUTABILITY(name) \
  { \
    (create_func_t)         create_##name, \
    (create_func_t)         create_##name##_inert, \
    (create_func_t)         hb_##name##_get_empty, \
    (reference_func_t)      hb_##name##_reference, \
    (destroy_func_t)        hb_##name##_destroy, \
    (set_user_data_func_t)  hb_##name##_set_user_data, \
    (get_user_data_func_t)  hb_##name##_get_user_data, \
    (make_immutable_func_t) NULL, \
    (is_immutable_func_t)   NULL, \
    #name, \
  }
#define OBJECT_WITH_IMMUTABILITY(name) \
  { \
    (create_func_t)         create_##name, \
    (create_func_t)         create_##name##_inert, \
    (create_func_t)         hb_##name##_get_empty, \
    (reference_func_t)      hb_##name##_reference, \
    (destroy_func_t)        hb_##name##_destroy, \
    (set_user_data_func_t)  hb_##name##_set_user_data, \
    (get_user_data_func_t)  hb_##name##_get_user_data, \
    (make_immutable_func_t) hb_##name##_make_immutable, \
    (is_immutable_func_t)   hb_##name##_is_immutable, \
    #name, \
  }
static const object_t objects[] =
{
  OBJECT_WITHOUT_IMMUTABILITY (buffer),
  OBJECT_WITH_IMMUTABILITY (blob),
  OBJECT_WITH_IMMUTABILITY (face),
  OBJECT_WITH_IMMUTABILITY (font),
  OBJECT_WITH_IMMUTABILITY (font_funcs),
  OBJECT_WITH_IMMUTABILITY (unicode_funcs)
};
#undef OBJECT


#define MAGIC0 0x12345678
#define MAGIC1 0x76543210

typedef struct {
  int value;
  gboolean freed;
} data_t;

static int global_data;

static void global_free_up (void *p G_GNUC_UNUSED)
{
  global_data++;
}

static void free_up0 (void *p)
{
  data_t *data = (data_t *) p;

  g_assert_cmphex (data->value, ==, MAGIC0);
  g_assert (!data->freed);
  data->freed = TRUE;
}

static void free_up1 (void *p)
{
  data_t *data = (data_t *) p;

  g_assert_cmphex (data->value, ==, MAGIC1);
  g_assert (!data->freed);
  data->freed = TRUE;
}


typedef struct {
  const object_t *klass;
  void *object;
  hb_user_data_key_t key;
} deadlock_test_t;

static void free_deadlock_test (void *p)
{
  deadlock_test_t *t = (deadlock_test_t *) p;

  g_assert (NULL == t->klass->get_user_data (t->object, &t->key));
}


static void
test_object (void)
{
  unsigned int i;

  for (i = 0; i < G_N_ELEMENTS (objects); i++) {
    const object_t *o = &objects[i];
    void *obj;
    hb_user_data_key_t key[1001];

    {
      unsigned int j;
      data_t data[2] = {{MAGIC0, FALSE}, {MAGIC1, FALSE}};
      deadlock_test_t deadlock_test;

      g_test_message ("Testing object %s", o->name);

      g_test_message ("->create()");
      obj = o->create ();
      g_assert (obj);

      g_assert (obj == o->reference (obj));
      o->destroy (obj);

      if (o->is_immutable)
	g_assert (!o->is_immutable (obj));

      g_assert (o->set_user_data (obj, &key[0], &data[0], free_up0, TRUE));
      g_assert (o->get_user_data (obj, &key[0]) == &data[0]);

      if (o->is_immutable) {
	o->make_immutable (obj);
	g_assert (o->is_immutable (obj));
      }

      /* Should still work even if object is made immutable */
      g_assert (o->set_user_data (obj, &key[1], &data[1], free_up1, TRUE));
      g_assert (o->get_user_data (obj, &key[1]) == &data[1]);

      g_assert (!o->set_user_data (obj, NULL, &data[0], free_up0, TRUE));
      g_assert (o->get_user_data (obj, &key[0]) == &data[0]);
      g_assert (o->set_user_data (obj, &key[0], &data[1], NULL, TRUE));
      g_assert (data[0].freed);
      g_assert (o->get_user_data (obj, &key[0]) == &data[1]);
      g_assert (!data[1].freed);

      data[0].freed = FALSE;
      g_assert (o->set_user_data (obj, &key[0], &data[0], free_up0, TRUE));
      g_assert (!data[0].freed);
      g_assert (o->set_user_data (obj, &key[0], NULL, NULL, TRUE));
      g_assert (data[0].freed);

      data[0].freed = FALSE;
      global_data = 0;
      g_assert (o->set_user_data (obj, &key[0], &data[0], free_up0, TRUE));
      g_assert (!o->set_user_data (obj, &key[0], &data[0], free_up0, FALSE));
      g_assert_cmpuint (global_data, ==, 0);
      g_assert (o->set_user_data (obj, &key[0], NULL, global_free_up, TRUE));
      g_assert_cmpuint (global_data, ==, 0);
      g_assert (o->set_user_data (obj, &key[0], NULL, NULL, TRUE));
      g_assert_cmpuint (global_data, ==, 1);

      global_data = 0;
      for (j = 2; j < 1000; j++)
	g_assert (o->set_user_data (obj, &key[j], &data[j], global_free_up, TRUE));
      for (j = 2; j < 1000; j++)
	g_assert (o->get_user_data (obj, &key[j]) == &data[j]);
      for (j = 100; j < 1000; j++)
	g_assert (o->set_user_data (obj, &key[j], NULL, NULL, TRUE));
      for (j = 2; j < 100; j++)
	g_assert (o->get_user_data (obj, &key[j]) == &data[j]);
      for (j = 100; j < 1000; j++)
	g_assert (!o->get_user_data (obj, &key[j]));
      g_assert_cmpuint (global_data, ==, 900);

      /* Test set_user_data where the destroy() func calls user_data functions.
       * Make sure it doesn't deadlock or corrupt memory. */
      deadlock_test.klass = o;
      deadlock_test.object = obj;
      g_assert (o->set_user_data (obj, &deadlock_test.key, &deadlock_test, free_deadlock_test, TRUE));
      g_assert (o->set_user_data (obj, &deadlock_test.key, NULL, NULL, TRUE));

      g_assert (!data[1].freed);
      o->destroy (obj);
      g_assert (data[0].freed);
      g_assert (data[1].freed);
      g_assert_cmpuint (global_data, ==, 1000-2);
    }

    {
      data_t data[2] = {{MAGIC0, FALSE}, {MAGIC1, FALSE}};

      g_test_message ("->get_empty()");
      obj = o->get_empty ();
      g_assert (obj);

      g_assert (obj == o->reference (obj));
      o->destroy (obj);

      if (o->is_immutable)
	g_assert (o->is_immutable (obj));

      g_assert (!o->set_user_data (obj, &key[0], &data[0], free_up0, TRUE));
      g_assert (!o->get_user_data (obj, &key[0]));

      o->destroy (obj);
      o->destroy (obj);
      o->destroy (obj);
      o->destroy (obj);
      o->destroy (obj);

      g_assert (!data[0].freed);
    }

    {
      data_t data[2] = {{MAGIC0, FALSE}, {MAGIC1, FALSE}};

      g_test_message ("->create_inert()");
      obj = o->create_inert ();
      if (!obj)
	continue;
      if (obj == o->get_empty ())
        continue; /* Tested already */

      g_assert (obj == o->reference (obj));
      o->destroy (obj);

      if (o->is_immutable)
	g_assert (o->is_immutable (obj));

      g_assert (!o->set_user_data (obj, &key[0], &data[0], free_up0, TRUE));
      g_assert (!o->get_user_data (obj, &key[0]));

      o->destroy (obj);
      o->destroy (obj);
      o->destroy (obj);
      o->destroy (obj);
      o->destroy (obj);

      g_assert (!data[0].freed);
    }
  }
}


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

  hb_test_add (test_object);

  return hb_test_run ();
}
