/*
 *
 *  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 "dbus-common.h"
#include "adapter.h"
#include "device.h"
#include "error.h"
#include "log.h"
#include "attrib/att.h"
#include "attrib/gattrib.h"
#include "attrib/gatt.h"
#include "attio.h"
#include "monitor.h"
#include "textfile.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);
}
