/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2006-2007  Nokia Corporation
 *  Copyright (C) 2004-2008  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 <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
#include <netinet/in.h>

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

#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>
#include <bluetooth/sdp.h>
#include <bluetooth/sdp_lib.h>

#include "dbus.h"
#include "dbus-helper.h"
#include "logging.h"
#include "textfile.h"

#include "error.h"
#include "ipc.h"
#include "device.h"
#include "avdtp.h"
#include "control.h"
#include "headset.h"
#include "sink.h"

static DBusHandlerResult device_get_address(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct device *device = data;
	DBusMessage *reply;
	char address[18], *ptr = address;

	reply = dbus_message_new_method_return(msg);
	if (!reply)
		return DBUS_HANDLER_RESULT_NEED_MEMORY;

	ba2str(&device->dst, address);

	dbus_message_append_args(reply, DBUS_TYPE_STRING, &ptr,
							DBUS_TYPE_INVALID);

	return send_message_and_unref(conn, reply);
}

static char *get_dev_name(DBusConnection *conn, const char *adapter_path,
				bdaddr_t *bda)
{
	DBusMessage *msg, *reply;
	DBusError derr;
	const char *name;
	char address[18], *addr_ptr = address, *ret;

	msg = dbus_message_new_method_call("org.bluez", adapter_path,
					"org.bluez.Adapter", "GetRemoteName");
	if (!msg)
		return NULL;

	ba2str(bda, address);
	dbus_message_append_args(msg, DBUS_TYPE_STRING, &addr_ptr,
					DBUS_TYPE_INVALID);

	dbus_error_init(&derr);
	reply = dbus_connection_send_with_reply_and_block(conn, msg, -1,
								&derr);
	dbus_message_unref(msg);

	if (dbus_error_is_set(&derr)) {
		error("%s GetRemoteName(): %s", adapter_path, derr.message);
		dbus_error_free(&derr);
		return NULL;
	}

	if (!dbus_message_get_args(reply, NULL,
					DBUS_TYPE_STRING, &name,
					DBUS_TYPE_INVALID))
		return NULL;

	ret = g_strdup(name);

	dbus_message_unref(reply);

	return ret;
}

static DBusHandlerResult device_get_name(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct device *dev = data;
	DBusMessage *reply;
	const char *name = dev->name ? dev->name : "";

	reply = dbus_message_new_method_return(msg);
	if (!reply)
		return DBUS_HANDLER_RESULT_NEED_MEMORY;

	dbus_message_append_args(reply, DBUS_TYPE_STRING, &name,
					DBUS_TYPE_INVALID);

	return send_message_and_unref(conn, reply);
}

static DBusHandlerResult device_get_adapter(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct device *device = data;
	DBusMessage *reply;
	char address[18], *ptr = address;

	reply = dbus_message_new_method_return(msg);
	if (!reply)
		return DBUS_HANDLER_RESULT_NEED_MEMORY;

	ba2str(&device->src, address);

	dbus_message_append_args(reply, DBUS_TYPE_STRING, &ptr,
							DBUS_TYPE_INVALID);

	return send_message_and_unref(conn, reply);
}


static DBusHandlerResult device_get_connected(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	DBusMessageIter iter, array_iter;
	struct device *device = data;
	DBusMessage *reply;
	const char *iface;

	reply = dbus_message_new_method_return(msg);
	if (!reply)
		return DBUS_HANDLER_RESULT_NEED_MEMORY;

	dbus_message_iter_init_append(reply, &iter);

	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
						DBUS_TYPE_STRING_AS_STRING,
						&array_iter);

	if (device->headset &&
			headset_get_state(device) >= HEADSET_STATE_CONNECTED) {
		iface = AUDIO_HEADSET_INTERFACE;
		dbus_message_iter_append_basic(&array_iter,
						DBUS_TYPE_STRING, &iface);
	}

	dbus_message_iter_close_container(&iter, &array_iter);

	return send_message_and_unref(conn, reply);
}

static DBusMethodVTable device_methods[] = {
	{ "GetAddress",			device_get_address,	"",	"s" },
	{ "GetName",			device_get_name,	"",	"s" },
	{ "GetAdapter",			device_get_adapter,	"",	"s" },
	{ "GetConnectedInterfaces",	device_get_connected,	"",	"as" },
	{ NULL, NULL, NULL, NULL }
};

static void device_free(struct device *dev)
{
	if (dev->headset)
		headset_free(dev);

	if (dev->sink)
		sink_free(dev);

	if (dev->control)
		control_free(dev);

	if (dev->conn)
		dbus_connection_unref(dev->conn);

	g_free(dev->adapter_path);
	g_free(dev->path);
	g_free(dev->name);

	g_free(dev);
}

static void device_unregister(DBusConnection *conn, void *data)
{
	struct device *device = data;

	info("Unregistered device path:%s", device->path);

	device_free(device);
}

