/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  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 <stdio.h>
#include <stdbool.h>
#include <errno.h>
#include <unistd.h>
#include <netinet/in.h>

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

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

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

#include "bnep.h"
#include "connection.h"

#define NETWORK_PEER_INTERFACE "org.bluez.Network1"
#define BNEP_INTERFACE "bnep%d"

typedef enum {
	CONNECTED,
	CONNECTING,
	DISCONNECTED
} conn_state;

struct network_peer {
	struct btd_device *device;
	GSList		*connections;
};

struct network_conn {
	struct btd_service *service;
	char		dev[16];	/* Interface name */
	uint16_t	id;		/* Role: Service Class Identifier */
	conn_state	state;
	GIOChannel	*io;
	guint		dc_id;
	struct network_peer *peer;
	DBusMessage	*connect;
	struct bnep	*session;
};

static GSList *peers = NULL;

static uint16_t get_service_id(struct btd_service *service)
{
	return bnep_service_id(btd_service_get_profile(service)->remote_uuid);
}

static struct network_peer *find_peer(GSList *list, struct btd_device *device)
{
	for (; list; list = list->next) {
		struct network_peer *peer = list->data;

		if (peer->device == device)
			return peer;
	}

	return NULL;
}

static struct network_conn *find_connection_by_state(GSList *list,
							conn_state state)
{
	for (; list; list = list->next) {
		struct network_conn *nc = list->data;

		if (nc->state == state)
			return nc;
	}

	return NULL;
}

static void bnep_disconn_cb(gpointer data)
{
	struct network_conn *nc = data;
	DBusConnection *conn = btd_get_dbus_connection();
	const char *path = device_get_path(nc->peer->device);

	g_dbus_emit_property_changed(conn, path,
					NETWORK_PEER_INTERFACE, "Connected");
	g_dbus_emit_property_changed(conn, path,
					NETWORK_PEER_INTERFACE, "Interface");
	g_dbus_emit_property_changed(conn, path,
					NETWORK_PEER_INTERFACE, "UUID");
	device_remove_disconnect_watch(nc->peer->device, nc->dc_id);
	nc->dc_id = 0;

	btd_service_disconnecting_complete(nc->service, 0);

	info("%s disconnected", nc->dev);

	nc->state = DISCONNECTED;
	memset(nc->dev, 0, sizeof(nc->dev));
	strncpy(nc->dev, BNEP_INTERFACE, 16);
	nc->dev[15] = '\0';

	bnep_free(nc->session);
	nc->session = NULL;
}

static void local_connect_cb(struct network_conn *nc, int err)
{
	DBusConnection *conn = btd_get_dbus_connection();
	const char *pdev = nc->dev;

	if (err < 0) {
		DBusMessage *reply = btd_error_failed(nc->connect,
							strerror(-err));
		g_dbus_send_message(conn, reply);
	} else {
		g_dbus_send_reply(conn, nc->connect, DBUS_TYPE_STRING, &pdev,
							DBUS_TYPE_INVALID);
	}

	dbus_message_unref(nc->connect);
	nc->connect = NULL;
}

static void cancel_connection(struct network_conn *nc, int err)
{
	btd_service_connecting_complete(nc->service, err);

	if (nc->connect)
		local_connect_cb(nc, err);

	if (nc->io) {
		g_io_channel_shutdown(nc->io, FALSE, NULL);
		g_io_channel_unref(nc->io);
		nc->io = NULL;
	}

	if (nc->state == CONNECTED)
		bnep_disconnect(nc->session);

	bnep_free(nc->session);
	nc->session = NULL;

	nc->state = DISCONNECTED;
}

static void connection_destroy(DBusConnection *conn, void *user_data)
{
	struct network_conn *nc = user_data;

	cancel_connection(nc, -EIO);
}

static void disconnect_cb(struct btd_device *device, gboolean removal,
				void *user_data)
{
	struct network_conn *nc = user_data;

	info("Network: disconnect %s", device_get_path(nc->peer->device));

	connection_destroy(NULL, user_data);
}

static void bnep_conn_cb(char *iface, int err, void *data)
{
	struct network_conn *nc = data;
	const char *path;
	DBusConnection *conn;

	DBG("");

	if (err < 0) {
		error("connect failed %s", strerror(-err));
		goto failed;
	}

	info("%s connected", nc->dev);

	memcpy(nc->dev, iface, sizeof(nc->dev));
	btd_service_connecting_complete(nc->service, 0);

	if (nc->connect)
		local_connect_cb(nc, 0);

	conn = btd_get_dbus_connection();
	path = device_get_path(nc->peer->device);

	g_dbus_emit_property_changed(conn, path,
					NETWORK_PEER_INTERFACE, "Connected");
	g_dbus_emit_property_changed(conn, path,
					NETWORK_PEER_INTERFACE, "Interface");
	g_dbus_emit_property_changed(conn, path,
					NETWORK_PEER_INTERFACE, "UUID");

	nc->state = CONNECTED;
	nc->dc_id = device_add_disconnect_watch(nc->peer->device, disconnect_cb,
								nc, NULL);

	return;

failed:
	cancel_connection(nc, -EIO);
}

