/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
 *
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser 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
 *
 */

/* FIXME:
 *  - the segment_event caching and re-sending should not be needed any
 *    longer with sticky events
 */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#define GLIB_DISABLE_DEPRECATION_WARNINGS

#include <unistd.h>

#include "gsta2dpsink.h"

#include <gst/rtp/gstrtpbasepayload.h>

GST_DEBUG_CATEGORY_STATIC (gst_a2dp_sink_debug);
#define GST_CAT_DEFAULT gst_a2dp_sink_debug

#define A2DP_SBC_RTP_PAYLOAD_TYPE 1

#define DEFAULT_AUTOCONNECT TRUE

enum
{
  PROP_0,
  PROP_DEVICE,
  PROP_AUTOCONNECT,
  PROP_TRANSPORT
};

#define parent_class gst_a2dp_sink_parent_class
G_DEFINE_TYPE (GstA2dpSink, gst_a2dp_sink, GST_TYPE_BIN);

static GstStaticPadTemplate gst_a2dp_sink_factory =
    GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/x-sbc, "
        "rate = (int) { 16000, 32000, 44100, 48000 }, "
        "channels = (int) [ 1, 2 ], "
        "channel-mode = (string) { mono, dual, stereo, joint }, "
        "blocks = (int) { 4, 8, 12, 16 }, "
        "subbands = (int) { 4, 8 }, "
        "allocation-method = (string) { snr, loudness }, "
        "bitpool = (int) [ 2, " TEMPLATE_MAX_BITPOOL_STR " ]; " "audio/mpeg"));

static gboolean gst_a2dp_sink_handle_event (GstPad * pad,
    GstObject * pad_parent, GstEvent * event);
static gboolean gst_a2dp_sink_query (GstPad * pad, GstObject * parent,
    GstQuery * query);
static GstCaps *gst_a2dp_sink_get_caps (GstA2dpSink * self);
static gboolean gst_a2dp_sink_init_caps_filter (GstA2dpSink * self);
static gboolean gst_a2dp_sink_init_fakesink (GstA2dpSink * self);
static gboolean gst_a2dp_sink_remove_fakesink (GstA2dpSink * self);

static void
gst_a2dp_sink_finalize (GObject * obj)
{
  GstA2dpSink *self = GST_A2DP_SINK (obj);

  g_mutex_clear (&self->cb_mutex);

  G_OBJECT_CLASS (parent_class)->finalize (obj);
}

static GstState
gst_a2dp_sink_get_state (GstA2dpSink * self)
{
  GstState current, pending;

  gst_element_get_state (GST_ELEMENT (self), &current, &pending, 0);
  if (pending == GST_STATE_VOID_PENDING)
    return current;

  return pending;
}

/*
 * Helper function to create elements, add to the bin and link it
 * to another element.
 */
static GstElement *
gst_a2dp_sink_init_element (GstA2dpSink * self,
    const gchar * elementname, const gchar * name, GstElement * link_to)
{
  GstElement *element;
  GstState state;

  GST_LOG_OBJECT (self, "Initializing %s", elementname);

  element = gst_element_factory_make (elementname, name);
  if (element == NULL) {
    GST_DEBUG_OBJECT (self, "Couldn't create %s", elementname);
    return NULL;
  }

  if (!gst_bin_add (GST_BIN (self), element)) {
    GST_DEBUG_OBJECT (self, "failed to add %s to the bin", elementname);
    goto cleanup_and_fail;
  }

  state = gst_a2dp_sink_get_state (self);
  if (gst_element_set_state (element, state) == GST_STATE_CHANGE_FAILURE) {
    GST_DEBUG_OBJECT (self, "%s failed to go to playing", elementname);
    goto remove_element_and_fail;
  }

  if (link_to != NULL)
    if (!gst_element_link (link_to, element)) {
      GST_DEBUG_OBJECT (self, "couldn't link %s", elementname);
      goto remove_element_and_fail;
    }

  return element;

remove_element_and_fail:
  gst_element_set_state (element, GST_STATE_NULL);
  gst_bin_remove (GST_BIN (self), element);
  return NULL;

cleanup_and_fail:
  g_object_unref (G_OBJECT (element));

  return NULL;
}

