/* GStreamer
 *
 * unit test for vorbisdec
 *
 * Copyright (C) <2005> Thomas Vander Stichele <thomas at apestaart dot 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 <glib.h>

#include <vorbis/codec.h>
#include <vorbis/vorbisenc.h>

#include <gst/gsttagsetter.h>
#include <gst/check/gstcheck.h>

/* a valid first header packet */
static guchar identification_header[30] = {
  1,                            /* packet_type */
  'v', 'o', 'r', 'b', 'i', 's',
  0, 0, 0, 0,                   /* vorbis_version */
  2,                            /* audio_channels */
  0x44, 0xac, 0, 0,             /* sample_rate */
  0xff, 0xff, 0xff, 0xff,       /* bitrate_maximum */
  0x00, 0xee, 0x02, 0x00,       /* bitrate_nominal */
  0xff, 0xff, 0xff, 0xff,       /* bitrate_minimum */
  0xb8,                         /* blocksize_0, blocksize_1 */
  0x01                          /* framing_flag */
};

static guchar artist_comment_header[] = {
  3,                            /* packet_type */
  'v', 'o', 'r', 'b', 'i', 's',
  2, 0, 0, 0,                   /* vendor_length */
  'm', 'e',
  1, 0, 0, 0,                   /* user_comment_list_length */
  9, 0, 0, 0,                   /* length comment[0] */
  'A', 'R', 'T', 'I', 'S', 'T', '=', 'm', 'e',
  0x01,                         /* framing bit */
};

static guchar title_comment_header[] = {
  3,                            /* packet_type */
  'v', 'o', 'r', 'b', 'i', 's',
  2, 0, 0, 0,                   /* vendor_length */
  'm', 'e',
  1, 0, 0, 0,                   /* user_comment_list_length */
  12, 0, 0, 0,                  /* length comment[0] */
  'T', 'I', 'T', 'L', 'E', '=', 'f', 'o', 'o', 'b', 'a', 'r',
  0x01,                         /* framing bit */
};

static guchar empty_comment_header[] = {
  3,                            /* packet_type */
  'v', 'o', 'r', 'b', 'i', 's',
  2, 0, 0, 0,                   /* vendor_length */
  'm', 'e',
  0, 0, 0, 0,                   /* user_comment_list_length */
  0x01,                         /* framing bit */
};


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 GstPad *mysrcpad, *mysinkpad;
static GAsyncQueue *pending_buffers;
static gulong id;


static GstElement *
setup_vorbistag (void)
{
  GstElement *vorbistag;
  GstCaps *caps;

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

  caps = gst_caps_new_empty_simple ("audio/x-vorbis");
  gst_check_setup_events (mysrcpad, vorbistag, caps, GST_FORMAT_TIME);
  gst_caps_unref (caps);

  gst_pad_set_active (mysinkpad, TRUE);

  return vorbistag;
}

