/* GStreamer
 *
 * unit test for GstMiniObject
 *
 * Copyright (C) <2005> Thomas Vander Stichele <thomas at apestaart dot org>
 * Copyright (C) <2005> Tim-Philipp Müller <tim centricular net>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include <gst/check/gstcheck.h>

GST_START_TEST (test_copy)
{
  GstBuffer *buffer, *copy;

  buffer = gst_buffer_new_and_alloc (4);

  copy = GST_BUFFER (gst_mini_object_copy (GST_MINI_OBJECT_CAST (buffer)));

  fail_if (copy == NULL, "Copy of buffer returned NULL");
  fail_unless (gst_buffer_get_size (copy) == 4,
      "Copy of buffer has different size");

  gst_buffer_unref (buffer);
  gst_buffer_unref (copy);
}

GST_END_TEST;

GST_START_TEST (test_is_writable)
{
  GstBuffer *buffer;
  GstMiniObject *mobj;

  buffer = gst_buffer_new_and_alloc (4);
  mobj = GST_MINI_OBJECT_CAST (buffer);

  fail_unless (gst_mini_object_is_writable (mobj),
      "A buffer with one ref should be writable");

  fail_if (gst_mini_object_ref (mobj) == NULL, "Could not ref the mobj");

  fail_if (gst_mini_object_is_writable (mobj),
      "A buffer with two refs should not be writable");

  gst_buffer_unref (buffer);
  gst_mini_object_unref (mobj);
}

GST_END_TEST;

GST_START_TEST (test_make_writable)
{
  GstBuffer *buffer;
  GstMiniObject *mobj, *mobj2, *mobj3;

  buffer = gst_buffer_new_and_alloc (4);
  mobj = GST_MINI_OBJECT_CAST (buffer);

  mobj2 = gst_mini_object_make_writable (mobj);
  fail_unless (GST_IS_BUFFER (mobj2), "make_writable did not return a buffer");
  fail_unless (mobj == mobj2,
      "make_writable returned a copy for a buffer with refcount 1");

  mobj2 = gst_mini_object_ref (mobj);
  mobj3 = gst_mini_object_make_writable (mobj);
  fail_unless (GST_IS_BUFFER (mobj3), "make_writable did not return a buffer");
  fail_if (mobj == mobj3,
      "make_writable returned same object for a buffer with refcount > 1");

  fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (mobj) == 1,
      "refcount of original mobj object should be back to 1");

  mobj2 = gst_mini_object_make_writable (mobj);
  fail_unless (GST_IS_BUFFER (mobj2), "make_writable did not return a buffer");
  fail_unless (mobj == mobj2,
      "make_writable returned a copy for a buffer with refcount 1");

  gst_buffer_unref (buffer);
  gst_mini_object_unref (mobj3);
}

GST_END_TEST;

static gint num_threads = 10;
static gint refs_per_thread = 10000;

/* test thread-safe refcounting of GstMiniObject */
static void
thread_ref (GstMiniObject * mobj)
{
  int j;

  THREAD_START ();

  for (j = 0; j < refs_per_thread; ++j) {
    gst_mini_object_ref (mobj);

    if (j % num_threads == 0)
      THREAD_SWITCH ();
  }
  GST_DEBUG ("thread stopped");
}

GST_START_TEST (test_ref_threaded)
{
  GstBuffer *buffer;
  GstMiniObject *mobj;
  gint expected;

  buffer = gst_buffer_new_and_alloc (4);

  mobj = GST_MINI_OBJECT_CAST (buffer);

  MAIN_START_THREADS (num_threads, thread_ref, mobj);

  MAIN_STOP_THREADS ();

  expected = num_threads * refs_per_thread + 1;
  ASSERT_MINI_OBJECT_REFCOUNT (mobj, "miniobject", expected);

  while (expected-- != 0)
    gst_buffer_unref (buffer);
}

GST_END_TEST;

static void
thread_unref (GstMiniObject * mobj)
{
  int j;

  THREAD_START ();

  for (j = 0; j < refs_per_thread; ++j) {
    gst_mini_object_unref (mobj);

    if (j % num_threads == 0)
      THREAD_SWITCH ();
  }
}