static void
gst_a2dp_sink_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstA2dpSink *self = GST_A2DP_SINK (object);

  switch (prop_id) {
    case PROP_DEVICE:
      if (self->sink != NULL)
        gst_avdtp_sink_set_device (self->sink, g_value_get_string (value));

      g_free (self->device);
      self->device = g_value_dup_string (value);
      break;

    case PROP_TRANSPORT:
      if (self->sink != NULL)
        gst_avdtp_sink_set_transport (self->sink, g_value_get_string (value));

      g_free (self->transport);
      self->transport = g_value_dup_string (value);
      break;

    case PROP_AUTOCONNECT:
      self->autoconnect = g_value_get_boolean (value);

      if (self->sink != NULL)
        g_object_set (G_OBJECT (self->sink), "auto-connect",
            self->autoconnect, NULL);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_a2dp_sink_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstA2dpSink *self = GST_A2DP_SINK (object);
  gchar *device, *transport;

  switch (prop_id) {
    case PROP_DEVICE:
      if (self->sink != NULL) {
        device = gst_avdtp_sink_get_device (self->sink);
        if (device != NULL)
          g_value_take_string (value, device);
      }
      break;
    case PROP_AUTOCONNECT:
      if (self->sink != NULL)
        g_object_get (G_OBJECT (self->sink), "auto-connect",
            &self->autoconnect, NULL);

      g_value_set_boolean (value, self->autoconnect);
      break;
    case PROP_TRANSPORT:
      if (self->sink != NULL) {
        transport = gst_avdtp_sink_get_transport (self->sink);
        if (transport != NULL)
          g_value_take_string (value, transport);
      }
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static gboolean
gst_a2dp_sink_init_ghost_pad (GstA2dpSink * self)
{
  GstPad *capsfilter_pad;

  /* we search for the capsfilter sinkpad */
  capsfilter_pad = gst_element_get_static_pad (self->capsfilter, "sink");

  /* now we add a ghostpad */
  self->ghostpad = gst_ghost_pad_new ("sink", capsfilter_pad);
  g_object_unref (capsfilter_pad);

  /* the getcaps of our ghostpad must reflect the device caps */
  gst_pad_set_query_function (self->ghostpad, gst_a2dp_sink_query);

  /* we need to handle events on our own and we also need the eventfunc
   * of the ghostpad for forwarding calls */
  self->ghostpad_eventfunc = GST_PAD_EVENTFUNC (self->ghostpad);
  gst_pad_set_event_function (self->ghostpad, gst_a2dp_sink_handle_event);

  if (!gst_element_add_pad (GST_ELEMENT (self), self->ghostpad))
    GST_ERROR_OBJECT (self, "failed to add ghostpad");

  return TRUE;
}

static void
gst_a2dp_sink_remove_dynamic_elements (GstA2dpSink * self)
{
  if (self->rtp) {
    GST_LOG_OBJECT (self, "removing rtp element from the bin");
    if (!gst_bin_remove (GST_BIN (self), GST_ELEMENT (self->rtp)))
      GST_WARNING_OBJECT (self, "failed to remove rtp " "element from bin");
    else
      self->rtp = NULL;
  }
}

static GstStateChangeReturn
gst_a2dp_sink_change_state (GstElement * element, GstStateChange transition)
{
  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
  GstA2dpSink *self = GST_A2DP_SINK (element);

  switch (transition) {
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      self->taglist = gst_tag_list_new_empty ();

      gst_a2dp_sink_init_fakesink (self);
      break;

    case GST_STATE_CHANGE_NULL_TO_READY:
      self->sink_is_in_bin = FALSE;
      self->sink =
          GST_AVDTP_SINK (gst_element_factory_make ("avdtpsink", "avdtpsink"));
      if (self->sink == NULL) {
        GST_WARNING_OBJECT (self, "failed to create avdtpsink");
        return GST_STATE_CHANGE_FAILURE;
      }

      if (self->device != NULL)
        gst_avdtp_sink_set_device (self->sink, self->device);

      if (self->transport != NULL)
        gst_avdtp_sink_set_transport (self->sink, self->transport);

      g_object_set (G_OBJECT (self->sink), "auto-connect",
          self->autoconnect, NULL);

      ret = gst_element_set_state (GST_ELEMENT (self->sink), GST_STATE_READY);
      if (ret == GST_STATE_CHANGE_FAILURE) {
        g_clear_object (&self->sink);
      }
      break;
    default:
      break;
  }

  if (ret == GST_STATE_CHANGE_FAILURE)
    return ret;

  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);

  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      if (self->taglist) {
        gst_tag_list_unref (self->taglist);
        self->taglist = NULL;
      }
      if (self->segment_event != NULL) {
        gst_event_unref (self->segment_event);
        self->segment_event = NULL;
      }
      gst_a2dp_sink_remove_fakesink (self);
      break;

    case GST_STATE_CHANGE_READY_TO_NULL:
      if (self->sink_is_in_bin) {
        if (!gst_bin_remove (GST_BIN (self), GST_ELEMENT (self->sink)))
          GST_WARNING_OBJECT (self, "Failed to remove " "avdtpsink from bin");
      } else if (self->sink != NULL) {
        gst_element_set_state (GST_ELEMENT (self->sink), GST_STATE_NULL);
        g_object_unref (G_OBJECT (self->sink));
      }

      self->sink = NULL;

      gst_a2dp_sink_remove_dynamic_elements (self);
      break;
    default:
      break;
  }

  return ret;
}