static void
cleanup_vorbistag (GstElement * vorbistag)
{
  GST_DEBUG ("cleanup_vorbistag");
  gst_element_set_state (vorbistag, GST_STATE_NULL);

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


static GstPadProbeReturn
buffer_probe (GstPad * pad, GstPadProbeInfo * info, gpointer unused)
{
  GstBuffer *buffer = GST_PAD_PROBE_INFO_BUFFER (info);

  g_async_queue_push (pending_buffers, gst_buffer_ref (buffer));

  return GST_PAD_PROBE_OK;
}

static void
start_pipeline (GstElement * element)
{
  id = gst_pad_add_probe (mysinkpad, GST_PAD_PROBE_TYPE_BUFFER,
      (GstPadProbeCallback) buffer_probe, NULL, NULL);

  pending_buffers = g_async_queue_new ();
  gst_element_set_state (element, GST_STATE_PLAYING);
}

static GstBuffer *
get_buffer (void)
{
  return GST_BUFFER (g_async_queue_pop (pending_buffers));
}

static void
stop_pipeline (GstElement * element)
{
  GstBuffer *buf;

  while ((buf = g_async_queue_try_pop (pending_buffers)))
    gst_buffer_unref (buf);

  gst_pad_remove_probe (mysinkpad, id);
  id = 0;

  gst_element_set_state (element, GST_STATE_NULL);

  while ((buf = g_async_queue_try_pop (pending_buffers)))
    gst_buffer_unref (buf);

  g_async_queue_unref (pending_buffers);
  pending_buffers = NULL;
}

static void
compare_buffer (GstBuffer * buf, const guint8 * data, gsize size)
{
  GstMapInfo map;

  gst_buffer_map (buf, &map, GST_MAP_READ);
  fail_unless_equals_int (map.size, size);
  fail_unless_equals_int (memcmp (map.data, data, size), 0);
  gst_buffer_unmap (buf, &map);
}

static vorbis_comment vc;
static vorbis_dsp_state vd;
static vorbis_info vi;
static vorbis_block vb;

static GstBuffer *
_create_codebook_header_buffer (void)
{
  GstBuffer *buffer;
  ogg_packet header;
  ogg_packet header_comm;
  ogg_packet header_code;

  vorbis_info_init (&vi);
  vorbis_encode_setup_vbr (&vi, 1, 44000, 0.5);
  vorbis_encode_setup_init (&vi);
  vorbis_analysis_init (&vd, &vi);
  vorbis_block_init (&vd, &vb);
  vorbis_comment_init (&vc);
  vorbis_analysis_headerout (&vd, &vc, &header, &header_comm, &header_code);

  buffer = gst_buffer_new_and_alloc (header_code.bytes);
  gst_buffer_fill (buffer, 0, header_code.packet, header_code.bytes);

  return buffer;
}

static GstBuffer *
_create_audio_buffer (void)
{
  GstBuffer *buffer;
  ogg_packet packet;
  float **vorbis_buffer G_GNUC_UNUSED;

  vorbis_buffer = vorbis_analysis_buffer (&vd, 0);
  vorbis_analysis_wrote (&vd, 0);
  vorbis_analysis_blockout (&vd, &vb);
  vorbis_analysis (&vb, NULL);
  vorbis_bitrate_addblock (&vb);
  vorbis_bitrate_flushpacket (&vd, &packet);
  buffer = gst_buffer_new_and_alloc (packet.bytes);
  gst_buffer_fill (buffer, 0, packet.packet, packet.bytes);
  GST_DEBUG ("%p %ld", packet.packet, packet.bytes);

  vorbis_comment_clear (&vc);
  vorbis_block_clear (&vb);
  vorbis_dsp_clear (&vd);
  vorbis_info_clear (&vi);

  return buffer;
}


GST_START_TEST (test_empty_tags_set)
{
  GstTagList *tags;
  GstElement *vorbistag;
  GstBuffer *inbuffer, *outbuffer;

  vorbistag = setup_vorbistag ();

  tags = gst_tag_list_new_empty ();
  gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, GST_TAG_TITLE, "foobar", NULL);
  gst_tag_setter_merge_tags (GST_TAG_SETTER (vorbistag), tags,
      GST_TAG_MERGE_REPLACE);
  gst_tag_setter_set_tag_merge_mode (GST_TAG_SETTER (vorbistag),
      GST_TAG_MERGE_KEEP_ALL);
  gst_tag_list_unref (tags);

  start_pipeline (vorbistag);

  /* send identification header */
  inbuffer = gst_buffer_new_and_alloc (sizeof (identification_header));
  gst_buffer_fill (inbuffer, 0, identification_header,
      sizeof (identification_header));
  fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), GST_FLOW_OK);

  /* send empty comment buffer */
  inbuffer = gst_buffer_new_and_alloc (sizeof (empty_comment_header));
  gst_buffer_fill (inbuffer, 0, empty_comment_header,
      sizeof (empty_comment_header));
  fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), GST_FLOW_OK);

  /* send minimal codebook header and audio packers */
  inbuffer = _create_codebook_header_buffer ();
  fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), GST_FLOW_OK);
  inbuffer = _create_audio_buffer ();
  fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), GST_FLOW_OK);


  /* check identification header is unchanged */
  outbuffer = get_buffer ();
  compare_buffer (outbuffer, identification_header,
      sizeof (identification_header));
  gst_buffer_unref (outbuffer);

  /* check comment header is correct */
  outbuffer = get_buffer ();
  compare_buffer (outbuffer, title_comment_header,
      sizeof (title_comment_header));
  gst_buffer_unref (outbuffer);

  stop_pipeline (vorbistag);
  cleanup_vorbistag (vorbistag);
}

