/* GStreamer unit tests for the funnel
 *
 * Copyright (C) 2008 Collabora, Nokia
 * @author: Olivier Crete <olivier.crete@collabora.co.uk>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
*/


#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include <gst/check/gstcheck.h>

struct TestData
{
  GstElement *funnel;
  GstPad *funnelsrc, *funnelsink11, *funnelsink22;
  GstPad *mysink, *mysrc1, *mysrc2;
  GstCaps *mycaps;
};

static void
setup_test_objects (struct TestData *td, GstPadChainFunction chain_func)
{
  td->mycaps = gst_caps_new_empty_simple ("test/test");

  td->funnel = gst_element_factory_make ("funnel", NULL);

  td->funnelsrc = gst_element_get_static_pad (td->funnel, "src");
  fail_unless (td->funnelsrc != NULL);

  td->funnelsink11 = gst_element_get_request_pad (td->funnel, "sink_11");
  fail_unless (td->funnelsink11 != NULL);
  fail_unless (!strcmp (GST_OBJECT_NAME (td->funnelsink11), "sink_11"));

  td->funnelsink22 = gst_element_get_request_pad (td->funnel, "sink_22");
  fail_unless (td->funnelsink22 != NULL);
  fail_unless (!strcmp (GST_OBJECT_NAME (td->funnelsink22), "sink_22"));

  fail_unless (gst_element_set_state (td->funnel, GST_STATE_PLAYING) ==
      GST_STATE_CHANGE_SUCCESS);

  td->mysink = gst_pad_new ("sink", GST_PAD_SINK);
  gst_pad_set_chain_function (td->mysink, chain_func);
  gst_pad_set_active (td->mysink, TRUE);

  td->mysrc1 = gst_pad_new ("src1", GST_PAD_SRC);
  gst_pad_set_active (td->mysrc1, TRUE);
  gst_check_setup_events_with_stream_id (td->mysrc1, td->funnel, td->mycaps,
      GST_FORMAT_BYTES, "test1");

  td->mysrc2 = gst_pad_new ("src2", GST_PAD_SRC);
  gst_pad_set_active (td->mysrc2, TRUE);
  gst_check_setup_events_with_stream_id (td->mysrc2, td->funnel, td->mycaps,
      GST_FORMAT_BYTES, "test2");

  fail_unless (GST_PAD_LINK_SUCCESSFUL (gst_pad_link (td->funnelsrc,
              td->mysink)));

  fail_unless (GST_PAD_LINK_SUCCESSFUL (gst_pad_link (td->mysrc1,
              td->funnelsink11)));

  fail_unless (GST_PAD_LINK_SUCCESSFUL (gst_pad_link (td->mysrc2,
              td->funnelsink22)));

}

static void
release_test_objects (struct TestData *td)
{
  gst_pad_set_active (td->mysink, FALSE);
  gst_pad_set_active (td->mysrc1, FALSE);
  gst_pad_set_active (td->mysrc1, FALSE);

  gst_object_unref (td->mysink);
  gst_object_unref (td->mysrc1);
  gst_object_unref (td->mysrc2);

  fail_unless (gst_element_set_state (td->funnel, GST_STATE_NULL) ==
      GST_STATE_CHANGE_SUCCESS);

  gst_object_unref (td->funnelsrc);
  gst_element_release_request_pad (td->funnel, td->funnelsink11);
  gst_object_unref (td->funnelsink11);
  gst_element_release_request_pad (td->funnel, td->funnelsink22);
  gst_object_unref (td->funnelsink22);

  gst_caps_unref (td->mycaps);
  gst_object_unref (td->funnel);
}

static gint bufcount = 0;
static gint alloccount = 0;

static GstFlowReturn
chain_ok (GstPad * pad, GstObject * parent, GstBuffer * buffer)
{
  bufcount++;

  gst_buffer_unref (buffer);

  return GST_FLOW_OK;
}

GST_START_TEST (test_funnel_simple)
{
  struct TestData td;

  setup_test_objects (&td, chain_ok);

  bufcount = 0;
  alloccount = 0;

  fail_unless (gst_pad_push (td.mysrc1, gst_buffer_new ()) == GST_FLOW_OK);
  fail_unless (gst_pad_push (td.mysrc2, gst_buffer_new ()) == GST_FLOW_OK);

  fail_unless (bufcount == 2);

  release_test_objects (&td);
}

GST_END_TEST;

guint num_eos = 0;

static gboolean
eos_event_func (GstPad * pad, GstObject * parent, GstEvent * event)
{
  if (GST_EVENT_TYPE (event) == GST_EVENT_EOS)
    ++num_eos;

  return gst_pad_event_default (pad, parent, event);
}