GST_START_TEST (test_unref_threaded)
{
  GstBuffer *buffer;
  GstMiniObject *mobj;
  int i;

  buffer = gst_buffer_new_and_alloc (4);

  mobj = GST_MINI_OBJECT (buffer);

  for (i = 0; i < num_threads * refs_per_thread; ++i)
    gst_mini_object_ref (mobj);

  MAIN_START_THREADS (num_threads, thread_unref, mobj);

  MAIN_STOP_THREADS ();

  ASSERT_MINI_OBJECT_REFCOUNT (mobj, "miniobject", 1);

  /* final unref */
  gst_mini_object_unref (mobj);
}

GST_END_TEST;

/* ======== weak ref test ======== */

static gboolean weak_ref_notify_succeeded = FALSE;

static void
on_weak_ref_notify (gpointer data, GstMiniObject * where_object_was)
{
  weak_ref_notify_succeeded = TRUE;
}

GST_START_TEST (test_weak_ref)
{
  GstBuffer *buffer;

  buffer = gst_buffer_new_and_alloc (4);

  gst_mini_object_weak_ref (GST_MINI_OBJECT (buffer), on_weak_ref_notify,
      &buffer);

  gst_buffer_unref (buffer);

  fail_unless (weak_ref_notify_succeeded,
      "No weak reference notification took place.");
}

GST_END_TEST;

#if 0
/* ======== recycle test ======== */

static gint recycle_buffer_count = 10;

typedef struct _MyBufferPool MyBufferPool;

struct _MyBufferPool
{
  GSList *buffers;

  volatile gboolean is_closed;
};

static void my_recycle_buffer_destroy (MyRecycleBuffer * buf);

static MyBufferPool *
my_buffer_pool_new (void)
{
  return g_new0 (MyBufferPool, 1);
}

static void
my_buffer_pool_free (MyBufferPool * self)
{
  while (self->buffers != NULL) {
    my_recycle_buffer_destroy (self->buffers->data);
    self->buffers = g_slist_delete_link (self->buffers, self->buffers);
  }

  g_free (self);
}

static void
my_buffer_pool_add (MyBufferPool * self, GstBuffer * buf)
{
  g_mutex_lock (mutex);
  self->buffers = g_slist_prepend (self->buffers, gst_buffer_ref (buf));
  g_mutex_unlock (mutex);
}

static GstBuffer *
my_buffer_pool_drain_one (MyBufferPool * self)
{
  GstBuffer *buf = NULL;

  g_mutex_lock (mutex);
  if (self->buffers != NULL) {
    buf = self->buffers->data;
    self->buffers = g_slist_delete_link (self->buffers, self->buffers);
  }
  g_mutex_unlock (mutex);

  return buf;
}

static void
my_recycle_buffer_finalize (GstMiniObject * mini_object)
{
  GstBuffer *self = GST_BUFFER_CAST (mini_object);

  if (self->pool != NULL) {
    my_buffer_pool_add (self->pool, GST_BUFFER_CAST (self));
    g_usleep (G_USEC_PER_SEC / 100);
  } else {
    GST_MINI_OBJECT_CLASS (my_recycle_buffer_parent_class)->finalize
        (mini_object);
  }
}

static GstBuffer *
my_recycle_buffer_new (MyBufferPool * pool)
{
  GstBuffer *buf;

  buf = gst_buffer_new ();

  //buf->pool = pool;

  return GST_BUFFER_CAST (buf);
}

static void
my_recycle_buffer_destroy (MyRecycleBuffer * buf)
{
  buf->pool = NULL;
  gst_buffer_unref (GST_BUFFER_CAST (buf));
}

static void
thread_buffer_producer (MyBufferPool * pool)
{
  int j;

  THREAD_START ();

  for (j = 0; j < recycle_buffer_count; ++j) {
    GstBuffer *buf = my_recycle_buffer_new (pool);
    gst_buffer_unref (buf);
  }

  pool->is_closed = TRUE;
}

static void
thread_buffer_consumer (MyBufferPool * pool)
{
  THREAD_START ();

  do {
    GstBuffer *buf;

    buf = my_buffer_pool_drain_one (pool);
    if (buf != NULL)
      my_recycle_buffer_destroy (MY_RECYCLE_BUFFER_CAST (buf));

    THREAD_SWITCH ();
  }
  while (!pool->is_closed);
}

GST_START_TEST (test_recycle_threaded)
{
  MyBufferPool *pool;

  pool = my_buffer_pool_new ();

  MAIN_START_THREADS (1, thread_buffer_producer, pool);
  MAIN_START_THREADS (1, thread_buffer_consumer, pool);

  MAIN_STOP_THREADS ();

  my_buffer_pool_free (pool);
}

