/* GStreamer
 *
 * Copyright (C) 2014 Samsung Electronics. All rights reserved.
 *   Author: Thiago Santos <ts.santos@sisa.samsung.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
#include <gst/gst.h>
#include <gst/check/gstcheck.h>
#include <gst/check/gstharness.h>
#include <gst/audio/audio.h>
#include <gst/app/app.h>

#define TEST_AUDIO_RATE 44100
#define TEST_AUDIO_CHANNELS 2
#define TEST_AUDIO_FORMAT "S16LE"

#define GST_AUDIO_ENCODER_TESTER_TYPE gst_audio_encoder_tester_get_type()
static GType gst_audio_encoder_tester_get_type (void);

typedef struct _GstAudioEncoderTester GstAudioEncoderTester;
typedef struct _GstAudioEncoderTesterClass GstAudioEncoderTesterClass;

struct _GstAudioEncoderTester
{
  GstAudioEncoder parent;
};

struct _GstAudioEncoderTesterClass
{
  GstAudioEncoderClass parent_class;
};

G_DEFINE_TYPE (GstAudioEncoderTester, gst_audio_encoder_tester,
    GST_TYPE_AUDIO_ENCODER);

static gboolean
gst_audio_encoder_tester_start (GstAudioEncoder * enc)
{
  return TRUE;
}

static gboolean
gst_audio_encoder_tester_stop (GstAudioEncoder * enc)
{
  return TRUE;
}

static gboolean
gst_audio_encoder_tester_set_format (GstAudioEncoder * enc, GstAudioInfo * info)
{
  GstCaps *caps;

  caps = gst_caps_new_simple ("audio/x-test-custom", "rate", G_TYPE_INT,
      TEST_AUDIO_RATE, "channels", G_TYPE_INT, TEST_AUDIO_CHANNELS, NULL);
  gst_audio_encoder_set_output_format (enc, caps);
  gst_caps_unref (caps);

  return TRUE;
}

static GstFlowReturn
gst_audio_encoder_tester_handle_frame (GstAudioEncoder * enc,
    GstBuffer * buffer)
{
  guint8 *data;
  GstMapInfo map;
  guint64 input_num;
  GstBuffer *output_buffer;

  if (buffer == NULL)
    return GST_FLOW_OK;

  gst_buffer_map (buffer, &map, GST_MAP_READ);
  input_num = *((guint64 *) map.data);
  gst_buffer_unmap (buffer, &map);

  data = g_malloc (sizeof (guint64));
  *(guint64 *) data = input_num;

  output_buffer = gst_buffer_new_wrapped (data, sizeof (guint64));
  GST_BUFFER_PTS (output_buffer) = GST_BUFFER_PTS (buffer);
  GST_BUFFER_DURATION (output_buffer) = GST_BUFFER_DURATION (buffer);

  return gst_audio_encoder_finish_frame (enc, output_buffer, TEST_AUDIO_RATE);
}

static void
gst_audio_encoder_tester_class_init (GstAudioEncoderTesterClass * klass)
{
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
  GstAudioEncoderClass *audioencoder_class = GST_AUDIO_ENCODER_CLASS (klass);

  static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
      GST_PAD_SINK, GST_PAD_ALWAYS,
      GST_STATIC_CAPS ("audio/x-raw"));

  static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src",
      GST_PAD_SRC, GST_PAD_ALWAYS,
      GST_STATIC_CAPS ("audio/x-test-custom"));

  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&sink_templ));
  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&src_templ));

  gst_element_class_set_metadata (element_class,
      "AudioEncoderTester", "Encoder/Audio", "yep", "me");

  audioencoder_class->start = gst_audio_encoder_tester_start;
  audioencoder_class->stop = gst_audio_encoder_tester_stop;
  audioencoder_class->handle_frame = gst_audio_encoder_tester_handle_frame;
  audioencoder_class->set_format = gst_audio_encoder_tester_set_format;
}

static void
gst_audio_encoder_tester_init (GstAudioEncoderTester * tester)
{
}

static GstHarness *
setup_audioencodertester (void)
{
  GstHarness * h;
  GstElement * enc;

  static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
      GST_PAD_SINK,
      GST_PAD_ALWAYS,
      GST_STATIC_CAPS ("audio/x-test-custom")
      );
  static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
      GST_PAD_SRC,
      GST_PAD_ALWAYS,
      GST_STATIC_CAPS ("audio/x-raw")
      );

  enc = g_object_new (GST_AUDIO_ENCODER_TESTER_TYPE, NULL);
  h = gst_harness_new_full (enc, &srctemplate, "sink", &sinktemplate, "src");

  gst_harness_set_src_caps (h,
      gst_caps_new_simple ("audio/x-raw",
      "rate", G_TYPE_INT, TEST_AUDIO_RATE,
      "channels", G_TYPE_INT, TEST_AUDIO_CHANNELS,
      "format", G_TYPE_STRING, TEST_AUDIO_FORMAT,
      "layout", G_TYPE_STRING, "interleaved",
      NULL));

  gst_object_unref (enc);
  return h;
}

static GstBuffer *
create_test_buffer (guint64 num)
{
  GstBuffer *buffer;
  guint64 *data;
  gsize size;
  guint64 samples;

  samples = TEST_AUDIO_RATE;
  size = 2 * 2 * samples;

  data = g_malloc0 (size);
  *data = num;

  buffer = gst_buffer_new_wrapped (data, size);

  GST_BUFFER_PTS (buffer) = num * GST_SECOND;
  GST_BUFFER_DURATION (buffer) = GST_SECOND;

  return buffer;
}

#define NUM_BUFFERS 100
GST_START_TEST (audioencoder_playback)
{
  GstBuffer *buffer;
  guint64 i;
  guint buffers_available;

  GstHarness * h = setup_audioencodertester ();

  /* push buffers, the data is actually a number so we can track them */
  for (i = 0; i < NUM_BUFFERS; i++) {
    fail_unless (gst_harness_push (h, create_test_buffer (i)) == GST_FLOW_OK);
  }

  fail_unless (gst_harness_push_event (h, gst_event_new_eos ()));

  /* check that all buffers were received by our source pad */
  buffers_available = gst_harness_buffers_in_queue (h);
  fail_unless_equals_int (NUM_BUFFERS, buffers_available);

  for (i = 0; i < buffers_available; i++) {
    GstMapInfo map;
    guint64 num;

    buffer = gst_harness_pull (h);

    gst_buffer_map (buffer, &map, GST_MAP_READ);

    num = *(guint64 *) map.data;
    fail_unless (i == num);
    fail_unless (GST_BUFFER_PTS (buffer) == i * GST_SECOND);
    fail_unless (GST_BUFFER_DURATION (buffer) == GST_SECOND);

    gst_buffer_unmap (buffer, &map);
    gst_buffer_unref (buffer);
  }

  gst_harness_teardown (h);
}