static void connect_cb(GIOChannel *chan, GError *err, gpointer data)
{
	struct network_conn *nc = data;
	int sk, perr;

	if (err) {
		error("%s", err->message);
		goto failed;
	}

	sk = g_io_channel_unix_get_fd(nc->io);
	nc->session = bnep_new(sk, BNEP_SVC_PANU, nc->id, BNEP_INTERFACE);
	if (!nc->session)
		goto failed;

	perr = bnep_connect(nc->session, bnep_conn_cb, nc);
	if (perr < 0) {
		error("bnep connect(): %s (%d)", strerror(-perr), -perr);
		goto failed;
	}

	bnep_set_disconnect(nc->session, bnep_disconn_cb, nc);

	if (nc->io) {
		g_io_channel_unref(nc->io);
		nc->io = NULL;
	}

	return;

failed:
	cancel_connection(nc, -EIO);
}

static DBusMessage *local_connect(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct network_peer *peer = data;
	struct btd_service *service;
	struct network_conn *nc;
	const char *svc;
	const char *uuid;
	uint16_t id;
	int err;

	if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &svc,
						DBUS_TYPE_INVALID) == FALSE)
		return btd_error_invalid_args(msg);

	id = bnep_service_id(svc);
	uuid = bnep_uuid(id);

	if (uuid == NULL)
		return btd_error_invalid_args(msg);

	service = btd_device_get_service(peer->device, uuid);
	if (service == NULL)
		return btd_error_not_supported(msg);

	nc = btd_service_get_user_data(service);

	if (nc->connect != NULL)
		return btd_error_busy(msg);

	err = connection_connect(nc->service);
	if (err < 0)
		return btd_error_failed(msg, strerror(-err));

	nc->connect = dbus_message_ref(msg);

	return NULL;
}

/* Connect and initiate BNEP session */
int connection_connect(struct btd_service *service)
{
	struct network_conn *nc = btd_service_get_user_data(service);
	struct network_peer *peer = nc->peer;
	uint16_t id = get_service_id(service);
	GError *err = NULL;
	const bdaddr_t *src;
	const bdaddr_t *dst;

	DBG("id %u", id);

	if (nc->state != DISCONNECTED)
		return -EALREADY;

	src = btd_adapter_get_address(device_get_adapter(peer->device));
	dst = device_get_address(peer->device);

	nc->io = bt_io_connect(connect_cb, nc,
				NULL, &err,
				BT_IO_OPT_SOURCE_BDADDR, src,
				BT_IO_OPT_DEST_BDADDR, dst,
				BT_IO_OPT_PSM, BNEP_PSM,
				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
				BT_IO_OPT_OMTU, BNEP_MTU,
				BT_IO_OPT_IMTU, BNEP_MTU,
				BT_IO_OPT_INVALID);
	if (!nc->io)
		return -EIO;

	nc->state = CONNECTING;

	return 0;
}

int connection_disconnect(struct btd_service *service)
{
	struct network_conn *nc = btd_service_get_user_data(service);

	if (nc->state == DISCONNECTED)
		return 0;

	connection_destroy(NULL, nc);

	return 0;
}

static DBusMessage *local_disconnect(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	struct network_peer *peer = data;
	GSList *l;

	for (l = peer->connections; l; l = l->next) {
		struct network_conn *nc = l->data;
		int err;

		if (nc->state == DISCONNECTED)
			continue;

		err = connection_disconnect(nc->service);
		if (err < 0)
			return btd_error_failed(msg, strerror(-err));

		return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
	}

	return btd_error_not_connected(msg);
}

static gboolean
network_property_get_connected(const GDBusPropertyTable *property,
					DBusMessageIter *iter, void *data)
{
	struct network_peer *peer = data;
	struct network_conn *nc;
	dbus_bool_t connected;

	nc = find_connection_by_state(peer->connections, CONNECTED);
	connected = nc != NULL ? TRUE : FALSE;

	dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &connected);

	return TRUE;
}

