/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2006-2010  Nokia Corporation
 *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
 *
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program 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 General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; 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 <stdint.h>
#include <stdbool.h>
#include <errno.h>

#include <bluetooth/bluetooth.h>
#include <bluetooth/sdp.h>

#include <glib.h>
#include <dbus/dbus.h>
#include <gdbus/gdbus.h>

#include "src/log.h"

#include "src/adapter.h"
#include "src/device.h"
#include "src/service.h"
#include "src/error.h"
#include "src/dbus-common.h"

#include "avdtp.h"
#include "media.h"
#include "a2dp.h"
#include "sink.h"

#define STREAM_SETUP_RETRY_TIMER 2

struct sink {
	struct btd_service *service;
	struct avdtp *session;
	struct avdtp_stream *stream;
	unsigned int cb_id;
	avdtp_session_state_t session_state;
	avdtp_state_t stream_state;
	sink_state_t state;
	unsigned int connect_id;
	unsigned int disconnect_id;
	unsigned int avdtp_callback_id;
};

struct sink_state_callback {
	sink_state_cb cb;
	struct btd_service *service;
	void *user_data;
	unsigned int id;
};

static GSList *sink_callbacks = NULL;

static char *str_state[] = {
	"SINK_STATE_DISCONNECTED",
	"SINK_STATE_CONNECTING",
	"SINK_STATE_CONNECTED",
	"SINK_STATE_PLAYING",
};

static void sink_set_state(struct sink *sink, sink_state_t new_state)
{
	struct btd_service *service = sink->service;
	struct btd_device *dev = btd_service_get_device(service);
	sink_state_t old_state = sink->state;
	GSList *l;

	sink->state = new_state;

	DBG("State changed %s: %s -> %s", device_get_path(dev),
				str_state[old_state], str_state[new_state]);

	for (l = sink_callbacks; l != NULL; l = l->next) {
		struct sink_state_callback *cb = l->data;

		if (cb->service != service)
			continue;

		cb->cb(service, old_state, new_state, cb->user_data);
	}

	if (new_state != SINK_STATE_DISCONNECTED)
		return;

	if (sink->session) {
		avdtp_unref(sink->session);
		sink->session = NULL;
	}
}

static void avdtp_state_callback(struct btd_device *dev,
					struct avdtp *session,
					avdtp_session_state_t old_state,
					avdtp_session_state_t new_state,
					void *user_data)
{
	struct sink *sink = user_data;

	switch (new_state) {
	case AVDTP_SESSION_STATE_DISCONNECTED:
		sink_set_state(sink, SINK_STATE_DISCONNECTED);
		break;
	case AVDTP_SESSION_STATE_CONNECTING:
		sink_set_state(sink, SINK_STATE_CONNECTING);
		break;
	case AVDTP_SESSION_STATE_CONNECTED:
		break;
	}

	sink->session_state = new_state;
}

static void stream_state_changed(struct avdtp_stream *stream,
					avdtp_state_t old_state,
					avdtp_state_t new_state,
					struct avdtp_error *err,
					void *user_data)
{
	struct btd_service *service = user_data;
	struct sink *sink = btd_service_get_user_data(service);

	if (err)
		return;

	switch (new_state) {
	case AVDTP_STATE_IDLE:
		btd_service_disconnecting_complete(sink->service, 0);

		if (sink->disconnect_id > 0) {
			a2dp_cancel(sink->disconnect_id);
			sink->disconnect_id = 0;
		}

		if (sink->session) {
			avdtp_unref(sink->session);
			sink->session = NULL;
		}
		sink->stream = NULL;
		sink->cb_id = 0;
		break;
	case AVDTP_STATE_OPEN:
		btd_service_connecting_complete(sink->service, 0);
		sink_set_state(sink, SINK_STATE_CONNECTED);
		break;
	case AVDTP_STATE_STREAMING:
		sink_set_state(sink, SINK_STATE_PLAYING);
		break;
	case AVDTP_STATE_CONFIGURED:
	case AVDTP_STATE_CLOSING:
	case AVDTP_STATE_ABORTING:
	default:
		break;
	}

	sink->stream_state = new_state;
}

static void stream_setup_complete(struct avdtp *session, struct a2dp_sep *sep,
					struct avdtp_stream *stream,
					struct avdtp_error *err, void *user_data)
{
	struct sink *sink = user_data;

	sink->connect_id = 0;

	if (stream)
		return;

	avdtp_unref(sink->session);
	sink->session = NULL;
	if (avdtp_error_category(err) == AVDTP_ERRNO
				&& avdtp_error_posix_errno(err) != EHOSTDOWN)
		btd_service_connecting_complete(sink->service, -EAGAIN);
	else
		btd_service_connecting_complete(sink->service, -EIO);
}

static void select_complete(struct avdtp *session, struct a2dp_sep *sep,
			GSList *caps, void *user_data)
{
	struct sink *sink = user_data;
	int id;

	sink->connect_id = 0;

	id = a2dp_config(session, sep, stream_setup_complete, caps, sink);
	if (id == 0)
		goto failed;

	sink->connect_id = id;
	return;

failed:
	btd_service_connecting_complete(sink->service, -EIO);

	avdtp_unref(sink->session);
	sink->session = NULL;
}