GST_END_TEST;


GST_START_TEST (audioencoder_flush_events)
{
  guint i;

  GstHarness *h = setup_audioencodertester ();

  /* push buffers, the data is actually a number so we can track them */
  for (i = 0; i < NUM_BUFFERS; i++) {
    if (i % 10 == 0) {
      GstTagList *tags;

      tags = gst_tag_list_new (GST_TAG_TRACK_NUMBER, i, NULL);
      fail_unless (gst_harness_push_event (h, gst_event_new_tag (tags)));
    } else {
      fail_unless (gst_harness_push (h, create_test_buffer (i)) == GST_FLOW_OK);
    }
  }

  fail_unless (gst_harness_push_event (h, gst_event_new_eos ()));

  /* make sure the usual events have been received */
  {
    GstEvent *sstart = gst_harness_pull_event (h);
    fail_unless (GST_EVENT_TYPE (sstart) == GST_EVENT_STREAM_START);
    gst_event_unref (sstart);
  }
  {
    GstEvent *caps_event = gst_harness_pull_event (h);
    fail_unless (GST_EVENT_TYPE (caps_event) == GST_EVENT_CAPS);
    gst_event_unref (caps_event);
  }
  {
    GstEvent *segment_event = gst_harness_pull_event (h);
    fail_unless (GST_EVENT_TYPE (segment_event) == GST_EVENT_SEGMENT);
    gst_event_unref (segment_event);
  }

  /* check that EOS was received */
  fail_unless (GST_PAD_IS_EOS (h->srcpad));
  fail_unless (gst_harness_push_event (h, gst_event_new_flush_start ()));
  fail_unless (GST_PAD_IS_EOS (h->srcpad));

  /* Check that we have tags */
  {
    GstEvent *tags = gst_pad_get_sticky_event (h->srcpad, GST_EVENT_TAG, 0);

    fail_unless (tags != NULL);
    gst_event_unref (tags);
  }

  /* Check that we still have a segment set */
  {
    GstEvent *segment =
        gst_pad_get_sticky_event (h->srcpad, GST_EVENT_SEGMENT, 0);

    fail_unless (segment != NULL);
    gst_event_unref (segment);
  }

  fail_unless (gst_harness_push_event (h, gst_event_new_flush_stop (TRUE)));
  fail_if (GST_PAD_IS_EOS (h->srcpad));

  /* Check that the segment was flushed on FLUSH_STOP */
  {
    GstEvent *segment =
        gst_pad_get_sticky_event (h->srcpad, GST_EVENT_SEGMENT, 0);

    fail_unless (segment == NULL);
  }

  /* Check the tags were not lost on FLUSH_STOP */
  {
    GstEvent *tags = gst_pad_get_sticky_event (h->srcpad, GST_EVENT_TAG, 0);

    fail_unless (tags != NULL);
    gst_event_unref (tags);

  }

  gst_harness_teardown (h);
}