static void
gst_a2dp_sink_class_init (GstA2dpSinkClass * klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);

  parent_class = g_type_class_peek_parent (klass);

  object_class->set_property = GST_DEBUG_FUNCPTR (gst_a2dp_sink_set_property);
  object_class->get_property = GST_DEBUG_FUNCPTR (gst_a2dp_sink_get_property);

  object_class->finalize = GST_DEBUG_FUNCPTR (gst_a2dp_sink_finalize);

  element_class->change_state = GST_DEBUG_FUNCPTR (gst_a2dp_sink_change_state);

  g_object_class_install_property (object_class, PROP_DEVICE,
      g_param_spec_string ("device", "Device",
          "Bluetooth remote device address", NULL, G_PARAM_READWRITE));

  g_object_class_install_property (object_class, PROP_AUTOCONNECT,
      g_param_spec_boolean ("auto-connect", "Auto-connect",
          "Automatically attempt to connect to device",
          DEFAULT_AUTOCONNECT, G_PARAM_READWRITE));

  g_object_class_install_property (object_class, PROP_TRANSPORT,
      g_param_spec_string ("transport", "Transport",
          "Use configured transport", NULL, G_PARAM_READWRITE));

  gst_element_class_set_static_metadata (element_class, "Bluetooth A2DP sink",
      "Sink/Audio", "Plays audio to an A2DP device",
      "Marcel Holtmann <marcel@holtmann.org>");

  GST_DEBUG_CATEGORY_INIT (gst_a2dp_sink_debug, "a2dpsink", 0,
      "A2DP sink element");

  gst_element_class_add_static_pad_template (element_class,
      &gst_a2dp_sink_factory);
}

GstCaps *
gst_a2dp_sink_get_device_caps (GstA2dpSink * self)
{
  return gst_avdtp_sink_get_device_caps (self->sink);
}

static GstCaps *
gst_a2dp_sink_get_caps (GstA2dpSink * self)
{
  GstCaps *caps;
  GstCaps *caps_aux;

  if (self->sink == NULL) {
    GST_DEBUG_OBJECT (self, "a2dpsink isn't initialized "
        "returning template caps");
    caps = gst_static_pad_template_get_caps (&gst_a2dp_sink_factory);
  } else {
    GST_LOG_OBJECT (self, "Getting device caps");
    caps = gst_a2dp_sink_get_device_caps (self);
    if (caps == NULL)
      caps = gst_static_pad_template_get_caps (&gst_a2dp_sink_factory);
  }
  caps_aux = gst_caps_copy (caps);
  g_object_set (self->capsfilter, "caps", caps_aux, NULL);
  gst_caps_unref (caps_aux);
  return caps;
}

static gboolean
gst_a2dp_sink_init_avdtp_sink (GstA2dpSink * self)
{
  GstElement *sink;

  /* check if we don't need a new sink */
  if (self->sink_is_in_bin)
    return TRUE;

  if (self->sink == NULL)
    sink = gst_element_factory_make ("avdtpsink", "avdtpsink");
  else
    sink = GST_ELEMENT (self->sink);

  if (sink == NULL) {
    GST_ERROR_OBJECT (self, "Couldn't create avdtpsink");
    return FALSE;
  }

  if (!gst_bin_add (GST_BIN (self), sink)) {
    GST_ERROR_OBJECT (self, "failed to add avdtpsink " "to the bin");
    goto cleanup_and_fail;
  }

  if (gst_element_set_state (sink, GST_STATE_READY) == GST_STATE_CHANGE_FAILURE) {
    GST_ERROR_OBJECT (self, "avdtpsink failed to go to ready");
    goto remove_element_and_fail;
  }

  if (!gst_element_link (GST_ELEMENT (self->rtp), sink)) {
    GST_ERROR_OBJECT (self, "couldn't link rtpsbcpay " "to avdtpsink");
    goto remove_element_and_fail;
  }

  self->sink = GST_AVDTP_SINK (sink);
  self->sink_is_in_bin = TRUE;
  g_object_set (G_OBJECT (self->sink), "device", self->device, NULL);
  g_object_set (G_OBJECT (self->sink), "transport", self->transport, NULL);

  gst_element_set_state (sink, GST_STATE_PAUSED);

  return TRUE;

remove_element_and_fail:
  gst_element_set_state (sink, GST_STATE_NULL);
  gst_bin_remove (GST_BIN (self), sink);
  return FALSE;

cleanup_and_fail:
  if (sink != NULL)
    g_object_unref (G_OBJECT (sink));

  return FALSE;
}

