/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2012 Texas Instruments Corporation
 *
 *  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 <stdbool.h>

#include <glib.h>
#include <adapter.h>

#include <dbus/dbus.h>
#include <gdbus/gdbus.h>

#include "lib/uuid.h"
#include "log.h"
#include "attrib/gattrib.h"
#include "attrib/att.h"
#include "attrib/gatt.h"
#include "attrib/att-database.h"
#include "attrib/gatt-service.h"
#include "attrib-server.h"
#include "device.h"
#include "profile.h"
#include "attio.h"
#include "dbus-common.h"
#include "reporter.h"
#include "immalert.h"

struct imm_alert_adapter {
	struct btd_adapter *adapter;
	GSList *connected_devices;
};

struct connected_device {
	struct btd_device *device;
	struct imm_alert_adapter *adapter;
	uint8_t alert_level;
	guint callback_id;
};

static GSList *imm_alert_adapters;

static int imdevice_cmp(gconstpointer a, gconstpointer b)
{
	const struct connected_device *condev = a;
	const struct btd_device *device = b;

	if (condev->device == device)
		return 0;

	return -1;
}

static struct connected_device *
find_connected_device(struct imm_alert_adapter *ia, struct btd_device *device)
{
	GSList *l = g_slist_find_custom(ia->connected_devices, device,
								imdevice_cmp);
	if (!l)
		return NULL;

	return l->data;
}

static int imadapter_cmp(gconstpointer a, gconstpointer b)
{
	const struct imm_alert_adapter *imadapter = a;
	const struct btd_adapter *adapter = b;

	if (imadapter->adapter == adapter)
		return 0;

	return -1;
}

static struct imm_alert_adapter *
find_imm_alert_adapter(struct btd_adapter *adapter)
{
	GSList *l = g_slist_find_custom(imm_alert_adapters, adapter,
								imadapter_cmp);
	if (!l)
		return NULL;

	return l->data;
}

const char *imm_alert_get_level(struct btd_device *device)
{
	struct imm_alert_adapter *imadapter;
	struct connected_device *condev;

	if (!device)
		return get_alert_level_string(NO_ALERT);

	imadapter = find_imm_alert_adapter(device_get_adapter(device));
	if (!imadapter)
		return get_alert_level_string(NO_ALERT);

	condev = find_connected_device(imadapter, device);
	if (!condev)
		return get_alert_level_string(NO_ALERT);

	return get_alert_level_string(condev->alert_level);
}

static void imm_alert_emit_alert_signal(struct connected_device *condev,
							uint8_t alert_level)
{
	const char *path, *alert_level_str;

	if (!condev)
		return;

	path = device_get_path(condev->device);
	alert_level_str = get_alert_level_string(alert_level);

	DBG("alert %s remote %s", alert_level_str, path);

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

static void imm_alert_remove_condev(struct connected_device *condev)
{
	struct imm_alert_adapter *ia;

	if (!condev)
		return;

	ia = condev->adapter;

	if (condev->callback_id && condev->device)
		btd_device_remove_attio_callback(condev->device,
							condev->callback_id);

	if (condev->device)
		btd_device_unref(condev->device);

	ia->connected_devices = g_slist_remove(ia->connected_devices, condev);
	g_free(condev);
}

/* condev can be NULL */
static void imm_alert_disc_cb(gpointer user_data)
{
	struct connected_device *condev = user_data;

	if (!condev)
		return;

	DBG("immediate alert remove device %p", condev->device);

	imm_alert_emit_alert_signal(condev, NO_ALERT);
	imm_alert_remove_condev(condev);
}

static uint8_t imm_alert_alert_lvl_write(struct attribute *a,
				struct btd_device *device, gpointer user_data)
{
	uint8_t value;
	struct imm_alert_adapter *ia = user_data;
	struct connected_device *condev = NULL;

	if (!device)
		goto set_error;

	condev = find_connected_device(ia, device);

	if (a->len == 0) {
		DBG("Illegal alert level length");
		goto set_error;
	}

	value = a->data[0];
	if (value != NO_ALERT && value != MILD_ALERT && value != HIGH_ALERT) {
		DBG("Illegal alert value");
		goto set_error;
	}

	/* Register a disconnect cb if the alert level is non-zero */
	if (value != NO_ALERT && !condev) {
		condev = g_new0(struct connected_device, 1);
		condev->device = btd_device_ref(device);
		condev->adapter = ia;
		condev->callback_id = btd_device_add_attio_callback(device,
					NULL, imm_alert_disc_cb, condev);
		ia->connected_devices = g_slist_append(ia->connected_devices,
								condev);
		DBG("added connected dev %p", device);
	}

	if (value != NO_ALERT) {
		condev->alert_level = value;
		imm_alert_emit_alert_signal(condev, value);
	}

	/*
	 * Emit NO_ALERT if the alert level was non-zero before. This is
	 * guaranteed when there's a condev.
	 */
	if (value == NO_ALERT && condev)
		imm_alert_disc_cb(condev);

	DBG("alert level set to %d by device %p", value, device);
	return 0;

set_error:
	error("Set immediate alert level for dev %p", device);
	/* remove alerts by erroneous devices */
	imm_alert_disc_cb(condev);
	return ATT_ECODE_IO;
}

void imm_alert_register(struct btd_adapter *adapter)
{
	gboolean svc_added;
	bt_uuid_t uuid;
	struct imm_alert_adapter *imadapter;

	bt_uuid16_create(&uuid, IMMEDIATE_ALERT_SVC_UUID);

	imadapter = g_new0(struct imm_alert_adapter, 1);
	imadapter->adapter = adapter;

	imm_alert_adapters = g_slist_append(imm_alert_adapters, imadapter);

	/* Immediate Alert Service */
	svc_added = gatt_service_add(adapter,
				GATT_PRIM_SVC_UUID, &uuid,
				/* Alert level characteristic */
				GATT_OPT_CHR_UUID16, ALERT_LEVEL_CHR_UUID,
				GATT_OPT_CHR_PROPS,
					ATT_CHAR_PROPER_WRITE_WITHOUT_RESP,
				GATT_OPT_CHR_VALUE_CB, ATTRIB_WRITE,
					imm_alert_alert_lvl_write, imadapter,
				GATT_OPT_INVALID);

	if (!svc_added) {
		imm_alert_unregister(adapter);
		return;
	}

	DBG("Immediate Alert service added");
}

static void remove_condev_list_item(gpointer data, gpointer user_data)
{
	struct connected_device *condev = data;

	imm_alert_remove_condev(condev);
}

void imm_alert_unregister(struct btd_adapter *adapter)
{
	struct imm_alert_adapter *imadapter;

	imadapter = find_imm_alert_adapter(adapter);
	if (!imadapter)
		return;

	g_slist_foreach(imadapter->connected_devices, remove_condev_list_item,
									NULL);

	imm_alert_adapters = g_slist_remove(imm_alert_adapters, imadapter);
	g_free(imadapter);
}