GST_END_TEST;

/* make sure tags sent right before eos are pushed */
GST_START_TEST (audioencoder_tags_before_eos)
{
  GstTagList *tags;
  GstEvent *event;

  GstHarness *h = setup_audioencodertester ();

  /* push buffer */
  fail_unless (gst_harness_push (h, create_test_buffer (0)) == GST_FLOW_OK);

  /* clean received events list */
  while ((event = gst_harness_try_pull_event (h)))
    gst_event_unref (event);

  /* push a tag event */
  tags = gst_tag_list_new (GST_TAG_COMMENT, "test-comment", NULL);
  fail_unless (gst_harness_push_event (h, gst_event_new_tag (tags)));

  fail_unless (gst_harness_push_event (h, gst_event_new_eos ()));

  /* check that the tag was received */
  {
    GstEvent *tag_event = gst_harness_pull_event (h);
    gchar *str;

    fail_unless (GST_EVENT_TYPE (tag_event) == GST_EVENT_TAG);
    gst_event_parse_tag (tag_event, &tags);
    fail_unless (gst_tag_list_get_string (tags, GST_TAG_COMMENT, &str));
    fail_unless (strcmp (str, "test-comment") == 0);
    g_free (str);
    gst_event_unref (tag_event);
  }

  gst_harness_teardown (h);
}

GST_END_TEST;

/* make sure events sent right before eos are pushed */
GST_START_TEST (audioencoder_events_before_eos)
{
  GstMessage *msg;
  GstEvent *event;

  GstHarness *h = setup_audioencodertester ();

  /* push buffer */
  fail_unless (gst_harness_push (h, create_test_buffer (0)) == GST_FLOW_OK);

  /* clean received events list */
  while ((event = gst_harness_try_pull_event (h)))
    gst_event_unref (event);

  /* push a serialized event */
  msg = gst_message_new_element (GST_OBJECT (h->element),
      gst_structure_new_empty ("test"));
  fail_unless (gst_harness_push_event (h,
          gst_event_new_sink_message ("sink-test", msg)));
  gst_message_unref (msg);

  fail_unless (gst_harness_push_event (h, gst_event_new_eos ()));

  /* check that the tag was received */
  {
    GstEvent *msg_event = gst_harness_pull_event (h);
    const GstStructure *structure;

    fail_unless (GST_EVENT_TYPE (msg_event) == GST_EVENT_SINK_MESSAGE);
    fail_unless (gst_event_has_name (msg_event, "sink-test"));
    gst_event_parse_sink_message (msg_event, &msg);
    structure = gst_message_get_structure (msg);
    fail_unless (gst_structure_has_name (structure, "test"));
    gst_message_unref (msg);
    gst_event_unref (msg_event);
  }

  gst_harness_teardown (h);
}

GST_END_TEST;

static Suite *
gst_audioencoder_suite (void)
{
  Suite *s = suite_create ("GstAudioEncoder");
  TCase *tc = tcase_create ("general");

  suite_add_tcase (s, tc);
  tcase_add_test (tc, audioencoder_playback);

  tcase_add_test (tc, audioencoder_tags_before_eos);
  tcase_add_test (tc, audioencoder_events_before_eos);
  tcase_add_test (tc, audioencoder_flush_events);

  return s;
}

GST_CHECK_MAIN (gst_audioencoder);