static gboolean network_property_exists(const GDBusPropertyTable *property,
								void *data)
{
	struct network_peer *peer = data;
	struct network_conn *nc;

	nc = find_connection_by_state(peer->connections, CONNECTED);
	if (nc == NULL)
		return FALSE;

	return TRUE;
}

static gboolean
network_property_get_interface(const GDBusPropertyTable *property,
					DBusMessageIter *iter, void *data)
{
	struct network_peer *peer = data;
	struct network_conn *nc;
	const char *iface;

	nc = find_connection_by_state(peer->connections, CONNECTED);
	if (nc == NULL)
		return FALSE;

	iface = nc->dev;

	dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &iface);

	return TRUE;
}

static gboolean network_property_get_uuid(const GDBusPropertyTable *property,
					DBusMessageIter *iter, void *data)
{
	struct network_peer *peer = data;
	struct network_conn *nc;
	const char *uuid;

	nc = find_connection_by_state(peer->connections, CONNECTED);
	if (nc == NULL)
		return FALSE;

	uuid = bnep_uuid(nc->id);

	dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &uuid);

	return TRUE;
}

static void connection_free(void *data)
{
	struct network_conn *nc = data;

	if (nc->dc_id)
		device_remove_disconnect_watch(nc->peer->device, nc->dc_id);

	connection_destroy(NULL, nc);

	if (nc->connect)
		dbus_message_unref(nc->connect);

	btd_service_unref(nc->service);
	g_free(nc);
}

static void peer_free(struct network_peer *peer)
{
	g_slist_free_full(peer->connections, connection_free);
	btd_device_unref(peer->device);
	g_free(peer);
}

static void path_unregister(void *data)
{
	struct network_peer *peer = data;

	DBG("Unregistered interface %s on path %s",
		NETWORK_PEER_INTERFACE, device_get_path(peer->device));

	peers = g_slist_remove(peers, peer);
	peer_free(peer);
}

static const GDBusMethodTable connection_methods[] = {
	{ GDBUS_ASYNC_METHOD("Connect",
				GDBUS_ARGS({"uuid", "s"}),
				GDBUS_ARGS({"interface", "s"}),
				local_connect) },
	{ GDBUS_METHOD("Disconnect",
			NULL, NULL, local_disconnect) },
	{ }
};

static const GDBusPropertyTable connection_properties[] = {
	{ "Connected", "b", network_property_get_connected },
	{ "Interface", "s", network_property_get_interface, NULL,
						network_property_exists },
	{ "UUID", "s", network_property_get_uuid, NULL,
						network_property_exists },
	{ }
};

void connection_unregister(struct btd_service *service)
{
	struct btd_device *device = btd_service_get_device(service);
	struct network_conn *conn = btd_service_get_user_data(service);
	struct network_peer *peer = conn->peer;
	uint16_t id = get_service_id(service);

	DBG("%s id %u", device_get_path(device), id);

	peer->connections = g_slist_remove(peer->connections, conn);
	connection_free(conn);

	if (peer->connections != NULL)
		return;

	g_dbus_unregister_interface(btd_get_dbus_connection(),
						device_get_path(device),
						NETWORK_PEER_INTERFACE);
}

static struct network_peer *create_peer(struct btd_device *device)
{
	struct network_peer *peer;
	const char *path;

	peer = g_new0(struct network_peer, 1);
	peer->device = btd_device_ref(device);

	path = device_get_path(device);

	if (g_dbus_register_interface(btd_get_dbus_connection(), path,
					NETWORK_PEER_INTERFACE,
					connection_methods,
					NULL, connection_properties,
					peer, path_unregister) == FALSE) {
		error("D-Bus failed to register %s interface",
			NETWORK_PEER_INTERFACE);
		peer_free(peer);
		return NULL;
	}

	DBG("Registered interface %s on path %s",
		NETWORK_PEER_INTERFACE, path);

	return peer;
}

int connection_register(struct btd_service *service)
{
	struct btd_device *device = btd_service_get_device(service);
	struct network_peer *peer;
	struct network_conn *nc;
	uint16_t id = get_service_id(service);

	DBG("%s id %u", device_get_path(device), id);

	peer = find_peer(peers, device);
	if (!peer) {
		peer = create_peer(device);
		if (!peer)
			return -1;
		peers = g_slist_append(peers, peer);
	}

	nc = g_new0(struct network_conn, 1);
	nc->id = id;
	nc->service = btd_service_ref(service);
	nc->state = DISCONNECTED;
	nc->peer = peer;

	btd_service_set_user_data(service, nc);

	DBG("id %u registered", id);

	peer->connections = g_slist_append(peer->connections, nc);

	return 0;
}
