/* GStreamer
 *
 * unit test for fakesrc
 *
 * Copyright (C) <2005> Thomas Vander Stichele <thomas at apestaart dot org>
 *
 * 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 <unistd.h>

#include <gst/check/gstcheck.h>

static gboolean have_eos = FALSE;

static GstPad *mysinkpad;

static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS_ANY);

static gboolean
event_func (GstPad * pad, GstObject * parent, GstEvent * event)
{
  if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) {
    have_eos = TRUE;
  }
  gst_event_unref (event);
  return TRUE;
}

static GstElement *
setup_fakesrc (void)
{
  GstElement *fakesrc;

  GST_DEBUG ("setup_fakesrc");
  fakesrc = gst_check_setup_element ("fakesrc");
  mysinkpad = gst_check_setup_sink_pad (fakesrc, &sinktemplate);
  gst_pad_set_event_function (mysinkpad, event_func);
  gst_pad_set_active (mysinkpad, TRUE);
  have_eos = FALSE;
  return fakesrc;
}

static void
cleanup_fakesrc (GstElement * fakesrc)
{
  gst_pad_set_active (mysinkpad, FALSE);
  gst_check_teardown_sink_pad (fakesrc);
  gst_check_teardown_element (fakesrc);
}

GST_START_TEST (test_num_buffers)
{
  GstElement *src;

  src = setup_fakesrc ();
  g_object_set (G_OBJECT (src), "num-buffers", 3, NULL);
  fail_unless (gst_element_set_state (src,
          GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
      "could not set to playing");

  while (!have_eos) {
    g_usleep (1000);
  }

  fail_unless_equals_int (g_list_length (buffers), 3);
  gst_check_drop_buffers ();

  fail_unless (gst_element_set_state (src,
          GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null");

  /* cleanup */
  cleanup_fakesrc (src);
}

GST_END_TEST;

GST_START_TEST (test_sizetype_empty)
{
  GstElement *src;
  GList *l;

  src = setup_fakesrc ();

  g_object_set (G_OBJECT (src), "sizetype", 1, NULL);
  g_object_set (G_OBJECT (src), "num-buffers", 100, NULL);

  fail_unless (gst_element_set_state (src,
          GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
      "could not set to playing");

  while (!have_eos) {
    g_usleep (1000);
  }

  fail_unless_equals_int (g_list_length (buffers), 100);
  l = buffers;
  while (l) {
    GstBuffer *buf = l->data;

    fail_unless (gst_buffer_get_size (buf) == 0);
    l = l->next;
  }
  gst_check_drop_buffers ();

  fail_unless (gst_element_set_state (src,
          GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null");

  /* cleanup */
  cleanup_fakesrc (src);
}

GST_END_TEST;

GST_START_TEST (test_sizetype_fixed)
{
  GstElement *src;
  GList *l;

  src = setup_fakesrc ();

  g_object_set (G_OBJECT (src), "sizetype", 2, NULL);
  g_object_set (G_OBJECT (src), "sizemax", 8192, NULL);
  g_object_set (G_OBJECT (src), "num-buffers", 100, NULL);

  fail_unless (gst_element_set_state (src,
          GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
      "could not set to playing");

  while (!have_eos) {
    g_usleep (1000);
  }

  fail_unless (g_list_length (buffers) == 100);
  l = buffers;
  while (l) {
    GstBuffer *buf = l->data;

    fail_unless (gst_buffer_get_size (buf) == 8192);
    l = l->next;
  }
  gst_check_drop_buffers ();

  fail_unless (gst_element_set_state (src,
          GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null");

  /* cleanup */
  cleanup_fakesrc (src);
}

GST_END_TEST;

GST_START_TEST (test_sizetype_random)
{
  GstElement *src;
  GList *l;

  src = setup_fakesrc ();

  g_object_set (G_OBJECT (src), "sizetype", 3, NULL);
  g_object_set (G_OBJECT (src), "sizemin", 4096, NULL);
  g_object_set (G_OBJECT (src), "sizemax", 8192, NULL);
  g_object_set (G_OBJECT (src), "num-buffers", 100, NULL);

  fail_unless (gst_element_set_state (src,
          GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
      "could not set to playing");

  while (!have_eos) {
    g_usleep (1000);
  }

  fail_unless (g_list_length (buffers) == 100);
  l = buffers;
  while (l) {
    GstBuffer *buf = l->data;

    fail_if (gst_buffer_get_size (buf) > 8192);
    fail_if (gst_buffer_get_size (buf) < 4096);
    l = l->next;
  }
  gst_check_drop_buffers ();

  fail_unless (gst_element_set_state (src,
          GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null");

  /* cleanup */
  cleanup_fakesrc (src);
}

GST_END_TEST;

GST_START_TEST (test_no_preroll)
{
  GstElement *src;
  GstStateChangeReturn ret;

  src = setup_fakesrc ();

  g_object_set (G_OBJECT (src), "is-live", TRUE, NULL);

  ret = gst_element_set_state (src, GST_STATE_PAUSED);

  fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL,
      "error going to paused the first time");

  ret = gst_element_set_state (src, GST_STATE_PAUSED);

  fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL,
      "error going to paused the second time");

  fail_unless (gst_element_set_state (src,
          GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null");

  /* cleanup */
  cleanup_fakesrc (src);
}

GST_END_TEST;

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

  suite_add_tcase (s, tc_chain);
  tcase_add_test (tc_chain, test_num_buffers);
  tcase_add_test (tc_chain, test_sizetype_empty);
  tcase_add_test (tc_chain, test_sizetype_fixed);
  tcase_add_test (tc_chain, test_sizetype_random);
  tcase_add_test (tc_chain, test_no_preroll);

  return s;
}

GST_CHECK_MAIN (fakesrc);
