/* GStreamer
 * Copyright (C) 2011 David A. Schleef <ds@schleef.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 Street, Suite 500,
 * Boston, MA 02110-1335, USA.
 */
/**
 * SECTION:element-gstinteraudiosink
 *
 * The interaudiosink element is an audio sink element.  It is used
 * in connection with a interaudiosrc element in a different pipeline,
 * similar to intervideosink and intervideosrc.
 *
 * <refsect2>
 * <title>Example launch line</title>
 * |[
 * gst-launch-1.0 -v audiotestsrc ! queue ! interaudiosink
 * ]|
 *
 * The interaudiosink element cannot be used effectively with gst-launch-1.0,
 * as it requires a second pipeline in the application to receive the
 * audio.
 * See the gstintertest.c example in the gst-plugins-bad source code for
 * more details.
 * </refsect2>
 */

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

#include <gst/gst.h>
#include <gst/base/gstbasesink.h>
#include <gst/audio/audio.h>
#include "gstinteraudiosink.h"
#include <string.h>

GST_DEBUG_CATEGORY_STATIC (gst_inter_audio_sink_debug_category);
#define GST_CAT_DEFAULT gst_inter_audio_sink_debug_category

/* prototypes */
static void gst_inter_audio_sink_set_property (GObject * object,
    guint property_id, const GValue * value, GParamSpec * pspec);
static void gst_inter_audio_sink_get_property (GObject * object,
    guint property_id, GValue * value, GParamSpec * pspec);
static void gst_inter_audio_sink_finalize (GObject * object);

static void gst_inter_audio_sink_get_times (GstBaseSink * sink,
    GstBuffer * buffer, GstClockTime * start, GstClockTime * end);
static gboolean gst_inter_audio_sink_start (GstBaseSink * sink);
static gboolean gst_inter_audio_sink_stop (GstBaseSink * sink);
static gboolean gst_inter_audio_sink_set_caps (GstBaseSink * sink,
    GstCaps * caps);
static gboolean gst_inter_audio_sink_event (GstBaseSink * sink,
    GstEvent * event);
static GstFlowReturn gst_inter_audio_sink_render (GstBaseSink * sink,
    GstBuffer * buffer);
static gboolean gst_inter_audio_sink_query (GstBaseSink * sink,
    GstQuery * query);

enum
{
  PROP_0,
  PROP_CHANNEL
};

#define DEFAULT_CHANNEL ("default")

/* pad templates */
static GstStaticPadTemplate gst_inter_audio_sink_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (GST_AUDIO_CAPS_MAKE (GST_AUDIO_FORMATS_ALL))
    );

/* class initialization */
#define parent_class gst_inter_audio_sink_parent_class
G_DEFINE_TYPE (GstInterAudioSink, gst_inter_audio_sink, GST_TYPE_BASE_SINK);

static void
gst_inter_audio_sink_class_init (GstInterAudioSinkClass * klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
  GstBaseSinkClass *base_sink_class = GST_BASE_SINK_CLASS (klass);

  GST_DEBUG_CATEGORY_INIT (gst_inter_audio_sink_debug_category,
      "interaudiosink", 0, "debug category for interaudiosink element");
  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&gst_inter_audio_sink_sink_template));

  gst_element_class_set_static_metadata (element_class,
      "Internal audio sink",
      "Sink/Audio",
      "Virtual audio sink for internal process communication",
      "David Schleef <ds@schleef.org>");

  gobject_class->set_property = gst_inter_audio_sink_set_property;
  gobject_class->get_property = gst_inter_audio_sink_get_property;
  gobject_class->finalize = gst_inter_audio_sink_finalize;
  base_sink_class->get_times =
      GST_DEBUG_FUNCPTR (gst_inter_audio_sink_get_times);
  base_sink_class->start = GST_DEBUG_FUNCPTR (gst_inter_audio_sink_start);
  base_sink_class->stop = GST_DEBUG_FUNCPTR (gst_inter_audio_sink_stop);
  base_sink_class->event = GST_DEBUG_FUNCPTR (gst_inter_audio_sink_event);
  base_sink_class->set_caps = GST_DEBUG_FUNCPTR (gst_inter_audio_sink_set_caps);
  base_sink_class->render = GST_DEBUG_FUNCPTR (gst_inter_audio_sink_render);
  base_sink_class->query = GST_DEBUG_FUNCPTR (gst_inter_audio_sink_query);

  g_object_class_install_property (gobject_class, PROP_CHANNEL,
      g_param_spec_string ("channel", "Channel",
          "Channel name to match inter src and sink elements",
          DEFAULT_CHANNEL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
}

static void
gst_inter_audio_sink_init (GstInterAudioSink * interaudiosink)
{
  interaudiosink->channel = g_strdup (DEFAULT_CHANNEL);
  interaudiosink->input_adapter = gst_adapter_new ();
}

void
gst_inter_audio_sink_set_property (GObject * object, guint property_id,
    const GValue * value, GParamSpec * pspec)
{
  GstInterAudioSink *interaudiosink = GST_INTER_AUDIO_SINK (object);

  switch (property_id) {
    case PROP_CHANNEL:
      g_free (interaudiosink->channel);
      interaudiosink->channel = g_value_dup_string (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
  }
}

void
gst_inter_audio_sink_get_property (GObject * object, guint property_id,
    GValue * value, GParamSpec * pspec)
{
  GstInterAudioSink *interaudiosink = GST_INTER_AUDIO_SINK (object);

  switch (property_id) {
    case PROP_CHANNEL:
      g_value_set_string (value, interaudiosink->channel);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
  }
}

void
gst_inter_audio_sink_finalize (GObject * object)
{
  GstInterAudioSink *interaudiosink = GST_INTER_AUDIO_SINK (object);

  /* clean up object here */
  g_free (interaudiosink->channel);
  gst_object_unref (interaudiosink->input_adapter);

  G_OBJECT_CLASS (gst_inter_audio_sink_parent_class)->finalize (object);
}

static void
gst_inter_audio_sink_get_times (GstBaseSink * sink, GstBuffer * buffer,
    GstClockTime * start, GstClockTime * end)
{
  GstInterAudioSink *interaudiosink = GST_INTER_AUDIO_SINK (sink);

  if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer)) {
    *start = GST_BUFFER_TIMESTAMP (buffer);
    if (GST_BUFFER_DURATION_IS_VALID (buffer)) {
      *end = *start + GST_BUFFER_DURATION (buffer);
    } else {
      if (interaudiosink->info.rate > 0) {
        *end = *start +
            gst_util_uint64_scale_int (gst_buffer_get_size (buffer), GST_SECOND,
            interaudiosink->info.rate * interaudiosink->info.bpf);
      }
    }
  }
}

