/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2011  Nokia Corporation
 *  Copyright (C) 2011  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 <errno.h>
#include <fcntl.h>
#include <gdbus/gdbus.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <glib.h>

#include <bluetooth/bluetooth.h>

#include "lib/uuid.h"
#include "src/dbus-common.h"
#include "src/adapter.h"
#include "src/device.h"
#include "src/error.h"
#include "src/log.h"
#include "attrib/att.h"
#include "attrib/gattrib.h"
#include "attrib/gatt.h"
#include "src/attio.h"
#include "src/textfile.h"

#include "monitor.h"

#define PROXIMITY_INTERFACE "org.bluez.ProximityMonitor1"

#define ALERT_LEVEL_CHR_UUID 0x2A06
#define POWER_LEVEL_CHR_UUID 0x2A07

#define IMMEDIATE_TIMEOUT	5
#define TX_POWER_SIZE		1

enum {
	ALERT_NONE = 0,
	ALERT_MILD,
	ALERT_HIGH,
};

struct monitor {
	struct btd_device *device;
	GAttrib *attrib;
	struct att_range *linkloss;
	struct att_range *txpower;
	struct att_range *immediate;
	struct enabled enabled;
	char *linklosslevel;		/* Link Loss Alert Level */
	char *fallbacklevel;		/* Immediate fallback alert level */
	char *immediatelevel;		/* Immediate Alert Level */
	char *signallevel;		/* Path Loss RSSI level */
	uint16_t linklosshandle;	/* Link Loss Characteristic
					 * Value Handle */
	uint16_t txpowerhandle;		/* Tx Characteristic Value Handle */
	uint16_t immediatehandle;	/* Immediate Alert Value Handle */
	guint immediateto;		/* Reset Immediate Alert to "none" */
	guint attioid;
};

static GSList *monitors = NULL;

static struct monitor *find_monitor(struct btd_device *device)
{
	GSList *l;

