/*
 *
 *  Dropcam BTLE integration for BlueZ
 *
 *  Copyright (C) 2013 Dropcam Inc.
 *
 *  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
 *
 */

/*  This module implements the Dropcam BTLE profile for mobile setup.
 *
 *  Notes:
 *   - General structure and "watcher" implementation is modeled after the
 *     cyclingspeed and thermometer profile implementations.
 *   - This module exposes a new DBus interface (com.dropcam.BTLEMessageDispatch1)
 *     which can be used to send and receive messages from a connected Dropcam BTLE setup
 *     device.
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdbool.h>
#include <glib.h>
#include <errno.h>
#include <stdlib.h>
#include <stdint.h>

#include <gdbus/gdbus.h>
#include "src/dbus-common.h"
#include "src/adapter.h"

#include "lib/uuid.h"
#include "src/plugin.h"
#include "src/hcid.h"
#include "src/log.h"
#include "src/device.h"
#include "src/error.h"
#include "attrib/gattrib.h"
#include "attrib/gatt-service.h"
#include "attrib/att.h"
#include "attrib/gatt.h"
#include "attrib/att-database.h"

#include "dropcam_btle_profile_def.h"

#define DROPCAM_OBJECT_PATH	"/com/dropcam"
#define DROPCAM_INTERFACE	"com.dropcam.BTLEMessageDispatch1"
#define DROPCAM_WATCHER_INTERFACE "com.dropcam.BTLEDispatchWatcher1"

#define MTU_SIZE 20

struct pending_read {
	int payload_len;
	uint8_t payload[MTU_SIZE];
};

struct message {
	uint8_t *bytes;
	int len;
};

struct watcher {
	guint id;
	char *srv;
	char *path;
};

struct dropcam_adapter {
	struct btd_adapter *adapter;

	uint8_t last_read_seqnum;
	uint8_t last_write_seqnum;

	int cur_message_pos;
	uint8_t message_payload[0xffff];
	GSList *pending_read_payloads;
};

static GSList *adapters = NULL;
static GSList *watchers = NULL;

static int adapter_cmp(gconstpointer a, gconstpointer b)
{
	const struct dropcam_adapter *dc_adapter = a;
	const struct btd_adapter *adapter = b;

	return dc_adapter->adapter == adapter ? 0 : -1;
}

static struct dropcam_adapter *find_dropcam_adapter(struct btd_adapter *adapter) {
	GSList *l = g_slist_find_custom(adapters, adapter, adapter_cmp);

	return l ? l->data : NULL;
}

static void update_watcher(gpointer data, gpointer user_data) {
	struct watcher *w = data;
	struct dropcam_adapter *dc_adapter = user_data;
	const char *path = DROPCAM_OBJECT_PATH;
	DBusMessageIter iter;
	DBusMessageIter array;
	DBusMessage *msg;

	msg = dbus_message_new_method_call(w->srv, w->path, DROPCAM_WATCHER_INTERFACE, "MessageReceived");
	if (msg == NULL)
		return;

	dbus_message_iter_init_append(msg, &iter);

	dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH , &path);

	uint8_t *payload_ptr = dc_adapter->message_payload;
	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "y", &array);
	dbus_message_iter_append_fixed_array(&array, DBUS_TYPE_BYTE,
	                                     &payload_ptr, dc_adapter->cur_message_pos);
	dbus_message_iter_close_container(&iter, &array);

	dbus_message_set_no_reply(msg, TRUE);

	DBG("Sending MessageReceived to: %s: %s", w->srv, w->path);
	g_dbus_send_message(btd_get_dbus_connection(), msg);
}

static uint8_t dropcam_tx_read(struct attribute *a, struct btd_device *device, gpointer user_data) {
	struct dropcam_adapter *dc_adapter = user_data;

	if (dc_adapter->pending_read_payloads == NULL) {
		/* nothing to send so increment the sequence number and return an empty message */
		uint8_t seq_num = dc_adapter->last_read_seqnum + 1;
		attrib_db_update(dc_adapter->adapter, a->handle, NULL, &seq_num, sizeof(seq_num), NULL);
		dc_adapter->last_read_seqnum = seq_num;
	} else {
		/* return the next pending read */
		struct pending_read* pr = dc_adapter->pending_read_payloads->data;
		DBG("Sending %d byte payload", pr->payload_len);
		attrib_db_update(dc_adapter->adapter, a->handle, NULL, pr->payload, pr->payload_len, NULL);

		dc_adapter->pending_read_payloads = g_slist_remove(dc_adapter->pending_read_payloads, pr);
		g_free(pr);
	}

	return 0;
}