GST_START_TEST (test_funnel_eos)
{
  struct TestData td;
  GstSegment segment;

  setup_test_objects (&td, chain_ok);

  num_eos = 0;
  bufcount = 0;

  gst_pad_set_event_function (td.mysink, eos_event_func);

  fail_unless (gst_pad_push (td.mysrc1, gst_buffer_new ()) == GST_FLOW_OK);
  fail_unless (gst_pad_push (td.mysrc2, gst_buffer_new ()) == GST_FLOW_OK);

  fail_unless (bufcount == 2);

  fail_unless (gst_pad_push_event (td.mysrc1, gst_event_new_eos ()));
  fail_unless (num_eos == 0);

  fail_unless (gst_pad_push (td.mysrc1, gst_buffer_new ()) == GST_FLOW_EOS);
  fail_unless (gst_pad_push (td.mysrc2, gst_buffer_new ()) == GST_FLOW_OK);

  fail_unless (bufcount == 3);

  fail_unless (gst_pad_push_event (td.mysrc2, gst_event_new_eos ()));
  fail_unless (num_eos == 1);

  fail_unless (gst_pad_push (td.mysrc1, gst_buffer_new ()) == GST_FLOW_EOS);
  fail_unless (gst_pad_push (td.mysrc2, gst_buffer_new ()) == GST_FLOW_EOS);

  fail_unless (bufcount == 3);

  fail_unless (gst_pad_push_event (td.mysrc1, gst_event_new_flush_start ()));
  fail_unless (gst_pad_push_event (td.mysrc1, gst_event_new_flush_stop (TRUE)));

  gst_segment_init (&segment, GST_FORMAT_BYTES);
  gst_pad_push_event (td.mysrc1, gst_event_new_segment (&segment));
  gst_pad_push_event (td.mysrc2, gst_event_new_segment (&segment));

  fail_unless (gst_pad_push (td.mysrc1, gst_buffer_new ()) == GST_FLOW_OK);
  fail_unless (gst_pad_push (td.mysrc2, gst_buffer_new ()) == GST_FLOW_EOS);

  fail_unless (bufcount == 4);

  fail_unless (gst_pad_unlink (td.mysrc1, td.funnelsink11));
  gst_element_release_request_pad (td.funnel, td.funnelsink11);
  gst_object_unref (td.funnelsink11);
  fail_unless (num_eos == 2);

  td.funnelsink11 = gst_element_get_request_pad (td.funnel, "sink_11");
  fail_unless (td.funnelsink11 != NULL);
  fail_unless (!strcmp (GST_OBJECT_NAME (td.funnelsink11), "sink_11"));

  fail_unless (GST_PAD_LINK_SUCCESSFUL (gst_pad_link (td.mysrc1,
              td.funnelsink11)));

  /* This will fail because everything is EOS already */
  fail_if (gst_pad_push_event (td.mysrc1, gst_event_new_eos ()));
  fail_unless (num_eos == 2);

  fail_unless (gst_pad_unlink (td.mysrc1, td.funnelsink11));
  gst_element_release_request_pad (td.funnel, td.funnelsink11);
  gst_object_unref (td.funnelsink11);
  fail_unless (num_eos == 2);

  /* send only eos to check, it handles empty streams */
  td.funnelsink11 = gst_element_get_request_pad (td.funnel, "sink_11");
  fail_unless (td.funnelsink11 != NULL);
  fail_unless (!strcmp (GST_OBJECT_NAME (td.funnelsink11), "sink_11"));

  fail_unless (GST_PAD_LINK_SUCCESSFUL (gst_pad_link (td.mysrc1,
              td.funnelsink11)));

  fail_unless (gst_pad_push_event (td.mysrc1, gst_event_new_flush_start ()));
  fail_unless (gst_pad_push_event (td.mysrc1, gst_event_new_flush_stop (TRUE)));
  fail_unless (gst_pad_push_event (td.mysrc2, gst_event_new_flush_start ()));
  fail_unless (gst_pad_push_event (td.mysrc2, gst_event_new_flush_stop (TRUE)));

  fail_unless (gst_pad_push_event (td.mysrc1, gst_event_new_eos ()));
  fail_unless (gst_pad_push_event (td.mysrc2, gst_event_new_eos ()));
  fail_unless (num_eos == 3);

  fail_unless (gst_pad_unlink (td.mysrc1, td.funnelsink11));
  gst_element_release_request_pad (td.funnel, td.funnelsink11);
  gst_object_unref (td.funnelsink11);
  fail_unless (num_eos == 3);

  td.funnelsink11 = gst_element_get_request_pad (td.funnel, "sink_11");
  fail_unless (td.funnelsink11 != NULL);
  fail_unless (!strcmp (GST_OBJECT_NAME (td.funnelsink11), "sink_11"));

  release_test_objects (&td);
}

GST_END_TEST;

guint nb_stream_start_event = 0;
guint nb_caps_event = 0;
guint nb_segment_event = 0;
guint nb_gap_event = 0;