static gboolean
gst_inter_audio_sink_start (GstBaseSink * sink)
{
  GstInterAudioSink *interaudiosink = GST_INTER_AUDIO_SINK (sink);

  GST_DEBUG_OBJECT (interaudiosink, "start");

  interaudiosink->surface = gst_inter_surface_get (interaudiosink->channel);
  g_mutex_lock (&interaudiosink->surface->mutex);
  memset (&interaudiosink->surface->audio_info, 0, sizeof (GstAudioInfo));

  /* We want to write latency-time before syncing has happened */
  /* FIXME: The other side can change this value when it starts */
  gst_base_sink_set_render_delay (sink,
      interaudiosink->surface->audio_latency_time);
  g_mutex_unlock (&interaudiosink->surface->mutex);

  return TRUE;
}

static gboolean
gst_inter_audio_sink_stop (GstBaseSink * sink)
{
  GstInterAudioSink *interaudiosink = GST_INTER_AUDIO_SINK (sink);

  GST_DEBUG_OBJECT (interaudiosink, "stop");

  g_mutex_lock (&interaudiosink->surface->mutex);
  gst_adapter_clear (interaudiosink->surface->audio_adapter);
  memset (&interaudiosink->surface->audio_info, 0, sizeof (GstAudioInfo));
  g_mutex_unlock (&interaudiosink->surface->mutex);

  gst_inter_surface_unref (interaudiosink->surface);
  interaudiosink->surface = NULL;

  gst_adapter_clear (interaudiosink->input_adapter);

  return TRUE;
}

static gboolean
gst_inter_audio_sink_set_caps (GstBaseSink * sink, GstCaps * caps)
{
  GstInterAudioSink *interaudiosink = GST_INTER_AUDIO_SINK (sink);
  GstAudioInfo info;

  if (!gst_audio_info_from_caps (&info, caps)) {
    GST_ERROR_OBJECT (sink, "Failed to parse caps %" GST_PTR_FORMAT, caps);
    return FALSE;
  }

  g_mutex_lock (&interaudiosink->surface->mutex);
  interaudiosink->surface->audio_info = info;
  interaudiosink->info = info;
  /* TODO: Ideally we would drain the source here */
  gst_adapter_clear (interaudiosink->surface->audio_adapter);
  g_mutex_unlock (&interaudiosink->surface->mutex);

  return TRUE;
}

static gboolean
gst_inter_audio_sink_event (GstBaseSink * sink, GstEvent * event)
{
  GstInterAudioSink *interaudiosink = GST_INTER_AUDIO_SINK (sink);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_EOS:{
      GstBuffer *tmp;
      guint n;

      if ((n = gst_adapter_available (interaudiosink->input_adapter)) > 0) {
        g_mutex_lock (&interaudiosink->surface->mutex);
        tmp = gst_adapter_take_buffer (interaudiosink->input_adapter, n);
        gst_adapter_push (interaudiosink->surface->audio_adapter, tmp);
        g_mutex_unlock (&interaudiosink->surface->mutex);
      }
      break;
    }
    default:
      break;
  }

  return GST_BASE_SINK_CLASS (parent_class)->event (sink, event);
}

