/* GStreamer
 *
 * unit test for capssetter
 *
 * Copyright (C) <2009> Mark Nauwelaerts <mnauw@users.sourceforge.net>
 *
 * 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 <unistd.h>

#include <gst/check/gstcheck.h>


/* For ease of programming we use globals to keep refs for our floating
 * src and sink pads we create; otherwise we always have to do get_pad,
 * get_peer, and then remove references in every test function */
static GstPad *mysrcpad, *mysinkpad;


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

static GstElement *
setup_capssetter (void)
{
  GstElement *capssetter;

  GST_DEBUG ("setup_capssetter");

  capssetter = gst_check_setup_element ("capssetter");
  mysrcpad = gst_check_setup_src_pad (capssetter, &srctemplate);
  mysinkpad = gst_check_setup_sink_pad (capssetter, &sinktemplate);
  gst_pad_set_active (mysrcpad, TRUE);
  gst_pad_set_active (mysinkpad, TRUE);

  return capssetter;
}

static void
cleanup_capssetter (GstElement * capssetter)
{
  GST_DEBUG ("cleanup_capssetter");

  gst_pad_set_active (mysrcpad, FALSE);
  gst_pad_set_active (mysinkpad, FALSE);
  gst_check_teardown_src_pad (capssetter);
  gst_check_teardown_sink_pad (capssetter);
  gst_check_teardown_element (capssetter);
}

static void
push_and_test (GstCaps * prop_caps, gboolean join, gboolean replace,
    GstCaps * in_caps, GstCaps * out_caps)
{
  GstElement *capssetter;
  GstBuffer *buffer;
  GstCaps *current_out;

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

  g_object_set (capssetter, "join", join, NULL);
  g_object_set (capssetter, "replace", replace, NULL);
  g_object_set (capssetter, "caps", prop_caps, NULL);
  gst_caps_unref (prop_caps);

  buffer = gst_buffer_new_and_alloc (4);
  ASSERT_BUFFER_REFCOUNT (buffer, "buffer", 1);
  gst_buffer_fill (buffer, 0, "data", 4);

  gst_check_setup_events (mysrcpad, capssetter, in_caps, GST_FORMAT_TIME);
  gst_caps_unref (in_caps);

  /* pushing gives away my reference ... */
  fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK,
      "Failed pushing buffer to capssetter");

  fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_eos ()) == TRUE);

  /* ... but it should end up being collected on the global buffer list */
  fail_unless (g_list_length (buffers) == 1);
  buffer = g_list_first (buffers)->data;
  ASSERT_BUFFER_REFCOUNT (buffer, "buffer", 1);

  current_out = gst_pad_get_current_caps (mysinkpad);
  fail_unless (gst_caps_is_equal (out_caps, current_out));
  gst_caps_unref (current_out);
  gst_caps_unref (out_caps);

  /* cleanup */
  cleanup_capssetter (capssetter);
}

#define SRC_WIDTH   8
#define SRC_HEIGHT 12

static GstCaps *
make_src_caps (void)
{
  return gst_caps_new_simple ("video/x-foo", "width", G_TYPE_INT, SRC_WIDTH,
      "height", G_TYPE_INT, SRC_HEIGHT, NULL);
}

/* don't try these caps mutations at home, folks */

GST_START_TEST (test_n_join_n_replace)
{
  GstCaps *in_caps, *prop_caps, *out_caps;

  in_caps = make_src_caps ();
  prop_caps = gst_caps_new_simple ("video/x-bar",
      "width", G_TYPE_INT, 2 * SRC_WIDTH, NULL);
  out_caps = gst_caps_new_simple ("video/x-bar",
      "width", G_TYPE_INT, 2 * SRC_WIDTH,
      "height", G_TYPE_INT, SRC_HEIGHT, NULL);
  push_and_test (prop_caps, FALSE, FALSE, in_caps, out_caps);
}

GST_END_TEST;

GST_START_TEST (test_n_join_replace)
{
  GstCaps *in_caps, *prop_caps, *out_caps;

  in_caps = make_src_caps ();
  prop_caps = gst_caps_new_simple ("video/x-bar",
      "width", G_TYPE_INT, 2 * SRC_WIDTH, NULL);
  out_caps = gst_caps_copy (prop_caps);
  push_and_test (prop_caps, FALSE, TRUE, in_caps, out_caps);
}

GST_END_TEST;

GST_START_TEST (test_join_n_replace_n_match)
{
  GstCaps *in_caps, *prop_caps, *out_caps;

  /* non joining caps */
  in_caps = make_src_caps ();
  prop_caps = gst_caps_new_simple ("video/x-bar",
      "width", G_TYPE_INT, 2 * SRC_WIDTH, NULL);
  out_caps = gst_caps_copy (in_caps);
  push_and_test (prop_caps, TRUE, FALSE, in_caps, out_caps);
}

GST_END_TEST;

GST_START_TEST (test_join_n_replace_match)
{
  GstCaps *in_caps, *prop_caps, *out_caps;

  /* joining caps */
  in_caps = make_src_caps ();
  prop_caps = gst_caps_new_simple ("video/x-foo",
      "width", G_TYPE_INT, 2 * SRC_WIDTH, NULL);
  out_caps = gst_caps_new_simple ("video/x-foo",
      "width", G_TYPE_INT, 2 * SRC_WIDTH,
      "height", G_TYPE_INT, SRC_HEIGHT, NULL);
  push_and_test (prop_caps, TRUE, FALSE, in_caps, out_caps);
}

GST_END_TEST;

GST_START_TEST (test_join_replace_n_match)
{
  GstCaps *in_caps, *prop_caps, *out_caps;

  /* non joining caps */
  in_caps = make_src_caps ();
  prop_caps = gst_caps_new_simple ("video/x-bar",
      "width", G_TYPE_INT, 2 * SRC_WIDTH, NULL);
  out_caps = gst_caps_copy (in_caps);
  push_and_test (prop_caps, TRUE, TRUE, in_caps, out_caps);
}

GST_END_TEST;

GST_START_TEST (test_join_replace_match)
{
  GstCaps *in_caps, *prop_caps, *out_caps;

  /* joining caps */
  in_caps = make_src_caps ();
  prop_caps = gst_caps_new_simple ("video/x-foo",
      "width", G_TYPE_INT, 2 * SRC_WIDTH, NULL);
  out_caps = gst_caps_copy (prop_caps);
  push_and_test (prop_caps, TRUE, TRUE, in_caps, out_caps);
}

GST_END_TEST;

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

  suite_add_tcase (s, tc_chain);
  tcase_add_test (tc_chain, test_n_join_n_replace);
  tcase_add_test (tc_chain, test_n_join_replace);
  tcase_add_test (tc_chain, test_join_n_replace_n_match);
  tcase_add_test (tc_chain, test_join_n_replace_match);
  tcase_add_test (tc_chain, test_join_replace_n_match);
  tcase_add_test (tc_chain, test_join_replace_match);

  return s;
}

GST_CHECK_MAIN (capssetter);