static uint8_t dropcam_tx_write(struct attribute *a, struct btd_device *device, gpointer user_data) {
	struct dropcam_adapter *dc_adapter = user_data;

	if (a->len > 0) {
		uint8_t expected_seq_num = dc_adapter->last_write_seqnum + 1;

		struct DropcamBTLEPayloadHeader *payload_header = (struct DropcamBTLEPayloadHeader *)a->data;
		uint8_t *payload_bytes = a->data + sizeof(struct DropcamBTLEPayloadHeader);
		int payload_bytes_len = a->len - sizeof(struct DropcamBTLEPayloadHeader);

		DBG("Received payload with sequence number: %d, length: %d", payload_header->seqnum, payload_bytes_len);

		if (payload_header->seqnum != expected_seq_num) {
			warn("Received out of order write!  Expected: %d, received: %d", expected_seq_num, payload_header->seqnum);
		}

		if (a->len > 1) {
			if (dc_adapter->cur_message_pos == -1) {
				/* we received data so we're starting a new message */
				dc_adapter->cur_message_pos = 0;
			}

			if (dc_adapter->cur_message_pos + payload_bytes_len >= sizeof(dc_adapter->message_payload)) {
				DBG("Message too large!");
				return;
			}

			uint8_t *cur_pos = dc_adapter->message_payload + dc_adapter->cur_message_pos;
			memcpy(cur_pos, payload_bytes, payload_bytes_len);

			dc_adapter->cur_message_pos += payload_bytes_len;
		} else {
			if (dc_adapter->cur_message_pos != -1) {
				/* received an empty payload - pending message is complete */
				DBG("Received message -- length: %d", dc_adapter->cur_message_pos);

				/* send the message to the watchers and reset the current message */
				g_slist_foreach(watchers, update_watcher, dc_adapter);
				dc_adapter->cur_message_pos = -1;
			}
		}

		dc_adapter->last_write_seqnum = payload_header->seqnum;
	}
	return 0;
}

static void queue_pending_read_packet(struct dropcam_adapter *dc_adapter, uint8_t *packet, int packet_len) {
	uint8_t seq_num = dc_adapter->last_read_seqnum + 1;
	struct pending_read *pr = g_new0(struct pending_read, 1);
	pr->payload_len = packet_len + 1;
	struct DropcamBTLEPayloadHeader *pkt_header = (struct DropcamBTLEPayloadHeader *)pr->payload;
	pkt_header->seqnum = seq_num;

	if (packet_len > 0) {
		memcpy(pr->payload + 1, packet, packet_len);
	}

	DBG("Queuing pending read: %d, %d", seq_num, packet_len + 1);
	dc_adapter->pending_read_payloads = g_slist_append(dc_adapter->pending_read_payloads, pr);

	dc_adapter->last_read_seqnum = seq_num;
}

static void queue_pending_read_message(struct dropcam_adapter *dc_adapter, struct message *msg) {
	uint8_t *packet = msg->bytes;
	int bytes_remaining = msg->len;

	/* Split the message into smaller packets */
	while (bytes_remaining > 0) {
		int next_packet_len = MIN(MTU_SIZE - sizeof(struct DropcamBTLEPayloadHeader), bytes_remaining);

		queue_pending_read_packet(dc_adapter, packet, next_packet_len);
		packet += next_packet_len;
		bytes_remaining -= next_packet_len;
	}

	/* Queue a final empty packet to signal that the message is complete */
	queue_pending_read_packet(dc_adapter, NULL, 0);
}

