/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2017  Intel Corporation. All rights reserved.
 *
 *
 *  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 <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdbool.h>
#include <sys/uio.h>
#include <wordexp.h>

#include <glib.h>

#include "src/shared/io.h"
#include "src/shared/shell.h"
#include "gdbus/gdbus.h"
#include "lib/bluetooth.h"
#include "lib/uuid.h"
#include "mesh/node.h"
#include "mesh/util.h"
#include "mesh/gatt.h"
#include "mesh/prov.h"
#include "mesh/net.h"

#define MESH_PROV_DATA_OUT_UUID_STR	"00002adc-0000-1000-8000-00805f9b34fb"
#define MESH_PROXY_DATA_OUT_UUID_STR	"00002ade-0000-1000-8000-00805f9b34fb"

static struct io *write_io;
static uint16_t write_mtu;

static struct io *notify_io;
static uint16_t notify_mtu;

struct write_data {
	GDBusProxy *proxy;
	void *user_data;
	struct iovec iov;
	GDBusReturnFunction cb;
	uint8_t *gatt_data;
	uint8_t gatt_len;
};

struct notify_data {
	GDBusProxy *proxy;
	bool enable;
	GDBusReturnFunction cb;
	void *user_data;
};

bool mesh_gatt_is_child(GDBusProxy *proxy, GDBusProxy *parent,
			const char *name)
{
	DBusMessageIter iter;
	const char *parent_path;

	if (!parent)
		return FALSE;

	if (g_dbus_proxy_get_property(proxy, name, &iter) == FALSE)
		return FALSE;

	dbus_message_iter_get_basic(&iter, &parent_path);

	if (!strcmp(parent_path, g_dbus_proxy_get_path(parent)))
		return TRUE;
	else
		return FALSE;
}

/* Refactor this once actual MTU is available */
#define GATT_MTU	23

static void write_data_free(void *user_data)
{
	struct write_data *data = user_data;

	g_free(data->gatt_data);
	free(data);
}

uint16_t mesh_gatt_sar(uint8_t **pkt, uint16_t size)
{
	const uint8_t *data = *pkt;
	uint8_t gatt_hdr = *data++;
	uint8_t type = gatt_hdr & GATT_TYPE_MASK;
	static uint8_t gatt_size;
	static uint8_t gatt_pkt[67];

	print_byte_array("GATT-RX:\t", *pkt, size);
	if (size < 1) {
		gatt_pkt[0] = GATT_TYPE_INVALID;
		/* TODO: Disconnect GATT per last paragraph sec 6.6 */
		return 0;
	}

	size--;

	switch (gatt_hdr & GATT_SAR_MASK) {
	case GATT_SAR_FIRST:
		gatt_size = 1;
		gatt_pkt[0] = type;
		/* TODO: Start Proxy Timeout */
		/* fall through */

	case GATT_SAR_CONTINUE:
		if (gatt_pkt[0] != type ||
				gatt_size + size > MAX_GATT_SIZE) {

			/* Invalidate packet and return failure */
			gatt_pkt[0] = GATT_TYPE_INVALID;
			/* TODO: Disconnect GATT per last paragraph sec 6.6 */
			return 0;
		}

		memcpy(gatt_pkt + gatt_size, data, size);
		gatt_size += size;

		/* We are good to this point, but incomplete */
		return 0;

	default:
	case GATT_SAR_COMPLETE:
		gatt_size = 1;
		gatt_pkt[0] = type;

		/* fall through */

	case GATT_SAR_LAST:
		if (gatt_pkt[0] != type ||
				gatt_size + size > MAX_GATT_SIZE) {

			/* Invalidate packet and return failure */
			gatt_pkt[0] = GATT_TYPE_INVALID;
			/* Disconnect GATT per last paragraph sec 6.6 */
			return 0;
		}

		memcpy(gatt_pkt + gatt_size, data, size);
		gatt_size += size;
		*pkt = gatt_pkt;
		return gatt_size;
	}
}

