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

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

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

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

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

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

