/* GStreamer
 *
 * unit test for GstMeta
 *
 * Copyright (C) <2009> Wim Taymans <wim.taymans@gmail.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., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#ifdef HAVE_VALGRIND_H
# include <valgrind/valgrind.h>
#else
# define RUNNING_ON_VALGRIND FALSE
#endif

#include <gst/check/gstcheck.h>

/* test metadata for PTS/DTS and duration */
typedef struct
{
  GstMeta meta;

  GstClockTime pts;
  GstClockTime dts;
  GstClockTime duration;
  GstClockTime clock_rate;
} GstMetaTest;

static GType gst_meta_test_api_get_type (void);
#define GST_META_TEST_API_TYPE (gst_meta_test_api_get_type())

static const GstMetaInfo *gst_meta_test_get_info (void);
#define GST_META_TEST_INFO (gst_meta_test_get_info())

#define GST_META_TEST_GET(buf) ((GstMetaTest *)gst_buffer_get_meta(buf,GST_META_TEST_API_TYPE))
#define GST_META_TEST_ADD(buf) ((GstMetaTest *)gst_buffer_add_meta(buf,GST_META_TEST_INFO,NULL))

#if 0
/* unused currently. This is a user function to fill the metadata with default
 * values. We don't call this from the init function because the user is mostly
 * likely going to override the values immediately after */
static void
gst_meta_test_init (GstMetaTest * meta)
{
  meta->pts = GST_CLOCK_TIME_NONE;
  meta->dts = GST_CLOCK_TIME_NONE;
  meta->duration = GST_CLOCK_TIME_NONE;
  meta->clock_rate = GST_SECOND;
}
#endif

static gboolean
test_init_func (GstMeta * meta, gpointer params, GstBuffer * buffer)
{
  GST_DEBUG ("init called on buffer %p, meta %p", buffer, meta);
  /* nothing to init really, the init function is mostly for allocating
   * additional memory or doing special setup as part of adding the metadata to
   * the buffer*/
  return TRUE;
}

static void
test_free_func (GstMeta * meta, GstBuffer * buffer)
{
  GST_DEBUG ("free called on buffer %p, meta %p", buffer, meta);
  /* nothing to free really */
}

static gboolean
test_transform_func (GstBuffer * transbuf, GstMeta * meta,
    GstBuffer * buffer, GQuark type, gpointer data)
{
  GstMetaTest *test, *tmeta = (GstMetaTest *) meta;

  GST_DEBUG ("transform %s called from buffer %p to %p, meta %p",
      g_quark_to_string (type), buffer, transbuf, meta);

  if (GST_META_TRANSFORM_IS_COPY (type)) {
    GstMetaTransformCopy *copy_data = data;

    test = GST_META_TEST_ADD (transbuf);

    if (copy_data->offset == 0) {
      /* same offset, copy timestamps */
      test->pts = tmeta->pts;
      test->dts = tmeta->dts;
      if (!copy_data->region) {
        fail_unless (gst_buffer_get_size (buffer) == copy_data->size);
        /* same size, copy duration */
        test->duration = tmeta->duration;
      } else {
        fail_unless (gst_buffer_get_size (buffer) > copy_data->size);
        /* else clear */
        test->duration = GST_CLOCK_TIME_NONE;
      }
    } else {
      fail_unless (copy_data->region == TRUE);
      test->pts = -1;
      test->dts = -1;
      test->duration = -1;
    }
    test->clock_rate = tmeta->clock_rate;
  }
  return TRUE;
}

static GType
gst_meta_test_api_get_type (void)
{
  static volatile GType type;
  static const gchar *tags[] = { "timing", NULL };

  if (g_once_init_enter (&type)) {
    GType _type = gst_meta_api_type_register ("GstMetaTestAPI", tags);
    g_once_init_leave (&type, _type);
  }
  return type;
}

static const GstMetaInfo *
gst_meta_test_get_info (void)
{
  static const GstMetaInfo *meta_test_info = NULL;

  if (g_once_init_enter (&meta_test_info)) {
    const GstMetaInfo *mi = gst_meta_register (GST_META_TEST_API_TYPE,
        "GstMetaTest",
        sizeof (GstMetaTest),
        test_init_func, test_free_func, test_transform_func);
    g_once_init_leave (&meta_test_info, mi);
  }
  return meta_test_info;
}

GST_START_TEST (test_meta_test)
{
  GstBuffer *buffer, *copy, *subbuf;
  GstMetaTest *meta;
  GstMapInfo info;

  buffer = gst_buffer_new_and_alloc (4);
  fail_if (buffer == NULL);

  fail_unless (gst_buffer_map (buffer, &info, GST_MAP_WRITE));
  fail_if (info.data == NULL);
  memset (info.data, 0, 4);
  gst_buffer_unmap (buffer, &info);

  /* add some metadata */
  meta = GST_META_TEST_ADD (buffer);
  fail_if (meta == NULL);
  /* fill some values */
  meta->pts = 1000;
  meta->dts = 2000;
  meta->duration = 1000;
  meta->clock_rate = 1000;

  /* copy of the buffer */
  copy = gst_buffer_copy (buffer);
  /* get metadata of the buffer */
  meta = GST_META_TEST_GET (copy);
  fail_if (meta == NULL);
  fail_if (meta->pts != 1000);
  fail_if (meta->dts != 2000);
  fail_if (meta->duration != 1000);
  fail_if (meta->clock_rate != 1000);
  gst_buffer_unref (copy);

  /* make subbuffer */
  subbuf = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, 0, 1);
  /* get metadata of the buffer */
  meta = GST_META_TEST_GET (subbuf);
  fail_if (meta == NULL);
  fail_if (meta->pts != 1000);
  fail_if (meta->dts != 2000);
  fail_if (meta->duration != -1);
  fail_if (meta->clock_rate != 1000);
  gst_buffer_unref (subbuf);

  /* make another subbuffer */
  subbuf = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, 1, 3);
  /* get metadata of the buffer */
  meta = GST_META_TEST_GET (subbuf);
  fail_if (meta == NULL);
  fail_if (meta->pts != -1);
  fail_if (meta->dts != -1);
  fail_if (meta->duration != -1);
  fail_if (meta->clock_rate != 1000);
  gst_buffer_unref (subbuf);

  /* clean up */
  gst_buffer_unref (buffer);
}

GST_END_TEST;

static gboolean
foreach_meta (GstBuffer * buffer, GstMeta ** meta, gpointer user_data)
{
  /* try to remove */
  *meta = NULL;
  return TRUE;
}

GST_START_TEST (test_meta_locked)
{
  GstBuffer *buffer;
  GstMetaTest *meta;

  buffer = gst_buffer_new_and_alloc (4);
  fail_if (buffer == NULL);

  /* add some metadata */
  meta = GST_META_TEST_ADD (buffer);
  fail_if (meta == NULL);
  GST_META_FLAG_SET (meta, GST_META_FLAG_LOCKED);

  ASSERT_CRITICAL (gst_buffer_remove_meta (buffer, (GstMeta *) meta));
  ASSERT_CRITICAL (gst_buffer_foreach_meta (buffer, foreach_meta, NULL));

  GST_META_FLAG_UNSET (meta, GST_META_FLAG_LOCKED);

  gst_buffer_remove_meta (buffer, (GstMeta *) meta);

  /* clean up */
  gst_buffer_unref (buffer);
}

GST_END_TEST;

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

  suite_add_tcase (s, tc_chain);
  tcase_add_test (tc_chain, test_meta_test);
  tcase_add_test (tc_chain, test_meta_locked);

  return s;
}

GST_CHECK_MAIN (gst_buffermeta);