	for (l = monitors; l; l = l->next) {
		struct monitor *monitor = l->data;

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

	return NULL;
}

static void write_proximity_config(struct btd_device *device, const char *alert,
					const char *level)
{
	char *filename;
	GKeyFile *key_file;
	char *data;
	gsize length = 0;

	filename = btd_device_get_storage_path(device, "proximity");
	if (!filename) {
		warn("Unable to get proximity storage path for device");
		return;
	}

	key_file = g_key_file_new();
	g_key_file_load_from_file(key_file, filename, 0, NULL);

	if (level)
		g_key_file_set_string(key_file, alert, "Level", level);
	else
		g_key_file_remove_group(key_file, alert, NULL);

	data = g_key_file_to_data(key_file, &length, NULL);
	if (length > 0) {
		create_file(filename, S_IRUSR | S_IWUSR);
		g_file_set_contents(filename, data, length, NULL);
	}

	g_free(data);
	g_free(filename);
	g_key_file_free(key_file);
}

static char *read_proximity_config(struct btd_device *device, const char *alert)
{
	char *filename;
	GKeyFile *key_file;
	char *str;

	filename = btd_device_get_storage_path(device, "proximity");
	if (!filename) {
		warn("Unable to get proximity storage path for device");
		return NULL;
	}

	key_file = g_key_file_new();
	g_key_file_load_from_file(key_file, filename, 0, NULL);

	str = g_key_file_get_string(key_file, alert, "Level", NULL);

	g_free(filename);
	g_key_file_free(key_file);

	return str;
}

static uint8_t str2level(const char *level)
{
	if (g_strcmp0("high", level) == 0)
		return ALERT_HIGH;
	else if (g_strcmp0("mild", level) == 0)
		return ALERT_MILD;

	return ALERT_NONE;
}

static void linkloss_written(guint8 status, const guint8 *pdu, guint16 plen,
							gpointer user_data)
{
	struct monitor *monitor = user_data;
	struct btd_device *device = monitor->device;
	const char *path = device_get_path(device);

	if (status != 0) {
		error("Link Loss Write Request failed: %s",
							att_ecode2str(status));
		return;
	}

	if (!dec_write_resp(pdu, plen)) {
		error("Link Loss Write Request: protocol error");
		return;
	}

	DBG("Link Loss Alert Level written");

	g_dbus_emit_property_changed(btd_get_dbus_connection(), path,
				PROXIMITY_INTERFACE, "LinkLossAlertLevel");
}

static void char_discovered_cb(uint8_t status, GSList *characteristics,
								void *user_data)
{
	struct monitor *monitor = user_data;
	struct gatt_char *chr;
	uint8_t value = str2level(monitor->linklosslevel);

	if (status) {
		error("Discover Link Loss handle: %s", att_ecode2str(status));
		return;
	}

	DBG("Setting alert level \"%s\" on Reporter", monitor->linklosslevel);

	/* Assume there is a single Alert Level characteristic */
	chr = characteristics->data;
	monitor->linklosshandle = chr->value_handle;

	gatt_write_char(monitor->attrib, monitor->linklosshandle, &value, 1,
						linkloss_written, monitor);
}

static int write_alert_level(struct monitor *monitor)
{
	struct att_range *linkloss = monitor->linkloss;
	bt_uuid_t uuid;

	if (monitor->linklosshandle) {
		uint8_t value = str2level(monitor->linklosslevel);

		gatt_write_char(monitor->attrib, monitor->linklosshandle,
					&value, 1, linkloss_written, monitor);
		return 0;
	}

	bt_uuid16_create(&uuid, ALERT_LEVEL_CHR_UUID);

	/* FIXME: use cache (requires service changed support) ? */
	gatt_discover_char(monitor->attrib, linkloss->start, linkloss->end,
					&uuid, char_discovered_cb, monitor);

	return 0;
}

static void tx_power_read_cb(guint8 status, const guint8 *pdu, guint16 plen,
							gpointer user_data)
{
	uint8_t value[TX_POWER_SIZE];
	ssize_t vlen;

	if (status != 0) {
		DBG("Tx Power Level read failed: %s", att_ecode2str(status));
		return;
	}

	vlen = dec_read_resp(pdu, plen, value, sizeof(value));
	if (vlen < 0) {
		DBG("Protocol error");
		return;
	}

	if (vlen != 1) {
		DBG("Invalid length for TX Power value: %zd", vlen);
		return;
	}

	DBG("Tx Power Level: %02x", (int8_t) value[0]);
}

static void tx_power_handle_cb(uint8_t status, GSList *characteristics,
								void *user_data)
{
	struct monitor *monitor = user_data;
	struct gatt_char *chr;

	if (status) {
		error("Discover Tx Power handle: %s", att_ecode2str(status));
		return;
	}

	chr = characteristics->data;
	monitor->txpowerhandle = chr->value_handle;

	DBG("Tx Power handle: 0x%04x", monitor->txpowerhandle);

	gatt_read_char(monitor->attrib, monitor->txpowerhandle,
							tx_power_read_cb, monitor);
}

static void read_tx_power(struct monitor *monitor)
{
	struct att_range *txpower = monitor->txpower;
	bt_uuid_t uuid;

	if (monitor->txpowerhandle != 0) {
		gatt_read_char(monitor->attrib, monitor->txpowerhandle,
						tx_power_read_cb, monitor);
		return;
	}

	bt_uuid16_create(&uuid, POWER_LEVEL_CHR_UUID);

	gatt_discover_char(monitor->attrib, txpower->start, txpower->end,
				&uuid, tx_power_handle_cb, monitor);
}

static gboolean immediate_timeout(gpointer user_data)
{
	struct monitor *monitor = user_data;
	const char *path = device_get_path(monitor->device);

	monitor->immediateto = 0;

	if (g_strcmp0(monitor->immediatelevel, "none") == 0)
		return FALSE;

	if (monitor->attrib) {
		uint8_t value = ALERT_NONE;
		gatt_write_cmd(monitor->attrib, monitor->immediatehandle,
				&value, 1, NULL, NULL);
	}

	g_free(monitor->immediatelevel);
	monitor->immediatelevel = g_strdup("none");


	g_dbus_emit_property_changed(btd_get_dbus_connection(), path,
				PROXIMITY_INTERFACE, "ImmediateAlertLevel");

	return FALSE;
}

static void immediate_written(gpointer user_data)
{
	struct monitor *monitor = user_data;
	const char *path = device_get_path(monitor->device);

	g_free(monitor->fallbacklevel);
	monitor->fallbacklevel = NULL;


	g_dbus_emit_property_changed(btd_get_dbus_connection(), path,
				PROXIMITY_INTERFACE, "ImmediateAlertLevel");

	monitor->immediateto = g_timeout_add_seconds(IMMEDIATE_TIMEOUT,
						immediate_timeout, monitor);
}

static void write_immediate_alert(struct monitor *monitor)
{
	uint8_t value = str2level(monitor->immediatelevel);

	gatt_write_cmd(monitor->attrib, monitor->immediatehandle, &value, 1,
						immediate_written, monitor);
}

static void immediate_handle_cb(uint8_t status, GSList *characteristics,
								void *user_data)
{
	struct monitor *monitor = user_data;
	struct gatt_char *chr;

	if (status) {
		error("Discover Immediate Alert handle: %s",
						att_ecode2str(status));
		return;
	}

	chr = characteristics->data;
	monitor->immediatehandle = chr->value_handle;

	DBG("Immediate Alert handle: 0x%04x", monitor->immediatehandle);

	if (monitor->fallbacklevel)
		write_immediate_alert(monitor);
}

static void discover_immediate_handle(struct monitor *monitor)
{
	struct att_range *immediate = monitor->immediate;
	bt_uuid_t uuid;

	bt_uuid16_create(&uuid, ALERT_LEVEL_CHR_UUID);

	gatt_discover_char(monitor->attrib, immediate->start, immediate->end,
					&uuid, immediate_handle_cb, monitor);
}

static void attio_connected_cb(GAttrib *attrib, gpointer user_data)
{
	struct monitor *monitor = user_data;

	monitor->attrib = g_attrib_ref(attrib);

	if (monitor->enabled.linkloss)
		write_alert_level(monitor);

	if (monitor->enabled.pathloss)
		read_tx_power(monitor);

	if (monitor->immediatehandle == 0) {
		if(monitor->enabled.pathloss || monitor->enabled.findme)
			discover_immediate_handle(monitor);
	} else if (monitor->fallbacklevel)
		write_immediate_alert(monitor);
}

static void attio_disconnected_cb(gpointer user_data)
{
	struct monitor *monitor = user_data;
	const char *path = device_get_path(monitor->device);

	g_attrib_unref(monitor->attrib);
	monitor->attrib = NULL;

	if (monitor->immediateto == 0)
		return;

	g_source_remove(monitor->immediateto);
	monitor->immediateto = 0;

	if (g_strcmp0(monitor->immediatelevel, "none") == 0)
		return;

	g_free(monitor->immediatelevel);
	monitor->immediatelevel = g_strdup("none");

	g_dbus_emit_property_changed(btd_get_dbus_connection(), path,
				PROXIMITY_INTERFACE, "ImmediateAlertLevel");
}

static gboolean level_is_valid(const char *level)
{
	return (g_str_equal("none", level) ||
			g_str_equal("mild", level) ||
			g_str_equal("high", level));
}

static gboolean property_get_link_loss_level(const GDBusPropertyTable *property,
					DBusMessageIter *iter, void *data)
{
	struct monitor *monitor = data;

	dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
						&monitor->linklosslevel);