static GstFlowReturn
gst_inter_audio_sink_render (GstBaseSink * sink, GstBuffer * buffer)
{
  GstInterAudioSink *interaudiosink = GST_INTER_AUDIO_SINK (sink);
  guint n, bpf;
  guint64 period_time, buffer_time;
  guint64 period_samples, buffer_samples;

  GST_DEBUG_OBJECT (interaudiosink, "render %" G_GSIZE_FORMAT,
      gst_buffer_get_size (buffer));
  bpf = interaudiosink->info.bpf;

  g_mutex_lock (&interaudiosink->surface->mutex);

  buffer_time = interaudiosink->surface->audio_buffer_time;
  period_time = interaudiosink->surface->audio_period_time;

  if (buffer_time < period_time) {
    GST_ERROR_OBJECT (interaudiosink,
        "Buffer time smaller than period time (%" GST_TIME_FORMAT " < %"
        GST_TIME_FORMAT ")", GST_TIME_ARGS (buffer_time),
        GST_TIME_ARGS (period_time));
    g_mutex_unlock (&interaudiosink->surface->mutex);
    return GST_FLOW_ERROR;
  }

  buffer_samples =
      gst_util_uint64_scale (buffer_time, interaudiosink->info.rate,
      GST_SECOND);
  period_samples =
      gst_util_uint64_scale (period_time, interaudiosink->info.rate,
      GST_SECOND);

  n = gst_adapter_available (interaudiosink->surface->audio_adapter) / bpf;
  while (n > buffer_samples) {
    GST_DEBUG_OBJECT (interaudiosink, "flushing %" GST_TIME_FORMAT,
        GST_TIME_ARGS (period_time));
    gst_adapter_flush (interaudiosink->surface->audio_adapter,
        period_samples * bpf);
    n -= period_samples;
  }

  n = gst_adapter_available (interaudiosink->input_adapter);
  if (period_samples * bpf > gst_buffer_get_size (buffer) + n) {
    gst_adapter_push (interaudiosink->input_adapter, gst_buffer_ref (buffer));
  } else {
    GstBuffer *tmp;

    if (n > 0) {
      tmp = gst_adapter_take_buffer (interaudiosink->input_adapter, n);
      gst_adapter_push (interaudiosink->surface->audio_adapter, tmp);
    }
    gst_adapter_push (interaudiosink->surface->audio_adapter,
        gst_buffer_ref (buffer));
  }
  g_mutex_unlock (&interaudiosink->surface->mutex);

  return GST_FLOW_OK;
}

static gboolean
gst_inter_audio_sink_query (GstBaseSink * sink, GstQuery * query)
{
  GstInterAudioSink *interaudiosink = GST_INTER_AUDIO_SINK (sink);
  gboolean ret;

  GST_DEBUG_OBJECT (sink, "query");

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_LATENCY:{
      gboolean live, us_live;
      GstClockTime min_l, max_l;

      GST_DEBUG_OBJECT (sink, "latency query");

      if ((ret =
              gst_base_sink_query_latency (GST_BASE_SINK_CAST (sink), &live,
                  &us_live, &min_l, &max_l))) {
        GstClockTime base_latency, min_latency, max_latency;

        /* we and upstream are both live, adjust the min_latency */
        if (live && us_live) {
          /* FIXME: The other side can change this value when it starts */
          base_latency = interaudiosink->surface->audio_latency_time;

          /* we cannot go lower than the buffer size and the min peer latency */
          min_latency = base_latency + min_l;
          /* the max latency is the max of the peer, we can delay an infinite
           * amount of time. */
          max_latency = (max_l == -1) ? -1 : (base_latency + max_l);

          GST_DEBUG_OBJECT (sink,
              "peer min %" GST_TIME_FORMAT ", our min latency: %"
              GST_TIME_FORMAT, GST_TIME_ARGS (min_l),
              GST_TIME_ARGS (min_latency));
          GST_DEBUG_OBJECT (sink,
              "peer max %" GST_TIME_FORMAT ", our max latency: %"
              GST_TIME_FORMAT, GST_TIME_ARGS (max_l),
              GST_TIME_ARGS (max_latency));
        } else {
          GST_DEBUG_OBJECT (sink,
              "peer or we are not live, don't care about latency");
          min_latency = min_l;
          max_latency = max_l;
        }
        gst_query_set_latency (query, live, min_latency, max_latency);
      }
      break;
    }
    default:
      ret =
          GST_BASE_SINK_CLASS (gst_inter_audio_sink_parent_class)->query (sink,
          query);
      break;
  }

  return ret;
}