GST_END_TEST;


GST_START_TEST (test_filled_tags_unset)
{
  GstTagList *tags;
  GstElement *vorbistag;
  GstBuffer *inbuffer, *outbuffer;

  vorbistag = setup_vorbistag ();

  tags = gst_tag_list_new_empty ();
  gst_tag_setter_merge_tags (GST_TAG_SETTER (vorbistag), tags,
      GST_TAG_MERGE_REPLACE);
  gst_tag_setter_set_tag_merge_mode (GST_TAG_SETTER (vorbistag),
      GST_TAG_MERGE_KEEP_ALL);
  gst_tag_list_unref (tags);

  start_pipeline (vorbistag);

  /* send identification header */
  inbuffer = gst_buffer_new_and_alloc (sizeof (identification_header));
  gst_buffer_fill (inbuffer, 0, identification_header,
      sizeof (identification_header));
  fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), GST_FLOW_OK);

  /* send empty comment buffer */
  inbuffer = gst_buffer_new_and_alloc (sizeof (title_comment_header));
  gst_buffer_fill (inbuffer, 0, title_comment_header,
      sizeof (title_comment_header));
  fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), GST_FLOW_OK);

  /* send minimal codebook header and audio packers */
  inbuffer = _create_codebook_header_buffer ();
  fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), GST_FLOW_OK);
  inbuffer = _create_audio_buffer ();
  fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), GST_FLOW_OK);


  /* check identification header is unchanged */
  outbuffer = get_buffer ();
  compare_buffer (outbuffer, identification_header,
      sizeof (identification_header));
  gst_buffer_unref (outbuffer);

  /* check comment header is correct */
  outbuffer = get_buffer ();
  compare_buffer (outbuffer, empty_comment_header,
      sizeof (empty_comment_header));
  gst_buffer_unref (outbuffer);

  stop_pipeline (vorbistag);
  cleanup_vorbistag (vorbistag);
}

GST_END_TEST;


GST_START_TEST (test_filled_tags_change)
{
  GstTagList *tags;
  GstElement *vorbistag;
  GstBuffer *inbuffer, *outbuffer;

  vorbistag = setup_vorbistag ();

  tags = gst_tag_list_new_empty ();
  gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, GST_TAG_TITLE, "foobar", NULL);
  gst_tag_setter_merge_tags (GST_TAG_SETTER (vorbistag), tags,
      GST_TAG_MERGE_REPLACE);
  gst_tag_setter_set_tag_merge_mode (GST_TAG_SETTER (vorbistag),
      GST_TAG_MERGE_KEEP_ALL);
  gst_tag_list_unref (tags);

  start_pipeline (vorbistag);

  /* send identification header */
  inbuffer = gst_buffer_new_and_alloc (sizeof (identification_header));
  gst_buffer_fill (inbuffer, 0, identification_header,
      sizeof (identification_header));
  fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), GST_FLOW_OK);

  /* send empty comment buffer */
  inbuffer = gst_buffer_new_and_alloc (sizeof (artist_comment_header));
  gst_buffer_fill (inbuffer, 0, artist_comment_header,
      sizeof (artist_comment_header));
  fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), GST_FLOW_OK);

  /* send minimal codebook header and audio packers */
  inbuffer = _create_codebook_header_buffer ();
  fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), GST_FLOW_OK);
  inbuffer = _create_audio_buffer ();
  fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), GST_FLOW_OK);


  /* check identification header is unchanged */
  outbuffer = get_buffer ();
  compare_buffer (outbuffer, identification_header,
      sizeof (identification_header));
  gst_buffer_unref (outbuffer);

  /* check comment header is correct */
  outbuffer = get_buffer ();
  compare_buffer (outbuffer, title_comment_header,
      sizeof (title_comment_header));
  gst_buffer_unref (outbuffer);

  stop_pipeline (vorbistag);
  cleanup_vorbistag (vorbistag);
}

GST_END_TEST;



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

  suite_add_tcase (s, tc_chain);
  tcase_add_test (tc_chain, test_empty_tags_set);
  tcase_add_test (tc_chain, test_filled_tags_unset);
  tcase_add_test (tc_chain, test_filled_tags_change);

  return s;
}

GST_CHECK_MAIN (vorbistag)