	return TRUE;
}

static void property_set_link_loss_level(const GDBusPropertyTable *property,
		DBusMessageIter *iter, GDBusPendingPropertySet id, void *data)
{
	struct monitor *monitor = data;
	const char *level;

	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_STRING) {
		g_dbus_pending_property_error(id,
					ERROR_INTERFACE ".InvalidArguments",
					"Invalid arguments in method call");
		return;
	}

	dbus_message_iter_get_basic(iter, &level);

	if (!level_is_valid(level)) {
		g_dbus_pending_property_error(id,
					ERROR_INTERFACE ".InvalidArguments",
					"Invalid arguments in method call");
		return;
	}

	if (g_strcmp0(monitor->linklosslevel, level) == 0)
		goto done;

	g_free(monitor->linklosslevel);
	monitor->linklosslevel = g_strdup(level);

	write_proximity_config(monitor->device, "LinkLossAlertLevel", level);

	if (monitor->attrib)
		write_alert_level(monitor);

done:
	g_dbus_pending_property_success(id);
}

static gboolean property_exists_link_loss_level(
				const GDBusPropertyTable *property, void *data)
{
	struct monitor *monitor = data;

	if (!monitor->enabled.linkloss)
		return FALSE;

	return TRUE;
}

static gboolean property_get_immediate_alert_level(
					const GDBusPropertyTable *property,
					DBusMessageIter *iter, void *data)
{
	struct monitor *monitor = data;

	dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
						&monitor->immediatelevel);

	return TRUE;
}

