/*
 *
 *  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 <readline/readline.h>
#include <readline/history.h>
#include <glib.h>

#include "src/shared/io.h"
#include "gdbus/gdbus.h"
#include "lib/bluetooth.h"
#include "lib/uuid.h"
#include "client/display.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);
}

static void write_setup(DBusMessageIter *iter, void *user_data)
{
	struct write_data *data = user_data;
	struct iovec *iov = &data->iov;
	DBusMessageIter array, dict;

	dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "y", &array);
	dbus_message_iter_append_fixed_array(&array, DBUS_TYPE_BYTE,
						&iov->iov_base, iov->iov_len);
	dbus_message_iter_close_container(iter, &array);

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

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 = write_mtu - 4;

	if (data == NULL)
		return true;

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

	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) {
			rl_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_reply(DBusMessage *message, void *user_data)
{
	struct write_data *data = user_data;
	struct write_data *tmp;
	uint8_t *dptr = data->gatt_data;
	uint8_t max_len = GATT_MTU - 3;
	uint8_t max_seg = GATT_MTU - 4;
	DBusError error;

	dbus_error_init(&error);

	if (dbus_set_error_from_message(&error, message) == TRUE) {
		rl_printf("Failed to write: %s\n", error.name);
		dbus_error_free(&error);
		return;
	}

	if (data == NULL)
		return;

	switch (data->gatt_data[0] & GATT_SAR_MASK) {
		case GATT_SAR_FIRST:
		case GATT_SAR_CONTINUE:
			tmp = g_new0(struct write_data, 1);
			if (!data)
				return;

			*tmp = *data;
			tmp->gatt_data = g_malloc(data->gatt_len);

			if (!tmp->gatt_data) {
				g_free(tmp);
				return;
			}

			tmp->gatt_data[0] = dptr[0];
			data = tmp;
			memcpy(data->gatt_data + 1, dptr + max_len,
					data->gatt_len - max_seg);
			data->gatt_len -= max_seg;
			data->gatt_data[0] &= GATT_TYPE_MASK;
			data->iov.iov_base = data->gatt_data;
			if (max_len < data->gatt_len) {
				data->iov.iov_len = max_len;
				data->gatt_data[0] |= GATT_SAR_CONTINUE;
			} else {
				data->iov.iov_len = data->gatt_len;
				data->gatt_data[0] |= GATT_SAR_LAST;
			}

			break;

		default:
			if(data->cb)
				data->cb(message, data->user_data);
			return;
	}

	if (g_dbus_proxy_method_call(data->proxy, "WriteValue", write_setup,
				write_reply, data, write_data_free) == FALSE) {
		rl_printf("Failed to write\n");
		write_data_free(data);
		return;
	}

}

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)
{
	rl_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);
		if (g_dbus_proxy_method_call(data->proxy, "WriteValue",
				write_setup, write_reply, data,
				write_data_free) == FALSE) {
			rl_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)) {
		rl_printf("Invalid AcquireWrite response\n");
		return;
	}

	rl_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;
	DBusMessageIter iter;
	uint8_t max_len;

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

	if (len > 69)
		return false;

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

	max_len = write_mtu ? write_mtu - 3 : GATT_MTU - 3;

	/* 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;
	if (max_len < len) {
		len = max_len;
		data->gatt_data[0] |= GATT_SAR_FIRST;
	}
	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_get_property(proxy, "WriteAcquired", &iter)) {
		if (g_dbus_proxy_method_call(proxy, "AcquireWrite",
					acquire_setup, acquire_write_reply,
					data, NULL) == FALSE) {
			rl_printf("Failed to AcquireWrite\n");
			write_data_free(data);
			return false;
		}
	} else {
		if (g_dbus_proxy_method_call(data->proxy, "WriteValue",
				write_setup, write_reply, data,
				write_data_free) == FALSE) {
			rl_printf("Failed to write\n");
			write_data_free(data);
			return false;
		}
		print_byte_array("GATT-TX: ", buf, len);
		rl_printf("Attempting to write %s\n",
						g_dbus_proxy_get_path(proxy));
	}

	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) {
		rl_printf("Failed to %s notify: %s\n",
				data->enable ? "start" : "stop", error.name);
		dbus_error_free(&error);
		goto done;
	}

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

	if (io != notify_io)
		return true;

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

		res = buf;
		mesh_gatt_sar(&res, len);

		if (prov)
			prov_data_ready(node, res, len);
		else
			net_data_ready(res, len);
	}

	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) {
			rl_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) {
			rl_printf("Failed to StartNotify\n");
			g_free(data);
		}
		return;
	}

	rl_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) {
		rl_printf("Failed to %s\n", method);
		return false;
	}
	return true;
}