static gboolean
gst_a2dp_sink_init_rtp_sbc_element (GstA2dpSink * self)
{
  GstElement *rtppay;

  /* if we already have a rtp, we don't need a new one */
  if (self->rtp != NULL)
    return TRUE;

  rtppay = gst_a2dp_sink_init_element (self, "rtpsbcpay", "rtp",
      self->capsfilter);
  if (rtppay == NULL)
    return FALSE;

  self->rtp = rtppay;
  g_object_set (self->rtp, "min-frames", -1, NULL);

  gst_element_set_state (rtppay, GST_STATE_PAUSED);

  return TRUE;
}

static gboolean
gst_a2dp_sink_init_rtp_mpeg_element (GstA2dpSink * self)
{
  GstElement *rtppay;

  /* check if we don't need a new rtp */
  if (self->rtp)
    return TRUE;

  GST_LOG_OBJECT (self, "Initializing rtp mpeg element");
  /* if capsfilter is not created then we can't have our rtp element */
  if (self->capsfilter == NULL)
    return FALSE;

  rtppay = gst_a2dp_sink_init_element (self, "rtpmpapay", "rtp",
      self->capsfilter);
  if (rtppay == NULL)
    return FALSE;

  self->rtp = rtppay;

  gst_element_set_state (rtppay, GST_STATE_PAUSED);

  return TRUE;
}

static gboolean
gst_a2dp_sink_init_dynamic_elements (GstA2dpSink * self, GstCaps * caps)
{
  GstStructure *structure;
  GstEvent *event;
  GstPad *capsfilterpad;
  gboolean crc;
  gchar *mode = NULL;

  structure = gst_caps_get_structure (caps, 0);

  /* before everything we need to remove fakesink */
  gst_a2dp_sink_remove_fakesink (self);

  /* first, we need to create our rtp payloader */
  if (gst_structure_has_name (structure, "audio/x-sbc")) {
    GST_LOG_OBJECT (self, "sbc media received");
    if (!gst_a2dp_sink_init_rtp_sbc_element (self))
      return FALSE;
  } else if (gst_structure_has_name (structure, "audio/mpeg")) {
    GST_LOG_OBJECT (self, "mp3 media received");
    if (!gst_a2dp_sink_init_rtp_mpeg_element (self))
      return FALSE;
  } else {
    GST_ERROR_OBJECT (self, "Unexpected media type");
    return FALSE;
  }

  if (!gst_a2dp_sink_init_avdtp_sink (self))
    return FALSE;

  /* check if we should push the taglist FIXME should we push this?
   * we can send the tags directly if needed */
  if (self->taglist != NULL && gst_structure_has_name (structure, "audio/mpeg")) {

    event = gst_event_new_tag (self->taglist);

    /* send directly the crc */
    if (gst_tag_list_get_boolean (self->taglist, "has-crc", &crc))
      gst_avdtp_sink_set_crc (self->sink, crc);

    if (gst_tag_list_get_string (self->taglist, "channel-mode", &mode))
      gst_avdtp_sink_set_channel_mode (self->sink, mode);

    capsfilterpad = gst_ghost_pad_get_target (GST_GHOST_PAD (self->ghostpad));
    gst_pad_send_event (capsfilterpad, event);
    self->taglist = NULL;
    g_free (mode);
  }

  if (!gst_avdtp_sink_set_device_caps (self->sink, caps))
    return FALSE;

  g_object_set (self->rtp, "mtu",
      gst_avdtp_sink_get_link_mtu (self->sink), NULL);

#if 0
  /* we forward our new segment here if we have one (FIXME: not needed any more) */
  if (self->segment_event) {
    gst_pad_send_event (GST_BASE_RTP_PAYLOAD_SINKPAD (self->rtp),
        self->segment_event);
    self->segment_event = NULL;
  }
#endif

  return TRUE;
}