static void discovery_complete(struct avdtp *session, GSList *seps, struct avdtp_error *err,
				void *user_data)
{
	struct sink *sink = user_data;
	int id, perr;

	if (err) {
		avdtp_unref(sink->session);
		sink->session = NULL;
		if (avdtp_error_category(err) == AVDTP_ERRNO
				&& avdtp_error_posix_errno(err) != EHOSTDOWN) {
			perr = -EAGAIN;
		} else
			perr = -EIO;
		goto failed;
	}

	DBG("Discovery complete");

	id = a2dp_select_capabilities(sink->session, AVDTP_SEP_TYPE_SINK, NULL,
						select_complete, sink);
	if (id == 0) {
		perr = -EIO;
		goto failed;
	}

	sink->connect_id = id;
	return;

failed:
	btd_service_connecting_complete(sink->service, perr);
	avdtp_unref(sink->session);
	sink->session = NULL;
}

gboolean sink_setup_stream(struct btd_service *service, struct avdtp *session)
{
	struct sink *sink = btd_service_get_user_data(service);

	if (sink->connect_id > 0 || sink->disconnect_id > 0)
		return FALSE;

	if (session && !sink->session)
		sink->session = avdtp_ref(session);

	if (!sink->session)
		return FALSE;

	if (avdtp_discover(sink->session, discovery_complete, sink) < 0)
		return FALSE;

	return TRUE;
}

int sink_connect(struct btd_service *service)
{
	struct sink *sink = btd_service_get_user_data(service);

	if (!sink->session)
		sink->session = avdtp_get(btd_service_get_device(service));

	if (!sink->session) {
		DBG("Unable to get a session");
		return -EIO;
	}

	if (sink->connect_id > 0 || sink->disconnect_id > 0)
		return -EBUSY;

	if (sink->stream_state >= AVDTP_STATE_OPEN)
		return -EALREADY;

	if (!sink_setup_stream(service, NULL)) {
		DBG("Failed to create a stream");
		return -EIO;
	}

	DBG("stream creation in progress");

	return 0;
}

static void sink_free(struct btd_service *service)
{
	struct sink *sink = btd_service_get_user_data(service);

	if (sink->cb_id)
		avdtp_stream_remove_cb(sink->session, sink->stream,
					sink->cb_id);

	if (sink->session)
		avdtp_unref(sink->session);

	if (sink->connect_id > 0) {
		btd_service_connecting_complete(sink->service, -ECANCELED);
		a2dp_cancel(sink->connect_id);
		sink->connect_id = 0;
	}

	if (sink->disconnect_id > 0) {
		btd_service_disconnecting_complete(sink->service, -ECANCELED);
		a2dp_cancel(sink->disconnect_id);
		sink->disconnect_id = 0;
	}

	avdtp_remove_state_cb(sink->avdtp_callback_id);
	btd_service_unref(sink->service);

	g_free(sink);
}

void sink_unregister(struct btd_service *service)
{
	struct btd_device *dev = btd_service_get_device(service);

	DBG("%s", device_get_path(dev));

	sink_free(service);
}

int sink_init(struct btd_service *service)
{
	struct btd_device *dev = btd_service_get_device(service);
	struct sink *sink;

	DBG("%s", device_get_path(dev));

	sink = g_new0(struct sink, 1);

	sink->service = btd_service_ref(service);

	sink->avdtp_callback_id = avdtp_add_state_cb(dev, avdtp_state_callback,
									sink);

	btd_service_set_user_data(service, sink);

	return 0;
}

gboolean sink_is_active(struct btd_service *service)
{
	struct sink *sink = btd_service_get_user_data(service);

	if (sink->session)
		return TRUE;

	return FALSE;
}

gboolean sink_new_stream(struct btd_service *service, struct avdtp *session,
				struct avdtp_stream *stream)
{
	struct sink *sink = btd_service_get_user_data(service);

	if (sink->stream)
		return FALSE;

	if (!sink->session)
		sink->session = avdtp_ref(session);

	sink->stream = stream;

	sink->cb_id = avdtp_stream_add_cb(session, stream,
						stream_state_changed, service);

	return TRUE;
}

int sink_disconnect(struct btd_service *service)
{
	struct sink *sink = btd_service_get_user_data(service);

	if (!sink->session)
		return -ENOTCONN;

	/* cancel pending connect */
	if (sink->connect_id > 0) {
		a2dp_cancel(sink->connect_id);
		sink->connect_id = 0;
		btd_service_connecting_complete(sink->service, -ECANCELED);

		avdtp_unref(sink->session);
		sink->session = NULL;

		return 0;
	}

	/* disconnect already ongoing */
	if (sink->disconnect_id > 0)
		return -EBUSY;

	if (!sink->stream)
		return -ENOTCONN;

	return avdtp_close(sink->session, sink->stream, FALSE);
}

unsigned int sink_add_state_cb(struct btd_service *service, sink_state_cb cb,
								void *user_data)
{
	struct sink_state_callback *state_cb;
	static unsigned int id = 0;

	state_cb = g_new(struct sink_state_callback, 1);
	state_cb->cb = cb;
	state_cb->service = service;
	state_cb->user_data = user_data;
	state_cb->id = ++id;

	sink_callbacks = g_slist_append(sink_callbacks, state_cb);

	return state_cb->id;
}

gboolean sink_remove_state_cb(unsigned int id)
{
	GSList *l;

	for (l = sink_callbacks; l != NULL; l = l->next) {
		struct sink_state_callback *cb = l->data;
		if (cb && cb->id == id) {
			sink_callbacks = g_slist_remove(sink_callbacks, cb);
			g_free(cb);
			return TRUE;
		}
	}

	return FALSE;
}
