/* GStreamer
 * Copyright (C) 2005 Thomas Vander Stichele <thomas at apestaart dot org>
 *
 * gsttask.c: Unit test for GstTask
 *
 * 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>

static GMutex task_lock;
static GCond task_cond;

static GRecMutex task_mutex;

#define TEST_RACE_ITERATIONS 1000

static void
task_signal_pause_func (void *data)
{
  GstTask **t = data;

  g_mutex_lock (&task_lock);
  GST_DEBUG ("signal");
  g_cond_signal (&task_cond);

  gst_task_pause (*t);
  g_mutex_unlock (&task_lock);
}

GST_START_TEST (test_pause_stop_race)
{
  guint it = TEST_RACE_ITERATIONS;
  GstTask *t;
  gboolean ret;

  t = gst_task_new (task_signal_pause_func, &t, NULL);
  fail_if (t == NULL);

  g_rec_mutex_init (&task_mutex);
  gst_task_set_lock (t, &task_mutex);

  g_cond_init (&task_cond);
  g_mutex_init (&task_lock);

  while (it-- > 0) {
    g_mutex_lock (&task_lock);
    GST_DEBUG ("starting");
    ret = gst_task_start (t);
    fail_unless (ret == TRUE);
    /* wait for it to spin up */
    GST_DEBUG ("waiting");
    g_cond_wait (&task_cond, &task_lock);
    GST_DEBUG ("done waiting");
    g_mutex_unlock (&task_lock);

    GST_DEBUG ("starting");
    ret = gst_task_stop (t);
    fail_unless (ret == TRUE);

    GST_DEBUG ("joining");
    ret = gst_task_join (t);
    fail_unless (ret == TRUE);
  }

  g_cond_clear (&task_cond);
  g_mutex_clear (&task_lock);

  gst_object_unref (t);
}

GST_END_TEST;

static void
task_func2 (void *data)
{
  gboolean ret;
  GstTask *t = *((GstTask **) data);

  g_mutex_lock (&task_lock);
  GST_DEBUG ("signal");
  g_cond_signal (&task_cond);
  g_mutex_unlock (&task_lock);

  ASSERT_WARNING (ret = gst_task_join (t));
  fail_unless (ret == FALSE);
}

GST_START_TEST (test_join)
{
  GstTask *t;
  gboolean ret;

  t = gst_task_new (task_func2, &t, NULL);
  fail_if (t == NULL);

  g_rec_mutex_init (&task_mutex);
  gst_task_set_lock (t, &task_mutex);

  g_cond_init (&task_cond);
  g_mutex_init (&task_lock);

  g_mutex_lock (&task_lock);
  GST_DEBUG ("starting");
  ret = gst_task_start (t);
  fail_unless (ret == TRUE);
  /* wait for it to spin up */
  GST_DEBUG ("waiting");
  g_cond_wait (&task_cond, &task_lock);
  GST_DEBUG ("done waiting");
  g_mutex_unlock (&task_lock);

  GST_DEBUG ("joining");
  ret = gst_task_join (t);
  fail_unless (ret == TRUE);

  gst_task_cleanup_all ();

  gst_object_unref (t);
}

GST_END_TEST;

static void
task_func (void *data)
{
  g_mutex_lock (&task_lock);
  GST_DEBUG ("signal");
  g_cond_signal (&task_cond);
  g_mutex_unlock (&task_lock);
}

GST_START_TEST (test_lock_start)
{
  GstTask *t;
  gboolean ret;

  t = gst_task_new (task_func, NULL, NULL);
  fail_if (t == NULL);

  g_rec_mutex_init (&task_mutex);
  gst_task_set_lock (t, &task_mutex);

  g_cond_init (&task_cond);
  g_mutex_init (&task_lock);

  g_mutex_lock (&task_lock);
  GST_DEBUG ("starting");
  ret = gst_task_start (t);
  fail_unless (ret == TRUE);
  /* wait for it to spin up */
  GST_DEBUG ("waiting");
  g_cond_wait (&task_cond, &task_lock);
  GST_DEBUG ("done waiting");
  g_mutex_unlock (&task_lock);

  /* cannot set mutex now */
  ASSERT_WARNING (gst_task_set_lock (t, &task_mutex));

  GST_DEBUG ("joining");
  ret = gst_task_join (t);
  fail_unless (ret == TRUE);

  gst_task_cleanup_all ();

  gst_object_unref (t);
}

GST_END_TEST;

GST_START_TEST (test_lock)
{
  GstTask *t;
  gboolean ret;

  t = gst_task_new (task_func, NULL, NULL);
  fail_if (t == NULL);

  g_rec_mutex_init (&task_mutex);
  gst_task_set_lock (t, &task_mutex);

  GST_DEBUG ("pause");
  ret = gst_task_pause (t);
  fail_unless (ret == TRUE);

  g_usleep (1 * G_USEC_PER_SEC / 2);

  GST_DEBUG ("joining");
  ret = gst_task_join (t);
  fail_unless (ret == TRUE);

  g_usleep (1 * G_USEC_PER_SEC / 2);

  gst_object_unref (t);
}

GST_END_TEST;

GST_START_TEST (test_no_lock)
{
  GstTask *t;
  gboolean ret;

  t = gst_task_new (task_func, NULL, NULL);
  fail_if (t == NULL);

  /* stop should be possible without lock */
  gst_task_stop (t);

  /* pause should give a warning */
  ASSERT_WARNING (ret = gst_task_pause (t));
  fail_unless (ret == FALSE);

  /* start should give a warning */
  ASSERT_WARNING (ret = gst_task_start (t));
  fail_unless (ret == FALSE);

  /* stop should be possible without lock */
  gst_task_stop (t);

  gst_object_unref (t);
}

GST_END_TEST;

GST_START_TEST (test_create)
{
  GstTask *t;

  t = gst_task_new (task_func, NULL, NULL);
  fail_if (t == NULL);

  gst_object_unref (t);
}

GST_END_TEST;


static Suite *
gst_task_suite (void)
{
  Suite *s = suite_create ("GstTask");
  TCase *tc_chain = tcase_create ("task tests");

  suite_add_tcase (s, tc_chain);
  tcase_add_test (tc_chain, test_create);
  tcase_add_test (tc_chain, test_no_lock);
  tcase_add_test (tc_chain, test_lock);
  tcase_add_test (tc_chain, test_lock_start);
  tcase_add_test (tc_chain, test_join);
  tcase_add_test (tc_chain, test_pause_stop_race);

  return s;
}

GST_CHECK_MAIN (gst_task);