static gboolean register_dropcam_service(struct dropcam_adapter *dc_adapter) {
	bt_uuid_t svc_uuid;
	bt_string_to_uuid(&svc_uuid, DROPCAM_SVC_UUID);

	bt_uuid_t tx_read_chr_uuid;
	bt_string_to_uuid(&tx_read_chr_uuid, DROPCAM_TRANSFER_READ_CHR_UUID);

	bt_uuid_t tx_write_chr_uuid;
	bt_string_to_uuid(&tx_write_chr_uuid, DROPCAM_TRANSFER_WRITE_CHR_UUID);

	/* Dropcam Service */
	gboolean svc_added = gatt_service_add(
	                         dc_adapter->adapter,
	                         GATT_PRIM_SVC_UUID, &svc_uuid,

	                         /* Dropcam Transfer Write */
	                         GATT_OPT_CHR_UUID, &tx_write_chr_uuid,
	                         GATT_OPT_CHR_PROPS,	GATT_CHR_PROP_WRITE,
	                         GATT_OPT_CHR_VALUE_CB, ATTRIB_WRITE,
	                         dropcam_tx_write, dc_adapter,

	                         /* Dropcam Transfer Read */
	                         GATT_OPT_CHR_UUID, &tx_read_chr_uuid,
	                         GATT_OPT_CHR_PROPS, GATT_CHR_PROP_READ,
	                         GATT_OPT_CHR_VALUE_CB, ATTRIB_READ,
	                         dropcam_tx_read, dc_adapter,

	                         GATT_OPT_INVALID);
}

static void remove_watcher(gpointer user_data) {
	struct watcher *watcher = user_data;

	g_dbus_remove_watch(btd_get_dbus_connection(), watcher->id);
}

static void dropcam_destroy(gpointer user_data) {
	g_slist_free_full(watchers, remove_watcher);
	watchers = NULL;
}

static void watcher_exit_cb(DBusConnection *conn, void *user_data) {
	struct watcher *watcher = user_data;

	DBG("Dropcam watcher [%s] disconnected", watcher->path);

	watchers = g_slist_remove(watchers, watcher);
	g_dbus_remove_watch(conn, watcher->id);
}

static int cmp_watcher(gconstpointer a, gconstpointer b) {
	const struct watcher *watcher = a;
	const struct watcher *match = b;
	int ret;

	ret = g_strcmp0(watcher->srv, match->srv);
	if (ret != 0)
		return ret;

	return g_strcmp0(watcher->path, match->path);
}

static void destroy_watcher(gpointer user_data) {
	struct watcher *watcher = user_data;

	g_free(watcher->path);
	g_free(watcher->srv);
	g_free(watcher);
}

static struct watcher *find_watcher(GSList *list, const char *sender, const char *path) {
	struct watcher *match;
	GSList *l;

	match = g_new0(struct watcher, 1);
	match->srv = g_strdup(sender);
	match->path = g_strdup(path);

	l = g_slist_find_custom(list, match, cmp_watcher);
	destroy_watcher(match);

	if (l != NULL)
		return l->data;

	return NULL;
}

static void queue_message_for_adapter(gpointer data, gpointer user_data) {
	struct dropcam_adapter *dc_adapter = data;
	struct message *msg = user_data;

	queue_pending_read_message(dc_adapter, msg);
}

static DBusMessage *send_message(DBusConnection *conn, DBusMessage *msg, void *data) {
	struct message msg_data;

	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &msg_data.bytes, &msg_data.len, DBUS_TYPE_INVALID))
		return btd_error_invalid_args(msg);

	DBG("Received message of length: %d", msg_data.len);

	g_slist_foreach(adapters, queue_message_for_adapter, &msg_data);

	return dbus_message_new_method_return(msg);
}

