/* GStreamer
 *
 * unit test for identity
 *
 * Copyright (C) <2005> Thomas Vander Stichele <thomas at apestaart dot org>
 * Copyright (C) <2015> Havard Graff           <havard@pexip.com>
 *
 * 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>
#include <gst/check/gstharness.h>

GST_START_TEST (test_one_buffer)
{
  GstHarness *h = gst_harness_new ("identity");
  GstBuffer *buffer_in;
  GstBuffer *buffer_out;

  gst_harness_set_src_caps_str (h, "mycaps");

  buffer_in = gst_buffer_new_and_alloc (4);
  ASSERT_BUFFER_REFCOUNT (buffer_in, "buffer", 1);

  gst_buffer_fill (buffer_in, 0, "data", 4);

  /* pushing gives away my reference ... */
  fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h, buffer_in));

  /* ... but it should end up being collected on GstHarness queue */
  fail_unless_equals_int (1, gst_harness_buffers_in_queue (h));
  buffer_out = gst_harness_pull (h);

  fail_unless (buffer_in == buffer_out);
  ASSERT_BUFFER_REFCOUNT (buffer_out, "buffer", 1);

  /* cleanup */
  gst_buffer_unref (buffer_out);
  gst_harness_teardown (h);
}
GST_END_TEST;

static void
handoff_func (GstElement * identity, GstBuffer * buf,  GstBuffer ** ret)
{
  (void)identity;
  *ret = buf;
}

GST_START_TEST (test_signal_handoffs)
{
  GstHarness *h = gst_harness_new ("identity");
  GstBuffer *buffer_in;
  GstBuffer *buffer_signaled = NULL;
  gst_harness_set_src_caps_str (h, "mycaps");

  /* connect to the handoff signal */
  g_signal_connect (h->element, "handoff",
      G_CALLBACK (handoff_func), &buffer_signaled);

  /* first, turn off signal-handoffs */
  g_object_set (h->element, "signal-handoffs", FALSE, NULL);

  /* then push a buffer */
  buffer_in = gst_buffer_new_and_alloc (4);
  fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h, buffer_in));

  /* verify that we got no buffer signaled */
  fail_unless (buffer_signaled == NULL);

  /* now turn on signal-handoffs */
  g_object_set (h->element, "signal-handoffs", TRUE, NULL);

  /* then push another buffer */
  buffer_in = gst_buffer_new_and_alloc (4);
  fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h, buffer_in));

  /* verify the buffer signaled is equal to the one pushed in */
  fail_unless (buffer_signaled == buffer_in);
  ASSERT_BUFFER_REFCOUNT (buffer_signaled, "buffer", 1);

  /* cleanup */
  gst_harness_teardown (h);
}
GST_END_TEST;

GST_START_TEST (test_sync_on_timestamp)
{
  /* the reason to use the queue in front of the identity element
     is to effectively make gst_harness_push asynchronous, not locking
     up the test, waiting for gst_clock_id_wait */
  GstHarness * h = gst_harness_new_parse ("queue ! identity sync=1");
  GstBuffer *buf;
  GstClock *clock;
  GstClockTime timestamp = 123456789;

  /* use testclock */
  gst_harness_use_testclock (h);
  gst_harness_set_src_caps_str (h, "mycaps");

  /* make a buffer and set the timestamp */
  buf = gst_buffer_new ();
  GST_BUFFER_PTS (buf) = timestamp;

  /* push the buffer, and verify it does *not* make it through */
  gst_harness_push (h, buf);
  fail_unless_equals_int (0, gst_harness_buffers_in_queue (h));

  /* verify the identity element has registered exactly one GstClockID */
  fail_unless (gst_harness_wait_for_clock_id_waits (h, 1, 42));

  /* crank the clock and pull the buffer */
  gst_harness_crank_single_clock_wait (h);
  buf = gst_harness_pull (h);

  /* verify that the buffer has the right timestamp, and that the time on
     the clock is equal to the timestamp */
  fail_unless_equals_int64 (timestamp, GST_BUFFER_PTS (buf));
  clock = gst_element_get_clock (h->element);
  fail_unless_equals_int64 (timestamp, gst_clock_get_time (clock));

  /* cleanup */
  gst_object_unref (clock);
  gst_buffer_unref (buf);
  gst_harness_teardown (h);
}
GST_END_TEST;

GST_START_TEST (test_stopping_element_unschedules_sync)
{
  /* the reason to use the queue in front of the identity element
     is to effectively make gst_harness_push asynchronous, not locking
     up the test, waiting for gst_clock_id_wait */
  GstHarness * h = gst_harness_new_parse ("queue ! identity sync=1");
  GstBuffer *buf;
  GstClockTime timestamp = 123456789;

  /* use testclock */
  gst_harness_use_testclock (h);
  gst_harness_set_src_caps_str (h, "mycaps");

  /* make a buffer and set the timestamp */
  buf = gst_buffer_new ();
  GST_BUFFER_PTS (buf) = timestamp;

  /* push the buffer, and verify it does *not* make it through */
  gst_harness_push (h, buf);
  fail_unless_equals_int (0, gst_harness_buffers_in_queue (h));

  /* verify the identity element has registered exactly one GstClockID */
  fail_unless (gst_harness_wait_for_clock_id_waits (h, 1, 42));

  /* setting identity to READY should unschedule the sync */
  gst_element_set_state (h->element, GST_STATE_READY);

  /* verify the identity element no longer waits on the clock */
  fail_unless (gst_harness_wait_for_clock_id_waits (h, 0, 42));

  /* and that the waiting buffer was dropped */
  fail_unless_equals_int (0, gst_harness_buffers_received (h));

  gst_harness_teardown (h);
}
GST_END_TEST;

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

  suite_add_tcase (s, tc_chain);
  tcase_add_test (tc_chain, test_one_buffer);
  tcase_add_test (tc_chain, test_signal_handoffs);
  tcase_add_test (tc_chain, test_sync_on_timestamp);
  tcase_add_test (tc_chain, test_stopping_element_unschedules_sync);


  return s;
}

GST_CHECK_MAIN (identity);
