/* GStreamer
 * Copyright (C) 2011 Stefan Kost <ensonic@users.sf.net>
 *
 * gstelementfactory.c: Unit test for GstElementFactory
 *
 * 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/gst_private.h"

#include <gst/check/gstcheck.h>

static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/x-raw, " "channels = (int) [ 1, 6 ]")
    );
static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/x-raw, " "channels = (int) [ 1, 6 ]")
    );

static void
setup_pad_template (GstElementFactory * factory, GstStaticPadTemplate * tmpl)
{
  GstStaticPadTemplate *template;

  template = g_slice_dup (GstStaticPadTemplate, tmpl);
  factory->staticpadtemplates = g_list_append (factory->staticpadtemplates,
      template);
  factory->numpadtemplates++;
}

static GstElementFactory *
setup_factory (void)
{
  GstPluginFeature *feature;
  GstElementFactory *factory;

  feature = g_object_newv (GST_TYPE_ELEMENT_FACTORY, 0, NULL);
  gst_plugin_feature_set_name (feature, "test");

  factory = GST_ELEMENT_FACTORY_CAST (feature);
#if 0
  gst_element_class_set_metadata (factory, "test", "test", "test", "test");
#endif

  setup_pad_template (factory, &sink_template);
  setup_pad_template (factory, &src_template);

  return factory;
}

/* create a basic factory */
GST_START_TEST (test_create)
{
  GstElementFactory *factory;

  factory = setup_factory ();
  fail_if (factory == NULL);

  g_object_unref (factory);
}

GST_END_TEST;

/* test if the factory can accept some caps */
GST_START_TEST (test_can_sink_any_caps)
{
  GstElementFactory *factory;
  GstCaps *caps;
  gboolean res;

  factory = setup_factory ();
  fail_if (factory == NULL);

  caps = gst_caps_new_empty_simple ("audio/x-raw");
  fail_if (caps == NULL);
  res = gst_element_factory_can_sink_any_caps (factory, caps);
  fail_if (!res);
  gst_caps_unref (caps);

  g_object_unref (factory);
}

GST_END_TEST;

/* test if the factory is compatible with some caps */
GST_START_TEST (test_can_sink_all_caps)
{
  GstElementFactory *factory;
  GstCaps *caps;
  gboolean res;

  factory = setup_factory ();
  fail_if (factory == NULL);

  caps = gst_caps_new_empty_simple ("audio/x-raw");
  fail_if (caps == NULL);
  res = gst_element_factory_can_sink_all_caps (factory, caps);
  fail_if (res);
  gst_caps_unref (caps);

  g_object_unref (factory);
}

GST_END_TEST;

/* check if the elementfactory of a class is filled (see #131079) */
GST_START_TEST (test_class)
{
  GstElementClass *klass;
  GstElementFactory *factory, *tmp;
  GType type;

  GST_DEBUG ("finding factory for queue");
  factory = gst_element_factory_find ("queue");
  fail_if (factory == NULL);

  /* it may already be loaded if check is being run with CK_FORK=no */
  if (!GST_PLUGIN_FEATURE (factory)->loaded) {
    GST_DEBUG ("getting the type");
    /* feature is not loaded, should return 0 as the type */
    type = gst_element_factory_get_element_type (factory);
    fail_if (type != 0);
  }

  GST_DEBUG ("now loading the plugin");
  tmp =
      GST_ELEMENT_FACTORY (gst_plugin_feature_load (GST_PLUGIN_FEATURE
          (factory)));
  fail_if (tmp == NULL);

  gst_object_unref (factory);
  factory = tmp;

  /* feature is now loaded */
  type = gst_element_factory_get_element_type (factory);
  fail_if (type == 0);

  klass = g_type_class_ref (factory->type);
  fail_if (klass == NULL);

  GST_DEBUG ("checking the element factory class field");
  /* and elementfactory is filled in */
  fail_if (klass->elementfactory == NULL);
  fail_if (klass->elementfactory != factory);

  gst_object_unref (factory);
}

GST_END_TEST;


static Suite *
gst_element_factory_suite (void)
{
  Suite *s = suite_create ("GstElementFactory");
  TCase *tc_chain = tcase_create ("element-factory tests");

  suite_add_tcase (s, tc_chain);
  tcase_add_test (tc_chain, test_class);
  tcase_add_test (tc_chain, test_create);
  tcase_add_test (tc_chain, test_can_sink_any_caps);
  tcase_add_test (tc_chain, test_can_sink_all_caps);

  return s;
}

GST_CHECK_MAIN (gst_element_factory);