static DBusMessage *register_watcher(DBusConnection *conn, DBusMessage *msg, void *data) {
	struct watcher *watcher;
	const char *sender = dbus_message_get_sender(msg);
	char *path;

	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID))
		return btd_error_invalid_args(msg);

	watcher = find_watcher(watchers, sender, path);
	if (watcher != NULL)
		return btd_error_already_exists(msg);

	watcher = g_new0(struct watcher, 1);
	watcher->id = g_dbus_add_disconnect_watch(conn, sender, watcher_exit_cb, watcher, destroy_watcher);
	watcher->srv = g_strdup(sender);
	watcher->path = g_strdup(path);

	watchers = g_slist_prepend(watchers, watcher);

	DBG("Dropcam watcher [%s] registered", path);

	return dbus_message_new_method_return(msg);
}

static DBusMessage *unregister_watcher(DBusConnection *conn, DBusMessage *msg, void *data) {
	struct watcher *watcher;
	const char *sender = dbus_message_get_sender(msg);
	char *path;

	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID))
		return btd_error_invalid_args(msg);

	watcher = find_watcher(watchers, sender, path);
	if (watcher == NULL)
		return btd_error_does_not_exist(msg);

	watchers = g_slist_remove(watchers, watcher);
	g_dbus_remove_watch(conn, watcher->id);

	DBG("Dropcam watcher [%s] unregistered", path);

	return dbus_message_new_method_return(msg);
}

static const GDBusMethodTable dropcam_methods[] = {
	{ GDBUS_METHOD("RegisterWatcher",    GDBUS_ARGS({ "agent", "o" }),    NULL, register_watcher) },
	{ GDBUS_METHOD("UnregisterWatcher",  GDBUS_ARGS({ "agent", "o" }),    NULL, unregister_watcher) },
	{ GDBUS_METHOD("SendMessage",        GDBUS_ARGS({ "message", "ay" }), NULL, send_message) },
	{ }
};

static int dropcam_adapter_probe(struct btd_adapter *adapter) {
	struct dropcam_adapter *dc_adapter = g_new0(struct dropcam_adapter, 1);
	dc_adapter->adapter = btd_adapter_ref(adapter);
	dc_adapter->last_write_seqnum = 0xff;
	dc_adapter->last_read_seqnum = 0xff;

	register_dropcam_service(dc_adapter);

	adapters = g_slist_append(adapters, dc_adapter);

	return 0;
}

static void dropcam_adapter_remove(struct btd_adapter *adapter) {
	struct dropcam_adapter *dc_adapter;

	dc_adapter = find_dropcam_adapter(adapter);
	if (!dc_adapter)
		return;

	adapters = g_slist_remove(adapters, dc_adapter);
	btd_adapter_unref(dc_adapter->adapter);

	g_free(dc_adapter);
}

static struct btd_adapter_driver dropcam_adapter_driver = {
	.name	= "dropcam-adapter-driver",
	.probe	= dropcam_adapter_probe,
	.remove	= dropcam_adapter_remove,
};

static int dropcam_init(void) {
	if (!g_dbus_register_interface(btd_get_dbus_connection(),
	                               DROPCAM_OBJECT_PATH, DROPCAM_INTERFACE,
	                               dropcam_methods, NULL, NULL, NULL,
	                               dropcam_destroy)) {
		error("D-Bus failed to register %s interface", DROPCAM_INTERFACE);
		return -EIO;
	}

	return btd_register_adapter_driver(&dropcam_adapter_driver);
}

static void dropcam_exit(void) {
	g_dbus_unregister_interface(btd_get_dbus_connection(),
	                            DROPCAM_OBJECT_PATH, DROPCAM_INTERFACE);

	btd_unregister_adapter_driver(&dropcam_adapter_driver);
}

BLUETOOTH_PLUGIN_DEFINE(dropcam, VERSION,
                        BLUETOOTH_PLUGIN_PRIORITY_LOW,
                        dropcam_init, dropcam_exit)
