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

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