static void property_set_immediate_alert_level(
		const GDBusPropertyTable *property, DBusMessageIter *iter,
		GDBusPendingPropertySet id, void *data)
{
	struct monitor *monitor = data;
	struct btd_device *device = monitor->device;
	const char *level;

	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_STRING) {
		g_dbus_pending_property_error(id,
					ERROR_INTERFACE ".InvalidArguments",
					"Invalid arguments in method call");
		return;
	}

	dbus_message_iter_get_basic(iter, &level);

	if (!level_is_valid(level)) {
		g_dbus_pending_property_error(id,
					ERROR_INTERFACE ".InvalidArguments",
					"Invalid arguments in method call");
		return;
	}

	if (g_strcmp0(monitor->immediatelevel, level) == 0)
		goto done;

	if (monitor->immediateto) {
		g_source_remove(monitor->immediateto);
		monitor->immediateto = 0;
	}

	/* Previous Immediate Alert level if connection/write fails */
	g_free(monitor->fallbacklevel);
	monitor->fallbacklevel = monitor->immediatelevel;

	monitor->immediatelevel = g_strdup(level);

	/*
	 * Means that Link/Path Loss are disabled or there is a pending
	 * writting for Find Me(Immediate Alert characteristic value).
	 * If enabled, Path Loss always registers a connection callback
	 * when the Proximity Monitor starts.
	 */
	if (monitor->attioid == 0)
		monitor->attioid = btd_device_add_attio_callback(device,
							attio_connected_cb,
							attio_disconnected_cb,
							monitor);
	else if (monitor->attrib)
		write_immediate_alert(monitor);

done:
	g_dbus_pending_property_success(id);
}

static gboolean property_exists_immediate_alert_level(
				const GDBusPropertyTable *property, void *data)
{
	struct monitor *monitor = data;

	if (!(monitor->enabled.findme || monitor->enabled.pathloss))
		return FALSE;

	return TRUE;
}

static gboolean property_get_signal_level(
					const GDBusPropertyTable *property,
					DBusMessageIter *iter, void *data)
{
	struct monitor *monitor = data;

	dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
						&monitor->signallevel);

	return TRUE;
}

static gboolean property_exists_signal_level(const GDBusPropertyTable *property,
								void *data)
{
	struct monitor *monitor = data;

	if (!monitor->enabled.pathloss)
		return FALSE;

	return TRUE;
}

static const GDBusPropertyTable monitor_device_properties[] = {
	{ "LinkLossAlertLevel", "s", property_get_link_loss_level,
					property_set_link_loss_level,
					property_exists_link_loss_level },
	{ "ImmediateAlertLevel", "s", property_get_immediate_alert_level,
					property_set_immediate_alert_level,
					property_exists_immediate_alert_level },
	{ "SignalLevel", "s", property_get_signal_level, NULL,
					property_exists_signal_level },
	{ }
};

static void monitor_destroy(gpointer user_data)
{
	struct monitor *monitor = user_data;

	btd_device_unref(monitor->device);
	g_free(monitor->linklosslevel);
	g_free(monitor->immediatelevel);
	g_free(monitor->signallevel);
	g_free(monitor);

	monitors = g_slist_remove(monitors, monitor);
}

static struct monitor *register_monitor(struct btd_device *device)
{
	const char *path = device_get_path(device);
	struct monitor *monitor;
	char *level;

	monitor = find_monitor(device);
	if (monitor != NULL)
		return monitor;

	level = read_proximity_config(device, "LinkLossAlertLevel");

	monitor = g_new0(struct monitor, 1);
	monitor->device = btd_device_ref(device);
	monitor->linklosslevel = (level ? : g_strdup("high"));
	monitor->signallevel = g_strdup("unknown");
	monitor->immediatelevel = g_strdup("none");

	monitors = g_slist_append(monitors, monitor);

	if (g_dbus_register_interface(btd_get_dbus_connection(), path,
				PROXIMITY_INTERFACE,
				NULL, NULL, monitor_device_properties,
				monitor, monitor_destroy) == FALSE) {
		error("D-Bus failed to register %s interface",
						PROXIMITY_INTERFACE);
		monitor_destroy(monitor);
		return NULL;
	}

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