static bool pipe_write(struct io *io, void *user_data)
{
	struct write_data *data = user_data;
	struct iovec iov[2];
	uint8_t sar;
	uint8_t max_len;

	if (data == NULL)
		return true;

	max_len = write_mtu ? write_mtu - 3 - 1 : GATT_MTU - 3 - 1;
	print_byte_array("GATT-TX:\t", data->gatt_data, data->gatt_len);

	sar = data->gatt_data[0];

	data->iov.iov_base = data->gatt_data + 1;
	data->iov.iov_len--;

	sar = data->gatt_data[0] & GATT_TYPE_MASK;
	data->gatt_len--;

	if (data->gatt_len > max_len) {
		sar |= GATT_SAR_FIRST;
		data->iov.iov_len = max_len;
	}

	iov[0].iov_base = &sar;
	iov[0].iov_len = sizeof(sar);

	while (1) {
		int err;

		iov[1] = data->iov;

		err = io_send(io, iov, 2);
		if (err < 0) {
			bt_shell_printf("Failed to write: %s\n", strerror(-err));
			write_data_free(data);
			return false;
		}

		switch (sar & GATT_SAR_MASK) {
		case GATT_SAR_FIRST:
		case GATT_SAR_CONTINUE:
			data->gatt_len -= max_len;
			data->iov.iov_base = data->iov.iov_base + max_len;

			sar &= GATT_TYPE_MASK;
			if (max_len < data->gatt_len) {
				data->iov.iov_len = max_len;
				sar |= GATT_SAR_CONTINUE;
			} else {
				data->iov.iov_len = data->gatt_len;
				sar |= GATT_SAR_LAST;
			}

			break;

		default:
			if(data->cb)
				data->cb(NULL, data->user_data);
			write_data_free(data);
			return true;
		}
	}
}

static void write_io_destroy(void)
{
	io_destroy(write_io);
	write_io = NULL;
	write_mtu = 0;
}

static void notify_io_destroy(void)
{
	io_destroy(notify_io);
	notify_io = NULL;
	notify_mtu = 0;
}

static bool pipe_hup(struct io *io, void *user_data)
{
	bt_shell_printf("%s closed\n", io == notify_io ? "Notify" : "Write");

	if (io == notify_io)
		notify_io_destroy();
	else
		write_io_destroy();

	return false;
}

static struct io *pipe_io_new(int fd)
{
	struct io *io;

	io = io_new(fd);

	io_set_close_on_destroy(io, true);

	io_set_disconnect_handler(io, pipe_hup, NULL, NULL);

	return io;
}

static void acquire_write_reply(DBusMessage *message, void *user_data)
{
	struct write_data *data = user_data;
	DBusError error;
	int fd;

	dbus_error_init(&error);

	if (dbus_set_error_from_message(&error, message) == TRUE) {
		dbus_error_free(&error);
		bt_shell_printf("Failed to write\n");
		write_data_free(data);
		return;
	}

	if ((dbus_message_get_args(message, NULL, DBUS_TYPE_UNIX_FD, &fd,
					DBUS_TYPE_UINT16, &write_mtu,
					DBUS_TYPE_INVALID) == false)) {
		bt_shell_printf("Invalid AcquireWrite response\n");
		return;
	}

	bt_shell_printf("AcquireWrite success: fd %d MTU %u\n", fd, write_mtu);

	write_io = pipe_io_new(fd);

	pipe_write(write_io, data);
}

static void acquire_setup(DBusMessageIter *iter, void *user_data)
{
	DBusMessageIter dict;

	dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
					DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
					DBUS_TYPE_STRING_AS_STRING
					DBUS_TYPE_VARIANT_AS_STRING
					DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
					&dict);

	dbus_message_iter_close_container(iter, &dict);
}

bool mesh_gatt_write(GDBusProxy *proxy, uint8_t *buf, uint16_t len,
			GDBusReturnFunction cb, void *user_data)
{
	struct write_data *data;

	if (!buf || !len)
		return false;

	if (len > 69)
		return false;

	data = g_new0(struct write_data, 1);
	if (!data)
		return false;

	/* TODO: should keep in queue in case we need to cancel write? */

	data->gatt_len = len;
	data->gatt_data = g_memdup(buf, len);
	data->gatt_data[0] &= GATT_TYPE_MASK;
	data->iov.iov_base = data->gatt_data;
	data->iov.iov_len = len;
	data->proxy = proxy;
	data->user_data = user_data;
	data->cb = cb;

	if (write_io)
		return pipe_write(write_io, data);

	if (g_dbus_proxy_method_call(proxy, "AcquireWrite",
				acquire_setup, acquire_write_reply,
				data, NULL) == FALSE) {
		bt_shell_printf("Failed to AcquireWrite\n");
		write_data_free(data);
		return false;
	}
	return true;
}