char *find_adapter(DBusConnection *conn, bdaddr_t *src)
{
	DBusMessage *msg, *reply;
	DBusError derr;
	char address[18], *addr_ptr = address;
	char *path, *ret;

	msg = dbus_message_new_method_call("org.bluez", "/org/bluez",
						"org.bluez.Manager",
						"FindAdapter");
	if (!msg) {
		error("Unable to allocate new method call");
		return NULL;
	}

	ba2str(src, address);

	dbus_message_append_args(msg, DBUS_TYPE_STRING, &addr_ptr,
				 DBUS_TYPE_INVALID);

	dbus_error_init(&derr);
	reply = dbus_connection_send_with_reply_and_block(conn, msg, -1,
								&derr);

	dbus_message_unref(msg);

	if (dbus_error_is_set(&derr) ||
				dbus_set_error_from_message(&derr, reply)) {
		error("FindAdapter(%s) failed: %s", address, derr.message);
		dbus_error_free(&derr);
		return NULL;
	}

	dbus_error_init(&derr);
	dbus_message_get_args(reply, &derr,
				DBUS_TYPE_STRING, &path,
				DBUS_TYPE_INVALID);

	if (dbus_error_is_set(&derr)) {
		error("Unable to get message args");
		dbus_message_unref(reply);
		dbus_error_free(&derr);
		return FALSE;
	}

	ret = g_strdup(path);

	dbus_message_unref(reply);

	debug("Got path %s for adapter with address %s", ret, address);

	return ret;
}

struct device *device_register(DBusConnection *conn,
					const char *path, bdaddr_t *bda)
{
	struct device *dev;
	bdaddr_t src;
	int dev_id;

	if (!conn || !path)
		return NULL;

	bacpy(&src, BDADDR_ANY);
	dev_id = hci_get_route(&src);
	if ((dev_id < 0) || (hci_devba(dev_id, &src) < 0))
		return NULL;

	dev = g_new0(struct device, 1);

	dev->adapter_path = find_adapter(conn, &src);
	if (!dev->adapter_path) {
		device_free(dev);
		return NULL;
	}

	if (!dbus_connection_create_object_path(conn, path, dev,
							device_unregister)) {
		error("D-Bus failed to register %s path", path);
		device_free(dev);
		return NULL;
	}

	if (!dbus_connection_register_interface(conn, path,
			AUDIO_DEVICE_INTERFACE, device_methods, NULL, NULL)) {
		error("Failed to register %s interface to %s",
					AUDIO_DEVICE_INTERFACE, path);
		dbus_connection_destroy_object_path(conn, path);
		return NULL;
	}

	dev->name = get_dev_name(conn, dev->adapter_path, bda);
	dev->path = g_strdup(path);
	bacpy(&dev->dst, bda);
	bacpy(&dev->src, &src);
	bacpy(&dev->store, &src);
	dev->conn = dbus_connection_ref(conn);

	return dev;
}

int device_store(struct device *dev, gboolean is_default)
{
	char value[64];
	char filename[PATH_MAX + 1];
	char src_addr[18], dst_addr[18];
	int offset = 0;

	if (!dev->path)
		return -EINVAL;

	ba2str(&dev->dst, dst_addr);
	ba2str(&dev->store, src_addr);

	create_name(filename, PATH_MAX, STORAGEDIR, src_addr, "audio");
	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);

	if (is_default)
		textfile_put(filename, "default", dst_addr);
	if (dev->headset) {
		snprintf(value, 64, "headset ");
		offset += strlen("headset ");
	}
	if (dev->gateway) {
		snprintf(value + offset, 64 - offset, "gateway ");
		offset += strlen("gateway ");
	}
	if (dev->sink) {
		snprintf(value + offset, 64 - offset, "sink ");
		offset += strlen("sink ");
	}
	if (dev->source) {
		snprintf(value + offset, 64 - offset, "source ");
		offset += strlen("source ");
	}
	if (dev->control) {
		snprintf(value + offset, 64 - offset, "control ");
		offset += strlen("control ");
	}
	if (dev->target)
		snprintf(value + offset, 64 - offset, "target");

	return textfile_put(filename, dst_addr, value);
}

int device_remove_stored(struct device *dev)
{
	char filename[PATH_MAX + 1];
	char src_addr[18], dst_addr[18];

	ba2str(&dev->dst, dst_addr);
	ba2str(&dev->store, src_addr);

	create_name(filename, PATH_MAX, STORAGEDIR, src_addr, "audio");

	return textfile_del(filename, dst_addr);
}

