/*
 * 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_from_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_from_inert (void)
{
  return NULL;
}

static void *
create_set (void)
{
  return hb_set_create ();
}
static void *
create_set_from_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_from_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_from_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_from_inert (void)
{
  return NULL;
}

static void *
create_unicode_funcs (void)
{
  return hb_unicode_funcs_create (NULL);
}
static void *
create_unicode_funcs_from_inert (void)
{
  return hb_unicode_funcs_create (hb_unicode_funcs_get_empty ());
}



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_from_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##_from_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##_from_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_WITHOUT_IMMUTABILITY (set),
  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[1000] = {{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_from_inert()");
      obj = o->create_from_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);

      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 ();
}