	return monitor;
}

static void update_monitor(struct monitor *monitor)
{
	if (monitor->txpower != NULL && monitor->immediate != NULL)
		monitor->enabled.pathloss = TRUE;
	else
		monitor->enabled.pathloss = FALSE;

	DBG("Link Loss: %s, Path Loss: %s, FindMe: %s",
				monitor->enabled.linkloss ? "TRUE" : "FALSE",
				monitor->enabled.pathloss ? "TRUE" : "FALSE",
				monitor->enabled.findme ? "TRUE" : "FALSE");

	if (!monitor->enabled.linkloss && !monitor->enabled.pathloss)
		return;

	if (monitor->attioid != 0)
		return;

	monitor->attioid = btd_device_add_attio_callback(monitor->device,
							attio_connected_cb,
							attio_disconnected_cb,
							monitor);
}

int monitor_register_linkloss(struct btd_device *device,
						struct enabled *enabled,
						struct gatt_primary *linkloss)
{
	struct monitor *monitor;

	if (!enabled->linkloss)
		return 0;

	monitor = register_monitor(device);
	if (monitor == NULL)
		return -1;

	monitor->linkloss = g_new0(struct att_range, 1);
	monitor->linkloss->start = linkloss->range.start;
	monitor->linkloss->end = linkloss->range.end;
	monitor->enabled.linkloss = TRUE;

	update_monitor(monitor);

	return 0;
}

int monitor_register_txpower(struct btd_device *device,
						struct enabled *enabled,
						struct gatt_primary *txpower)
{
	struct monitor *monitor;

	if (!enabled->pathloss)
		return 0;

	monitor = register_monitor(device);
	if (monitor == NULL)
		return -1;

	monitor->txpower = g_new0(struct att_range, 1);
	monitor->txpower->start = txpower->range.start;
	monitor->txpower->end = txpower->range.end;

	update_monitor(monitor);

	return 0;
}

int monitor_register_immediate(struct btd_device *device,
						struct enabled *enabled,
						struct gatt_primary *immediate)
{
	struct monitor *monitor;

	if (!enabled->pathloss && !enabled->findme)
		return 0;

	monitor = register_monitor(device);
	if (monitor == NULL)
		return -1;

	monitor->immediate = g_new0(struct att_range, 1);
	monitor->immediate->start = immediate->range.start;
	monitor->immediate->end = immediate->range.end;
	monitor->enabled.findme = enabled->findme;

	update_monitor(monitor);

	return 0;
}

static void cleanup_monitor(struct monitor *monitor)
{
	struct btd_device *device = monitor->device;
	const char *path = device_get_path(device);

	if (monitor->immediate != NULL || monitor->txpower != NULL)
		return;

	if (monitor->immediateto != 0) {
		g_source_remove(monitor->immediateto);
		monitor->immediateto = 0;
	}

	if (monitor->linkloss != NULL)
		return;

	if (monitor->attioid != 0) {
		btd_device_remove_attio_callback(device, monitor->attioid);
		monitor->attioid = 0;
	}

	if (monitor->attrib != NULL) {
		g_attrib_unref(monitor->attrib);
		monitor->attrib = NULL;
	}

	g_dbus_unregister_interface(btd_get_dbus_connection(), path,
							PROXIMITY_INTERFACE);
}

void monitor_unregister_linkloss(struct btd_device *device)
{
	struct monitor *monitor;

	monitor = find_monitor(device);
	if (monitor == NULL)
		return;

	g_free(monitor->linkloss);
	monitor->linkloss = NULL;
	monitor->enabled.linkloss = FALSE;

	cleanup_monitor(monitor);
}

void monitor_unregister_txpower(struct btd_device *device)
{
	struct monitor *monitor;

	monitor = find_monitor(device);
	if (monitor == NULL)
		return;

	g_free(monitor->txpower);
	monitor->txpower = NULL;
	monitor->enabled.pathloss = FALSE;

	cleanup_monitor(monitor);
}

void monitor_unregister_immediate(struct btd_device *device)
{
	struct monitor *monitor;

	monitor = find_monitor(device);
	if (monitor == NULL)
		return;

	g_free(monitor->immediate);
	monitor->immediate = NULL;
	monitor->enabled.findme = FALSE;
	monitor->enabled.pathloss = FALSE;

	cleanup_monitor(monitor);
}
