/*
 *
 *  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
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <unistd.h>
#include <pthread.h>

#include "gstpragma.h"
#include "gsta2dpsink.h"

GType gst_avdtp_sink_get_type(void);

GST_DEBUG_CATEGORY_STATIC(gst_a2dp_sink_debug);
#define GST_CAT_DEFAULT gst_a2dp_sink_debug

#define A2DP_SBC_RTP_PAYLOAD_TYPE 1
#define TEMPLATE_MAX_BITPOOL_STR "64"

#define DEFAULT_AUTOCONNECT TRUE

enum {
	PROP_0,
	PROP_DEVICE,
	PROP_AUTOCONNECT,
	PROP_TRANSPORT
};

GST_BOILERPLATE(GstA2dpSink, gst_a2dp_sink, GstBin, GST_TYPE_BIN);

static const GstElementDetails gst_a2dp_sink_details =
	GST_ELEMENT_DETAILS("Bluetooth A2DP sink",
				"Sink/Audio",
				"Plays audio to an A2DP device",
				"Marcel Holtmann <marcel@holtmann.org>");

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 ], "
				"mode = (string) { \"mono\", \"dual\", \"stereo\", \"joint\" }, "
				"blocks = (int) { 4, 8, 12, 16 }, "
				"subbands = (int) { 4, 8 }, "
				"allocation = (string) { \"snr\", \"loudness\" }, "
				"bitpool = (int) [ 2, "
				TEMPLATE_MAX_BITPOOL_STR " ]; "
				"audio/mpeg"
				));

static gboolean gst_a2dp_sink_handle_event(GstPad *pad, GstEvent *event);
static gboolean gst_a2dp_sink_set_caps(GstPad *pad, GstCaps *caps);
static GstCaps *gst_a2dp_sink_get_caps(GstPad *pad);
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_free(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_base_init(gpointer g_class)
{
	GstElementClass *element_class = GST_ELEMENT_CLASS(g_class);

	gst_element_class_set_details(element_class,
		&gst_a2dp_sink_details);
	gst_element_class_add_pad_template(element_class,
		gst_static_pad_template_get(&gst_a2dp_sink_factory));
}

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));

		if (self->device != NULL)
			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));

		if (self->transport != NULL)
			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(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_getcaps_function(GST_PAD(self->ghostpad),
				gst_a2dp_sink_get_caps);
	self->ghostpad_setcapsfunc = GST_PAD_SETCAPSFUNC(self->ghostpad);
	gst_pad_set_setcaps_function(GST_PAD(self->ghostpad),
			GST_DEBUG_FUNCPTR(gst_a2dp_sink_set_caps));

	/* 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(GST_PAD(self->ghostpad));
	gst_pad_set_event_function(GST_PAD(self->ghostpad),
			gst_a2dp_sink_handle_event);

	if (!gst_element_add_pad(GST_ELEMENT(self), GST_PAD(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();

		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);
		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_free(self->taglist);
			self->taglist = NULL;
		}
		if (self->newseg_event != NULL) {
			gst_event_unref(self->newseg_event);
			self->newseg_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_DEBUG_CATEGORY_INIT(gst_a2dp_sink_debug, "a2dpsink", 0,
				"A2DP sink element");
}

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(GstPad *pad)
{
	GstCaps *caps;
	GstCaps *caps_aux;
	GstA2dpSink *self = GST_A2DP_SINK(GST_PAD_PARENT(pad));

	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 = GST_BASE_RTP_PAYLOAD(rtppay);
	g_object_set(G_OBJECT(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 = GST_BASE_RTP_PAYLOAD(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(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(G_OBJECT(self->rtp), "mtu",
		gst_avdtp_sink_get_link_mtu(self->sink), NULL);

	/* we forward our new segment here if we have one */
	if (self->newseg_event) {
		gst_pad_send_event(GST_BASE_RTP_PAYLOAD_SINKPAD(self->rtp),
					self->newseg_event);
		self->newseg_event = NULL;
	}

	return TRUE;
}

static gboolean gst_a2dp_sink_set_caps(GstPad *pad, GstCaps *caps)
{
	GstA2dpSink *self;

	self = GST_A2DP_SINK(GST_PAD_PARENT(pad));
	GST_INFO_OBJECT(self, "setting caps");

	/* now we know the caps */
	gst_a2dp_sink_init_dynamic_elements(self, caps);

	return self->ghostpad_setcapsfunc(GST_PAD(self->ghostpad), caps);
}

/* 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, GstEvent *event)
{
	GstA2dpSink *self;
	GstTagList *taglist = NULL;
	GstObject *parent;

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

	if (GST_EVENT_TYPE(event) == GST_EVENT_NEWSEGMENT &&
			parent != GST_OBJECT_CAST(self)) {
		if (self->newseg_event != NULL)
			gst_event_unref(self->newseg_event);
		self->newseg_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);
		}
	}

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

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

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,
			GstA2dpSinkClass *klass)
{
	self->sink = NULL;
	self->fakesink = NULL;
	self->rtp = NULL;
	self->device = NULL;
	self->transport = NULL;
	self->autoconnect = DEFAULT_AUTOCONNECT;
	self->capsfilter = NULL;
	self->newseg_event = NULL;
	self->taglist = NULL;
	self->ghostpad = NULL;
	self->sink_is_in_bin = FALSE;

	self->cb_mutex = g_mutex_new();

	/* 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);

}

gboolean gst_a2dp_sink_plugin_init(GstPlugin *plugin)
{
	return gst_element_register(plugin, "a2dpsink",
			GST_RANK_MARGINAL, GST_TYPE_A2DP_SINK);
}