/* used for catching newsegment events while we don't have a sink, for
 * later forwarding it to the sink */
static gboolean
gst_a2dp_sink_handle_event (GstPad * pad, GstObject * pad_parent,
    GstEvent * event)
{
  GstA2dpSink *self;
  GstTagList *taglist = NULL;
  GstObject *parent;

  self = GST_A2DP_SINK (pad_parent);
  parent = gst_element_get_parent (GST_ELEMENT (self->sink));

  if (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT &&
      parent != GST_OBJECT_CAST (self)) {
    if (self->segment_event != NULL)
      gst_event_unref (self->segment_event);
    self->segment_event = gst_event_ref (event);

  } else if (GST_EVENT_TYPE (event) == GST_EVENT_TAG &&
      parent != GST_OBJECT_CAST (self)) {
    if (self->taglist == NULL)
      gst_event_parse_tag (event, &self->taglist);
    else {
      gst_event_parse_tag (event, &taglist);
      gst_tag_list_insert (self->taglist, taglist, GST_TAG_MERGE_REPLACE);
    }
  } else if (GST_EVENT_TYPE (event) == GST_EVENT_CAPS &&
      parent != GST_OBJECT_CAST (self)) {
    GstCaps *caps = NULL;

    /* FIXME: really check for parent != self above? */
    /* now we know the caps */
    gst_event_parse_caps (event, &caps);
    gst_a2dp_sink_init_dynamic_elements (self, caps);
  }

  if (parent != NULL)
    gst_object_unref (GST_OBJECT (parent));

  return self->ghostpad_eventfunc (self->ghostpad, GST_OBJECT (self), event);
}

static gboolean
gst_a2dp_sink_query (GstPad * pad, GstObject * parent, GstQuery * query)
{
  GstA2dpSink *sink = GST_A2DP_SINK (parent);
  gboolean ret;

  if (GST_QUERY_TYPE (query) == GST_QUERY_CAPS) {
    GstCaps *caps;

    caps = gst_a2dp_sink_get_caps (sink);
    gst_query_set_caps_result (query, caps);
    gst_caps_unref (caps);
    ret = TRUE;
  } else {
    ret = sink->ghostpad_queryfunc (pad, parent, query);
  }

  return ret;
}


static gboolean
gst_a2dp_sink_init_caps_filter (GstA2dpSink * self)
{
  GstElement *element;

  element = gst_element_factory_make ("capsfilter", "filter");
  if (element == NULL)
    goto failed;

  if (!gst_bin_add (GST_BIN (self), element))
    goto failed;

  self->capsfilter = element;
  return TRUE;

failed:
  GST_ERROR_OBJECT (self, "Failed to initialize caps filter");
  return FALSE;
}

static gboolean
gst_a2dp_sink_init_fakesink (GstA2dpSink * self)
{
  if (self->fakesink != NULL)
    return TRUE;

  g_mutex_lock (&self->cb_mutex);
  self->fakesink = gst_a2dp_sink_init_element (self, "fakesink",
      "fakesink", self->capsfilter);
  g_mutex_unlock (&self->cb_mutex);

  if (!self->fakesink)
    return FALSE;

  return TRUE;
}

static gboolean
gst_a2dp_sink_remove_fakesink (GstA2dpSink * self)
{
  g_mutex_lock (&self->cb_mutex);

  if (self->fakesink != NULL) {
    gst_element_set_locked_state (self->fakesink, TRUE);
    gst_element_set_state (self->fakesink, GST_STATE_NULL);

    gst_bin_remove (GST_BIN (self), self->fakesink);
    self->fakesink = NULL;
  }

  g_mutex_unlock (&self->cb_mutex);

  return TRUE;
}

static void
gst_a2dp_sink_init (GstA2dpSink * self)
{
  self->sink = NULL;
  self->fakesink = NULL;
  self->rtp = NULL;
  self->device = NULL;
  self->transport = NULL;
  self->autoconnect = DEFAULT_AUTOCONNECT;
  self->capsfilter = NULL;
  self->segment_event = NULL;
  self->taglist = NULL;
  self->ghostpad = NULL;
  self->sink_is_in_bin = FALSE;

  g_mutex_init (&self->cb_mutex);

  /* we initialize our capsfilter */
  gst_a2dp_sink_init_caps_filter (self);
  g_object_set (self->capsfilter, "caps",
      gst_static_pad_template_get_caps (&gst_a2dp_sink_factory), NULL);

  gst_a2dp_sink_init_fakesink (self);

  gst_a2dp_sink_init_ghost_pad (self);
}
