/* GStreamer
 *
 * unit test for wavpackparse
 *
 * Copyright (c) 2006 Sebastian Dröge <slomo@circular-chaos.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., 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;

/* Wavpack file with 2 frames of silence */
guint8 test_file[] = {
  0x77, 0x76, 0x70, 0x6B, 0x62, 0x00, 0x00, 0x00,       /* first frame */
  0x04, 0x04, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00,       /* include RIFF header */
  0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00,
  0x05, 0x18, 0x80, 0x04, 0xFF, 0xAF, 0x80, 0x60,
  0x21, 0x16, 0x52, 0x49, 0x46, 0x46, 0x24, 0x90,
  0x01, 0x00, 0x57, 0x41, 0x56, 0x45, 0x66, 0x6D,
  0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00,
  0x01, 0x00, 0x44, 0xAC, 0x00, 0x00, 0x88, 0x58,
  0x01, 0x00, 0x02, 0x00, 0x10, 0x00, 0x64, 0x61,
  0x74, 0x61, 0x00, 0x90, 0x01, 0x00, 0x02, 0x00,
  0x03, 0x00, 0x04, 0x00, 0x05, 0x03, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x65, 0x02, 0x00, 0x00,
  0x00, 0x00, 0x8A, 0x02, 0x00, 0x00, 0xFF, 0x7F,
  0x00, 0xE4,
  0x77, 0x76, 0x70, 0x6B, 0x2E, 0x00, 0x00, 0x00,       /* second frame */
  0x04, 0x04, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
  0x00, 0x64, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00,
  0x05, 0x18, 0x80, 0x04, 0xFF, 0xAF, 0x80, 0x60,
  0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x03,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8A, 0x02,
  0x00, 0x00, 0xFF, 0x7F, 0x00, 0xE4,
};

static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/x-wavpack, "
        "depth = (int) 16, "
        "channels = (int) 1, "
        "rate = (int) 44100, " "framed = (boolean) TRUE"));

static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/x-wavpack"));

static GstElement *
setup_wavpackparse (void)
{
  GstElement *wavpackparse;

  GST_DEBUG ("setup_wavpackparse");

  wavpackparse = gst_check_setup_element ("wavpackparse");
  mysrcpad = gst_check_setup_src_pad (wavpackparse, &srctemplate);
  mysinkpad = gst_check_setup_sink_pad (wavpackparse, &sinktemplate);
  gst_pad_set_active (mysrcpad, TRUE);
  gst_pad_set_active (mysinkpad, TRUE);
  gst_check_setup_events (mysrcpad, wavpackparse, NULL, GST_FORMAT_BYTES);

  return wavpackparse;
}

static void
cleanup_wavpackparse (GstElement * wavpackparse)
{
  GST_DEBUG ("cleanup_wavpackparse");
  gst_element_set_state (wavpackparse, GST_STATE_NULL);

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

GST_START_TEST (test_parsing_valid_frames)
{
  GstElement *wavpackparse;
  GstBuffer *inbuffer, *outbuffer;
  int i, num_buffers;
  GstFormat format = GST_FORMAT_TIME;
  gint64 pos;

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

  inbuffer = gst_buffer_new_and_alloc (sizeof (test_file));
  gst_buffer_fill (inbuffer, 0, test_file, sizeof (test_file));

  /* should decode the buffer without problems */
  fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), GST_FLOW_OK);

  num_buffers = g_list_length (buffers);
  /* should get 2 buffers, each one complete wavpack frame */
  fail_unless_equals_int (num_buffers, 2);

  for (i = 0; i < num_buffers; ++i) {
    outbuffer = GST_BUFFER (buffers->data);
    fail_if (outbuffer == NULL);

    fail_unless (gst_buffer_memcmp (outbuffer, 0, "wvpk", 4) == 0,
        "Buffer contains no Wavpack frame");
    fail_unless_equals_int (GST_BUFFER_DURATION (outbuffer), 580498866);

    switch (i) {
      case 0:{
        fail_unless_equals_int (GST_BUFFER_TIMESTAMP (outbuffer), 0);
        break;
      }
      case 1:{
        fail_unless_equals_int (GST_BUFFER_TIMESTAMP (outbuffer), 580498866);
        break;
      }
    }

    buffers = g_list_remove (buffers, outbuffer);

    gst_buffer_unref (outbuffer);
    outbuffer = NULL;
  }

  fail_unless (gst_element_query_position (wavpackparse, format, &pos),
      "Position query failed");
  fail_unless_equals_int64 (pos, 580498866 * 2);
  fail_unless (gst_element_query_duration (wavpackparse, format, NULL),
      "Duration query failed");

  g_list_free (buffers);
  buffers = NULL;

  cleanup_wavpackparse (wavpackparse);
}

GST_END_TEST;

GST_START_TEST (test_parsing_invalid_first_header)
{
  GstElement *wavpackparse;
  GstBuffer *inbuffer, *outbuffer;
  int i, num_buffers;

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

  inbuffer = gst_buffer_new_and_alloc (sizeof (test_file));
  gst_buffer_fill (inbuffer, 0, test_file, sizeof (test_file));
  gst_buffer_memset (inbuffer, 0, 'k', 1);

  /* should decode the buffer without problems */
  fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), GST_FLOW_OK);

  num_buffers = g_list_length (buffers);

  /* should get 1 buffers, the second non-broken one */
  fail_unless_equals_int (num_buffers, 1);

  for (i = 0; i < num_buffers; ++i) {
    outbuffer = GST_BUFFER (buffers->data);
    fail_if (outbuffer == NULL);

    fail_unless (gst_buffer_memcmp (outbuffer, 0, "wvpk", 4) == 0,
        "Buffer contains no Wavpack frame");
    fail_unless_equals_int (GST_BUFFER_DURATION (outbuffer), 580498866);

    switch (i) {
      case 0:{
        fail_unless_equals_int (GST_BUFFER_TIMESTAMP (outbuffer), 580498866);
        break;
      }
    }

    buffers = g_list_remove (buffers, outbuffer);

    gst_buffer_unref (outbuffer);
    outbuffer = NULL;
  }

  g_list_free (buffers);
  buffers = NULL;

  cleanup_wavpackparse (wavpackparse);
}

GST_END_TEST;


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

  suite_add_tcase (s, tc_chain);
  tcase_add_test (tc_chain, test_parsing_valid_frames);
  tcase_add_test (tc_chain, test_parsing_invalid_first_header);

  return s;
}

int
main (int argc, char **argv)
{
  int nf;

  Suite *s = wavpackparse_suite ();
  SRunner *sr = srunner_create (s);

  gst_check_init (&argc, &argv);

  srunner_run_all (sr, CK_NORMAL);
  nf = srunner_ntests_failed (sr);
  srunner_free (sr);

  return nf;
}
