/* GStreamer unit tests for the srtp elements
 * Copyright (C) 2007 Tim-Philipp Müller <tim centricular net>
 * Copyright (C) 2008 Sebastian Dröge <slomo@circular-chaos.org>
 * Copyright (C) 2016 Collabora Ltd <vincent.penquerch@collabora.co.uk>
 *
 * 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
# include <valgrind/valgrind.h>
#endif

#include <gst/check/gstcheck.h>

#include <gst/check/gstharness.h>

GST_START_TEST (test_create_and_unref)
{
  GstElement *e;

  e = gst_element_factory_make ("dtlsenc", NULL);
  fail_unless (e != NULL);
  gst_element_set_state (e, GST_STATE_NULL);
  gst_object_unref (e);

  e = gst_element_factory_make ("dtlsdec", NULL);
  fail_unless (e != NULL);
  gst_element_set_state (e, GST_STATE_NULL);
  gst_object_unref (e);
}

GST_END_TEST;

static GMutex key_lock;
static GCond key_cond;
static int key_count;

static void
_on_key_received (GstElement * element, gpointer user_data)
{
  g_mutex_lock (&key_lock);
  key_count++;
  g_cond_broadcast (&key_cond);
  g_mutex_unlock (&key_lock);
}

static void
_wait_for_key_count_to_reach (int n)
{
  g_mutex_lock (&key_lock);
  while (key_count < n)
    g_cond_wait (&key_cond, &key_lock);
  g_mutex_unlock (&key_lock);
}

static gchar data[] = {
  0x00, 0x01, 0x02, 0x03,
};

GST_START_TEST (test_data_transfer)
{
  GstHarness *server, *client;
  GstElement *s_enc, *s_dec, *c_enc, *c_dec, *s_bin, *c_bin;
  GstPad *target, *ghost;
  GstBuffer *buffer, *buf2;

  /* setup a server and client for dtls negotiation */
  s_bin = gst_bin_new (NULL);
  c_bin = gst_bin_new (NULL);

  /* XXX: the element set states are needed to avoid a runtime warning:
   *
   *   'gst_dtls_connection_process: runtime check failed: (!priv->bio_buffer)'
   *
   * where the encoder needs to be started (and SSL initialized) before the
   * associated decoder receives any data and calls gst_dtls_connection_process().
   */
  s_dec = gst_element_factory_make ("dtlsdec", "server_dec");
  g_object_set (s_dec, "connection-id", "server", NULL);
  g_signal_connect (s_dec, "on-key-received", G_CALLBACK (_on_key_received),
      NULL);
  gst_element_set_state (s_dec, GST_STATE_PAUSED);
  gst_bin_add (GST_BIN (s_bin), s_dec);

  s_enc = gst_element_factory_make ("dtlsenc", "server_enc");
  g_object_set (s_enc, "connection-id", "server", NULL);
  g_signal_connect (s_enc, "on-key-received", G_CALLBACK (_on_key_received),
      NULL);
  gst_element_set_state (s_enc, GST_STATE_PAUSED);
  gst_bin_add (GST_BIN (c_bin), s_enc);

  c_dec = gst_element_factory_make ("dtlsdec", "client_dec");
  g_object_set (c_dec, "connection-id", "client", NULL);
  g_signal_connect (c_dec, "on-key-received", G_CALLBACK (_on_key_received),
      NULL);
  gst_element_set_state (c_dec, GST_STATE_PAUSED);
  gst_bin_add (GST_BIN (c_bin), c_dec);

  c_enc = gst_element_factory_make ("dtlsenc", "client_enc");
  g_object_set (c_enc, "connection-id", "client", "is-client", TRUE, NULL);
  g_signal_connect (c_enc, "on-key-received", G_CALLBACK (_on_key_received),
      NULL);
  gst_element_set_state (c_enc, GST_STATE_PAUSED);
  gst_bin_add (GST_BIN (s_bin), c_enc);

  gst_element_link_pads (s_enc, "src", c_dec, "sink");
  gst_element_link_pads (c_enc, "src", s_dec, "sink");

  target = gst_element_get_request_pad (c_dec, "src");
  ghost = gst_ghost_pad_new ("src", target);
  gst_element_add_pad (s_bin, ghost);
  gst_object_unref (target);

  target = gst_element_get_request_pad (s_enc, "sink");
  ghost = gst_ghost_pad_new ("sink", target);
  gst_element_add_pad (s_bin, ghost);
  gst_object_unref (target);

  target = gst_element_get_request_pad (s_dec, "src");
  ghost = gst_ghost_pad_new ("src", target);
  gst_element_add_pad (c_bin, ghost);
  gst_object_unref (target);

  target = gst_element_get_request_pad (c_enc, "sink");
  ghost = gst_ghost_pad_new ("sink", target);
  gst_element_add_pad (c_bin, ghost);
  gst_object_unref (target);

  server = gst_harness_new_with_element (s_bin, "sink", "src");
  client = gst_harness_new_with_element (c_bin, "sink", "src");

  gst_harness_set_src_caps_str (server, "application/data");
  gst_harness_set_src_caps_str (client, "application/data");

  _wait_for_key_count_to_reach (4);

  buffer = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY, data,
      G_N_ELEMENTS (data), 0, G_N_ELEMENTS (data), NULL, NULL);
  gst_harness_push (server, gst_buffer_ref (buffer));
  buf2 = gst_harness_pull (server);
  fail_unless_equals_int (0, gst_buffer_memcmp (buf2, 0, data,
          G_N_ELEMENTS (data)));
  gst_buffer_unref (buf2);

  gst_harness_play (client);
  gst_harness_push (client, gst_buffer_ref (buffer));
  buf2 = gst_harness_pull (client);
  fail_unless_equals_int (0, gst_buffer_memcmp (buf2, 0, data,
          G_N_ELEMENTS (data)));
  gst_buffer_unref (buf2);

  gst_object_unref (s_bin);
  gst_object_unref (c_bin);

  gst_buffer_unref (buffer);
  gst_harness_teardown (server);
  gst_harness_teardown (client);
}

GST_END_TEST;

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

  suite_add_tcase (s, tc_chain);
  tcase_add_test (tc_chain, test_create_and_unref);
  tcase_add_test (tc_chain, test_data_transfer);

  return s;
}

GST_CHECK_MAIN (dtls);
