/*
 * Tests and examples of GstHarness
 *
 * 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include <gst/check/gstcheck.h>
#include <gst/check/gstharness.h>

static void
create_destroy_element_harness (gpointer data, gpointer user_data)
{
  GstElement *element = user_data;
  GstHarness *h = gst_harness_new_with_element (element, NULL, NULL);
  gst_harness_teardown (h);
}

GST_START_TEST (test_harness_element_ref)
{
  GstHarness *h = gst_harness_new ("identity");
  GstHarnessThread *threads[100];
  gint i;

  for (i = 0; i < G_N_ELEMENTS (threads); i++)
    threads[i] = gst_harness_stress_custom_start (h, NULL,
        create_destroy_element_harness, h->element, 0);
  for (i = 0; i < G_N_ELEMENTS (threads); i++)
    gst_harness_stress_thread_stop (threads[i]);

  fail_unless_equals_int (G_OBJECT (h->element)->ref_count, 1);

  gst_harness_teardown (h);
}

GST_END_TEST;


GST_START_TEST (test_src_harness)
{
  GstHarness *h = gst_harness_new ("identity");

  /* add a fakesrc that syncs to the clock and a
     capsfilter that adds some caps to it */
  gst_harness_add_src_parse (h,
      "fakesrc sync=1 ! capsfilter caps=\"mycaps\"", TRUE);

  /* this cranks the clock and transfers the resulting buffer
     from the src-harness into the identity element */
  gst_harness_push_from_src (h);

  /* verify that identity outputs a buffer by pulling and unreffing */
  gst_buffer_unref (gst_harness_pull (h));

  gst_harness_teardown (h);
}

GST_END_TEST;

GST_START_TEST (test_src_harness_no_forwarding)
{
  GstHarness *h = gst_harness_new ("identity");

  /* turn of forwarding of necessary events */
  gst_harness_set_forwarding (h, FALSE);

  /* add a fakesrc that syncs to the clock and a
     capsfilter that adds some caps to it */
  gst_harness_add_src_parse (h,
      "fakesrc sync=1 ! capsfilter caps=\"mycaps\"", TRUE);

  /* start the fakesrc to produce the first events */
  gst_harness_play (h->src_harness);

  /* transfer STREAM_START event */
  gst_harness_src_push_event (h);

  /* crank the clock to produce the CAPS and SEGMENT events */
  gst_harness_crank_single_clock_wait (h->src_harness);

  /* transfer CAPS event */
  gst_harness_src_push_event (h);

  /* transfer SEGMENT event */
  gst_harness_src_push_event (h);

  /* now transfer the buffer produced by exploiting
     the ability to say 0 cranks but 1 push */
  gst_harness_src_crank_and_push_many (h, 0, 1);

  /* and verify that the identity element outputs it */
  gst_buffer_unref (gst_harness_pull (h));

  gst_harness_teardown (h);
}

GST_END_TEST;

GST_START_TEST (test_add_sink_harness_without_sinkpad)
{
  GstHarness *h = gst_harness_new ("fakesink");

  gst_harness_add_sink (h, "fakesink");

  gst_harness_teardown (h);
}

GST_END_TEST;

static GstEvent *
create_new_stream_start_event (GstHarness * h, gpointer data)
{
  guint *counter = data;
  gchar *stream_id = g_strdup_printf ("streamid/%d", *counter);
  GstEvent *event = gst_event_new_stream_start (stream_id);
  g_free (stream_id);
  (*counter)++;
  return event;
}

static void
push_query (gpointer data, gpointer user_data)
{
  GstHarness *h = user_data;
  GstCaps *caps = gst_caps_new_empty_simple ("mycaps");
  GstQuery *query = gst_query_new_allocation (caps, FALSE);
  gst_caps_unref (caps);
  gst_pad_peer_query (h->srcpad, query);
  gst_query_unref (query);
}

GST_START_TEST (test_forward_event_and_query_to_sink_harness_while_teardown)
{
  GstHarness *h = gst_harness_new ("identity");
  guint counter = 0;
  GstHarnessThread *e_thread = gst_harness_stress_push_event_with_cb_start (h,
      create_new_stream_start_event, &counter, NULL);
  GstHarnessThread *q_thread = gst_harness_stress_custom_start (h, NULL,
      push_query, h, 0);
  gdouble duration = 1.0;
  GTimer *timer = g_timer_new ();

  while (g_timer_elapsed (timer, NULL) < duration) {
    gst_harness_add_sink (h, "fakesink");
    g_thread_yield ();
  }

  g_timer_destroy (timer);
  gst_harness_stress_thread_stop (q_thread);
  gst_harness_stress_thread_stop (e_thread);
  gst_harness_teardown (h);
}

GST_END_TEST;

static Suite *
gst_harness_suite (void)
{
  Suite *s = suite_create ("GstHarness");
  TCase *tc_chain = tcase_create ("harness");

  suite_add_tcase (s, tc_chain);

  tcase_add_test (tc_chain, test_harness_element_ref);
  tcase_add_test (tc_chain, test_src_harness);
  tcase_add_test (tc_chain, test_src_harness_no_forwarding);
  tcase_add_test (tc_chain, test_add_sink_harness_without_sinkpad);

  tcase_add_test (tc_chain,
      test_forward_event_and_query_to_sink_harness_while_teardown);

  return s;
}

GST_CHECK_MAIN (gst_harness);