void device_finish_sdp_transaction(struct device *dev)
{
	char address[18], *addr_ptr = address;
	DBusMessage *msg, *reply;
	DBusError derr;

	ba2str(&dev->dst, address);

	msg = dbus_message_new_method_call("org.bluez", dev->adapter_path,
						"org.bluez.Adapter",
						"FinishRemoteServiceTransaction");
	if (!msg) {
		error("Unable to allocate new method call");
		return;
	}

	dbus_message_append_args(msg, DBUS_TYPE_STRING, &addr_ptr,
				 DBUS_TYPE_INVALID);

	dbus_error_init(&derr);
	reply = dbus_connection_send_with_reply_and_block(dev->conn,
							msg, -1, &derr);

	dbus_message_unref(msg);

	if (dbus_error_is_set(&derr) ||
				dbus_set_error_from_message(&derr, reply)) {
		error("FinishRemoteServiceTransaction(%s) failed: %s",
						address, derr.message);
		dbus_error_free(&derr);
		return;
	}

	dbus_message_unref(reply);
}

#if 0
static avdtp_state_t ipc_to_avdtp_state(uint8_t ipc_state)
{
	switch (ipc_state) {
	case STATE_DISCONNECTED:
		return AVDTP_STATE_IDLE;
	case STATE_CONNECTING:
		return AVDTP_STATE_CONFIGURED;
	case STATE_CONNECTED:
		return AVDTP_STATE_OPEN;
	case STATE_STREAM_STARTING:
	case STATE_STREAMING:
		return AVDTP_STATE_STREAMING;
	default:
		error("Unknown ipc state");
		return AVDTP_STATE_IDLE;
	}
}

static headset_state_t ipc_to_hs_state(uint8_t ipc_state)
{
	switch (ipc_state) {
	case STATE_DISCONNECTED:
		return HEADSET_STATE_DISCONNECTED;
	case STATE_CONNECTING:
		return HEADSET_STATE_CONNECT_IN_PROGRESS;
	case STATE_CONNECTED:
		return HEADSET_STATE_CONNECTED;
	case STATE_STREAM_STARTING:
		return HEADSET_STATE_PLAY_IN_PROGRESS;
	case STATE_STREAMING:
		return HEADSET_STATE_PLAYING;
	default:
		error("Unknown ipc state");
		return HEADSET_STATE_DISCONNECTED;
	}
}

static uint8_t avdtp_to_ipc_state(avdtp_state_t state)
{
	switch (state) {
	case AVDTP_STATE_IDLE:
		return STATE_DISCONNECTED;
	case AVDTP_STATE_CONFIGURED:
		return STATE_CONNECTING;
	case AVDTP_STATE_OPEN:
		return STATE_CONNECTED;
	case AVDTP_STATE_STREAMING:
		return STATE_STREAMING;
	default:
		error("Unknown avdt state");
		return AVDTP_STATE_IDLE;
	}
}

static uint8_t hs_to_ipc_state(headset_state_t state)
{
	switch (state) {
	case HEADSET_STATE_DISCONNECTED:
		return STATE_DISCONNECTED;
	case HEADSET_STATE_CONNECT_IN_PROGRESS:
		return STATE_CONNECTING;
	case HEADSET_STATE_CONNECTED:
		return STATE_CONNECTED;
	case HEADSET_STATE_PLAY_IN_PROGRESS:
		return STATE_STREAMING;
	default:
		error("Unknown headset state");
		return AVDTP_STATE_IDLE;
	}
}

uint8_t device_get_state(struct device *dev)
{
	avdtp_state_t sink_state;
	headset_state_t hs_state;

	if (dev->sink && sink_is_active(dev)) {
		sink_state = sink_get_state(dev);
		return avdtp_to_ipc_state(sink_state);
	}
	else if (dev->headset && headset_is_active(dev)) {
		hs_state = headset_get_state(dev);
		return hs_to_ipc_state(hs_state);
	}
	else if (dev->control && control_is_active(dev))
		return STATE_CONNECTED;

	return STATE_DISCONNECTED;
}
#endif

gboolean device_is_connected(struct device *dev, const char *interface)
{
	if (!interface) {
		if ((dev->sink || dev->source) &&
			avdtp_is_connected(&dev->src, &dev->dst))
			return TRUE;

		if (dev->headset && headset_is_active(dev))
			return TRUE;
	}
	else if (!strcmp(interface, AUDIO_SINK_INTERFACE) && dev->sink &&
			avdtp_is_connected(&dev->src, &dev->dst))
		return TRUE;
	else if (!strcmp(interface, AUDIO_SOURCE_INTERFACE) && dev->source &&
			avdtp_is_connected(&dev->src, &dev->dst))
		return TRUE;
	else if (!strcmp(interface, AUDIO_HEADSET_INTERFACE) && dev->headset &&
			headset_is_active(dev))
		return TRUE;
	else if (!strcmp(interface, AUDIO_CONTROL_INTERFACE) && dev->headset &&
			control_is_active(dev))
		return TRUE;

	return FALSE;
}