static void notify_reply(DBusMessage *message, void *user_data)
{
	struct notify_data *data = user_data;
	DBusError error;

	dbus_error_init(&error);

	if (dbus_set_error_from_message(&error, message) == TRUE) {
		bt_shell_printf("Failed to %s notify: %s\n",
				data->enable ? "start" : "stop", error.name);
		dbus_error_free(&error);
		goto done;
	}

	bt_shell_printf("Notify %s\n", data->enable ? "started" : "stopped");

done:
	if (data->cb)
		data->cb(message, data->user_data);

	g_free(data);
}

static bool pipe_read(struct io *io, bool prov, void *user_data)
{
	struct mesh_node *node = user_data;
	uint8_t buf[512];
	uint8_t *res;
	int fd = io_get_fd(io);
	ssize_t len, len_sar;

	if (io != notify_io)
		return true;

	while ((len = read(fd, buf, sizeof(buf)))) {
		if (len <= 0)
			break;

		res = buf;
		len_sar = mesh_gatt_sar(&res, len);
		if (len_sar) {
			if (prov)
				prov_data_ready(node, res, len_sar);
			else
				net_data_ready(res, len_sar);
		}
	}
	return true;
}

static bool pipe_read_prov(struct io *io, void *user_data)
{
	return pipe_read(io, true, user_data);
}

static bool pipe_read_proxy(struct io *io, void *user_data)
{
	return pipe_read(io, false, user_data);
}

static void acquire_notify_reply(DBusMessage *message, void *user_data)
{
	struct notify_data *data = user_data;
	DBusMessageIter iter;
	DBusError error;
	int fd;
	const char *uuid;

	dbus_error_init(&error);

	if (dbus_set_error_from_message(&error, message) == TRUE) {
		dbus_error_free(&error);
		if (g_dbus_proxy_method_call(data->proxy, "StartNotify", NULL,
					notify_reply, data, NULL) == FALSE) {
			bt_shell_printf("Failed to StartNotify\n");
			g_free(data);
		}
		return;
	}

	if (notify_io) {
		io_destroy(notify_io);
		notify_io = NULL;
	}

	notify_mtu = 0;

	if ((dbus_message_get_args(message, NULL, DBUS_TYPE_UNIX_FD, &fd,
					DBUS_TYPE_UINT16, &notify_mtu,
					DBUS_TYPE_INVALID) == false)) {
		if (g_dbus_proxy_method_call(data->proxy, "StartNotify", NULL,
					notify_reply, data, NULL) == FALSE) {
			bt_shell_printf("Failed to StartNotify\n");
			g_free(data);
		}
		return;
	}

	bt_shell_printf("AcquireNotify success: fd %d MTU %u\n", fd, notify_mtu);

	if (g_dbus_proxy_get_property(data->proxy, "UUID", &iter) == FALSE)
		goto done;

	notify_io = pipe_io_new(fd);

	dbus_message_iter_get_basic(&iter, &uuid);

	if (!bt_uuid_strcmp(uuid, MESH_PROV_DATA_OUT_UUID_STR))
		io_set_read_handler(notify_io, pipe_read_prov, data->user_data,
									NULL);
	else if (!bt_uuid_strcmp(uuid, MESH_PROXY_DATA_OUT_UUID_STR))
		io_set_read_handler(notify_io, pipe_read_proxy, data->user_data,
									NULL);

done:
	if (data->cb)
		data->cb(message, data->user_data);

	g_free(data);
}

bool mesh_gatt_notify(GDBusProxy *proxy, bool enable, GDBusReturnFunction cb,
			void *user_data)
{
	struct notify_data *data;
	DBusMessageIter iter;
	const char *method;
	GDBusSetupFunction setup = NULL;

	data = g_new0(struct notify_data, 1);
	data->proxy = proxy;
	data->enable = enable;
	data->cb = cb;
	data->user_data = user_data;

	if (enable == TRUE) {
		if (g_dbus_proxy_get_property(proxy, "NotifyAcquired", &iter)) {
			method = "AcquireNotify";
			cb = acquire_notify_reply;
			setup = acquire_setup;
		} else {
			method = "StartNotify";
			cb = notify_reply;
		}
	} else {
		if (notify_io) {
			notify_io_destroy();
			if (cb)
				cb(NULL, user_data);
			return true;
		} else {
			method = "StopNotify";
			cb = notify_reply;
		}
	}

	if (g_dbus_proxy_method_call(proxy, method, setup, cb,
					data, NULL) == FALSE) {
		bt_shell_printf("Failed to %s\n", method);
		return false;
	}
	return true;
}