GST_END_TEST;
#endif

/* ======== value collection test ======== */
typedef struct _MyFoo
{
  GObject object;
} MyFoo;

typedef struct _MyFooClass
{
  GObjectClass gobject_class;
} MyFooClass;

enum
{
  PROP_BUFFER = 1
};

GType my_foo_get_type (void);
G_DEFINE_TYPE (MyFoo, my_foo, G_TYPE_OBJECT);

static void
my_foo_init (MyFoo * foo)
{
}

static void
my_foo_get_property (GObject * object, guint prop_id, GValue * value,
    GParamSpec * pspec)
{
  GstBuffer *new_buf;

  g_assert (prop_id == PROP_BUFFER);

  new_buf = gst_buffer_new_and_alloc (1024);
  g_value_set_boxed (value, GST_MINI_OBJECT (new_buf));
  gst_buffer_unref (new_buf);
}

static void
my_foo_set_property (GObject * object, guint prop_id, const GValue * value,
    GParamSpec * pspec)
{
  GstMiniObject *mini_obj;

  g_assert (prop_id == PROP_BUFFER);

  mini_obj = g_value_get_boxed (value);
  g_assert (GST_IS_BUFFER (mini_obj));

#if 0
  /* gst_value_dup_mini_object() does not exist yet */
  mini_obj = gst_value_dup_mini_object (value);
  g_assert (GST_IS_MINI_OBJECT (mini_obj));
  g_assert (GST_IS_BUFFER (mini_obj));
  gst_mini_object_unref (mini_obj);
#endif
}


static void
my_foo_class_init (MyFooClass * klass)
{
  GObjectClass *gobject_klass = G_OBJECT_CLASS (klass);

  gobject_klass->get_property = my_foo_get_property;
  gobject_klass->set_property = my_foo_set_property;

  g_object_class_install_property (gobject_klass, PROP_BUFFER,
      g_param_spec_boxed ("buffer", "Buffer",
          "a newly created GstBuffer", GST_TYPE_BUFFER, G_PARAM_READWRITE));
}

GST_START_TEST (test_value_collection)
{
  GstBuffer *buf = NULL;
  MyFoo *foo;

  foo = (MyFoo *) g_object_new (my_foo_get_type (), NULL);

  /* test g_object_get() refcounting */
  g_object_get (foo, "buffer", &buf, NULL);
  g_assert (GST_IS_BUFFER (buf));
  g_assert (GST_MINI_OBJECT_REFCOUNT_VALUE (GST_MINI_OBJECT_CAST (buf)) == 1);
  gst_buffer_unref (buf);

  /* test g_object_set() refcounting */
  buf = gst_buffer_new_and_alloc (1024);
  g_object_set (foo, "buffer", buf, NULL);
  g_assert (GST_MINI_OBJECT_REFCOUNT_VALUE (GST_MINI_OBJECT_CAST (buf)) == 1);
  gst_buffer_unref (buf);

  g_object_unref (foo);
}

GST_END_TEST;


GST_START_TEST (test_dup_null_mini_object)
{
  GValue value = { 0, };
  GstMiniObject *mo;

  g_value_init (&value, GST_TYPE_BUFFER);

  g_value_set_boxed (&value, NULL);

  mo = GST_MINI_OBJECT_CAST (g_value_dup_boxed (&value));
  g_assert (mo == NULL);

  g_value_unset (&value);
}

GST_END_TEST;

static Suite *
gst_mini_object_suite (void)
{
  Suite *s = suite_create ("GstMiniObject");
  TCase *tc_chain = tcase_create ("general");

  /* turn off timeout */
  tcase_set_timeout (tc_chain, 60);

  suite_add_tcase (s, tc_chain);
  tcase_add_test (tc_chain, test_copy);
  tcase_add_test (tc_chain, test_is_writable);
  tcase_add_test (tc_chain, test_make_writable);
  tcase_add_test (tc_chain, test_ref_threaded);
  tcase_add_test (tc_chain, test_unref_threaded);
  tcase_add_test (tc_chain, test_weak_ref);
  //tcase_add_test (tc_chain, test_recycle_threaded);
  tcase_add_test (tc_chain, test_value_collection);
  tcase_add_test (tc_chain, test_dup_null_mini_object);
  return s;
}

GST_CHECK_MAIN (gst_mini_object);