static GstPadProbeReturn
event_counter (GstObject * pad, GstPadProbeInfo * info, gpointer user_data)
{
  GstEvent *event = GST_PAD_PROBE_INFO_EVENT (info);

  fail_unless (event != NULL);
  fail_unless (GST_IS_EVENT (event));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_STREAM_START:
      ++nb_stream_start_event;
      break;
    case GST_EVENT_CAPS:
      ++nb_caps_event;
      break;
    case GST_EVENT_SEGMENT:
      ++nb_segment_event;
      break;
    case GST_EVENT_GAP:
      ++nb_gap_event;
      break;
    default:
      break;
  }

  return GST_PAD_PROBE_OK;
}

/*
 * Push GAP events into funnel to forward sticky events.
 * Funnel element shoud also treat GAP events likes buffers.
 * For example, funnel can be used for internal subtitle with streamiddemux. 
 *  +--------------------------------------------------------------------------+
 *  | playbin                               +--------------------------------+ |
 *  | +--------------+  +----------------+  | +------------+     playsink    | |
 *  | | uridecodebin |  | input-selector |  | | video-sink |                 | |
 *  | |              |  +----------------+  | +------------+                 | |
 *  | |              |                      |                                | |
 *  | |              |  +----------------+  | +------------+                 | |
 *  | |              |  | input-selector |  | | audio-sink |                 | |
 *  | |              |  +----------------+  | +------------+                 | |
 *  | |              |                      |                                | |
 *  | |              |  +----------------+  | +---------------+ +----------+ | |
 *  | |              |  | funnel         |  | | streamiddemux | | appsink0 | | |
 *  | +--------------+  +----------------+  | +---------------+ +----------+ | |
 *  |                                       |                   +----------+ | |
 *  |                                       |                   | appsinkn | | |
 *  |                                       |                   +----------+ | |
 *  |                                       +--------------------------------+ |
 *  +--------------------------------------------------------------------------+
 * If no data was received in funnel and then sticky events can be pending continuously. 
 * And streamiddemux only receive gap events continuously. 
 * Thus, pipeline can not be constructed completely.
 * For support it, need to handle GAP events likes buffers.
 */
GST_START_TEST (test_funnel_gap_event)
{
  struct TestData td;
  guint probe = 0;

  setup_test_objects (&td, chain_ok);

  nb_stream_start_event = 0;
  nb_caps_event = 0;
  nb_segment_event = 0;
  nb_gap_event = 0;
  bufcount = 0;

  probe = gst_pad_add_probe (td.mysink, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
      (GstPadProbeCallback) event_counter, NULL, NULL);

  /* push a gap event to srcpad1 to push sticky events */
  fail_unless (gst_pad_push_event (td.mysrc1, gst_event_new_gap (0,
              GST_SECOND)));

  fail_unless (nb_stream_start_event == 1);
  fail_unless (nb_caps_event == 1);
  fail_unless (nb_segment_event == 1);
  fail_unless (nb_gap_event == 1);

  /* push a gap event to srcpad2 to push sticky events */
  fail_unless (gst_pad_push_event (td.mysrc2, gst_event_new_gap (0,
              GST_SECOND)));

  fail_unless (nb_stream_start_event == 2);
  fail_unless (nb_caps_event == 2);
  fail_unless (nb_segment_event == 2);
  fail_unless (nb_gap_event == 2);

  /* push a gap event to srcpad2 */
  fail_unless (gst_pad_push_event (td.mysrc2, gst_event_new_gap (0,
              GST_SECOND)));

  fail_unless (nb_stream_start_event == 2);
  fail_unless (nb_caps_event == 2);
  fail_unless (nb_segment_event == 2);
  fail_unless (nb_gap_event == 3);

  /* push a gap event to srcpad1 */
  fail_unless (gst_pad_push_event (td.mysrc1, gst_event_new_gap (0,
              GST_SECOND)));

  fail_unless (nb_stream_start_event == 3);
  fail_unless (nb_caps_event == 3);
  fail_unless (nb_segment_event == 3);
  fail_unless (nb_gap_event == 4);

  /* push buffer */
  fail_unless (gst_pad_push (td.mysrc1, gst_buffer_new ()) == GST_FLOW_OK);
  fail_unless (gst_pad_push (td.mysrc2, gst_buffer_new ()) == GST_FLOW_OK);

  fail_unless (nb_stream_start_event == 4);
  fail_unless (nb_caps_event == 4);
  fail_unless (nb_segment_event == 4);
  fail_unless (nb_gap_event == 4);
  fail_unless (bufcount == 2);

  gst_pad_remove_probe (td.mysink, probe);

  release_test_objects (&td);
}

GST_END_TEST;

static Suite *
funnel_suite (void)
{
  Suite *s = suite_create ("funnel");
  TCase *tc_chain;

  tc_chain = tcase_create ("funnel simple");
  tcase_add_test (tc_chain, test_funnel_simple);
  tcase_add_test (tc_chain, test_funnel_eos);
  tcase_add_test (tc_chain, test_funnel_gap_event);
  suite_add_tcase (s, tc_chain);

  return s;
}

GST_CHECK_MAIN (funnel);
