/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2012  Instituto Nokia de Tecnologia - INdT
 *
 *  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 <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>

#include <glib.h>
#include <btio/btio.h>

#include "lib/uuid.h"
#include "plugin.h"
#include "adapter.h"
#include "device.h"
#include "profile.h"
#include "service.h"
#include "attrib/att.h"
#include "attrib/gattrib.h"
#include "attio.h"
#include "attrib/gatt.h"
#include "log.h"
#include "textfile.h"

/* Generic Attribute/Access Service */
struct gas {
	struct btd_device *device;
	struct att_range gap;	/* GAP Primary service range */
	struct att_range gatt;	/* GATT Primary service range */
	GAttrib *attrib;
	guint attioid;
	guint changed_ind;
	uint16_t changed_handle;
	uint16_t mtu;
};

static GSList *devices = NULL;

static void gas_free(struct gas *gas)
{
	if (gas->attioid)
		btd_device_remove_attio_callback(gas->device, gas->attioid);

	g_attrib_unref(gas->attrib);
	btd_device_unref(gas->device);
	g_free(gas);
}

static int cmp_device(gconstpointer a, gconstpointer b)
{
	const struct gas *gas = a;
	const struct btd_device *device = b;

	return (gas->device == device ? 0 : -1);
}

static void write_ctp_handle(struct btd_device *device, uint16_t uuid,
					uint16_t handle)
{
	char *filename, group[6], value[7];
	GKeyFile *key_file;
	char *data;
	gsize length = 0;

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

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

	snprintf(group, sizeof(group), "%hu", uuid);
	snprintf(value, sizeof(value), "0x%4.4X", handle);
	g_key_file_set_string(key_file, group, "Value", value);

	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 int read_ctp_handle(struct btd_device *device, uint16_t uuid,
					uint16_t *value)
{
	char *filename, group[6];
	GKeyFile *key_file;
	char *str;
	int err = 0;

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

	snprintf(group, sizeof(group), "%hu", uuid);

	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, group, "Value", NULL);
	if (str == NULL || sscanf(str, "%hx", value) != 1)
		err = -ENOENT;

	g_free(str);
	g_free(filename);
	g_key_file_free(key_file);

	return err;
}

static void gap_appearance_cb(guint8 status, const guint8 *pdu, guint16 plen,
							gpointer user_data)
{
	struct gas *gas = user_data;
	struct att_data_list *list =  NULL;
	uint16_t app;
	uint8_t *atval;

	if (status != 0) {
		error("Read characteristics by UUID failed: %s",
				att_ecode2str(status));
		return;
	}

	list = dec_read_by_type_resp(pdu, plen);
	if (list == NULL)
		return;

	if (list->len != 4) {
		error("GAP Appearance value: invalid data");
		goto done;
	}

	atval = list->data[0] + 2; /* skip handle value */
	app = att_get_u16(atval);

	DBG("GAP Appearance: 0x%04x", app);

	device_set_appearance(gas->device, app);

done:
	att_data_list_free(list);
}

static void indication_cb(const uint8_t *pdu, uint16_t len, gpointer user_data)
{
	struct gas *gas = user_data;
	uint16_t start, end, olen;
	size_t plen;
	uint8_t *opdu;

	if (len < 7) { /* 1-byte opcode + 2-byte handle + 4 range */
		error("Malformed ATT notification");
		return;
	}

	start = att_get_u16(&pdu[3]);
	end = att_get_u16(&pdu[5]);

	DBG("Service Changed start: 0x%04X end: 0x%04X", start, end);

	/* Confirming indication received */
	opdu = g_attrib_get_buffer(gas->attrib, &plen);
	olen = enc_confirmation(opdu, plen);
	g_attrib_send(gas->attrib, 0, opdu, olen, NULL, NULL, NULL);

	if (device_is_bonded(gas->device) == FALSE) {
		DBG("Ignoring Service Changed: device is not bonded");
		return;
	}

	btd_device_gatt_set_service_changed(gas->device, start, end);
}

static void ccc_written_cb(guint8 status, const guint8 *pdu, guint16 plen,
							gpointer user_data)
{
	struct gas *gas = user_data;

	if (status) {
		error("Write Service Changed CCC failed: %s",
						att_ecode2str(status));
		return;
	}

	DBG("Service Changed indications enabled");

	gas->changed_ind = g_attrib_register(gas->attrib, ATT_OP_HANDLE_IND,
						gas->changed_handle,
						indication_cb, gas, NULL);

	write_ctp_handle(gas->device, GATT_CHARAC_SERVICE_CHANGED,
					gas->changed_handle);
}

static void write_ccc(GAttrib *attrib, uint16_t handle, gpointer user_data)
{
	uint8_t value[2];

	att_put_u16(GATT_CLIENT_CHARAC_CFG_IND_BIT, value);
	gatt_write_char(attrib, handle, value, sizeof(value), ccc_written_cb,
								user_data);
}

static void gatt_descriptors_cb(guint8 status, const guint8 *pdu, guint16 len,
							gpointer user_data)
{
	struct gas *gas = user_data;
	struct att_data_list *list;
	int i;
	uint8_t format;

	if (status) {
		error("Discover all GATT characteristic descriptors: %s",
							att_ecode2str(status));
		return;
	}

	list = dec_find_info_resp(pdu, len, &format);
	if (list == NULL)
		return;

	if (format != ATT_FIND_INFO_RESP_FMT_16BIT)
		goto done;

	for (i = 0; i < list->num; i++) {
		uint16_t uuid16, ccc;
		uint8_t *value;

		value = list->data[i];
		ccc = att_get_u16(value);
		uuid16 = att_get_u16(&value[2]);
		DBG("CCC: 0x%04x UUID: 0x%04x", ccc, uuid16);
		write_ccc(gas->attrib, ccc, user_data);
	}

done:
	att_data_list_free(list);
}

static void gatt_characteristic_cb(GSList *characteristics, guint8 status,
							gpointer user_data)
{
	struct gas *gas = user_data;
	struct gatt_char *chr;
	uint16_t start, end;

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

	chr = characteristics->data;

	start = chr->value_handle + 1;
	end = gas->gatt.end;

	if (start > end) {
		error("Inconsistent database: Service Changed CCC missing");
		return;
	}

	gas->changed_handle = chr->value_handle;
	gatt_discover_char_desc(gas->attrib, start, end, gatt_descriptors_cb,
									gas);
}

static void exchange_mtu_cb(guint8 status, const guint8 *pdu, guint16 plen,
							gpointer user_data)
{
	struct gas *gas = user_data;
	uint16_t rmtu;

	if (status) {
		error("MTU exchange: %s", att_ecode2str(status));
		return;
	}

	if (!dec_mtu_resp(pdu, plen, &rmtu)) {
		error("MTU exchange: protocol error");
		return;
	}

	gas->mtu = MIN(rmtu, gas->mtu);
	if (g_attrib_set_mtu(gas->attrib, gas->mtu))
		DBG("MTU exchange succeeded: %d", gas->mtu);
	else
		DBG("MTU exchange failed");
}

static void attio_connected_cb(GAttrib *attrib, gpointer user_data)
{
	struct gas *gas = user_data;
	GIOChannel *io;
	GError *gerr = NULL;
	uint16_t cid, imtu;
	uint16_t app;

	gas->attrib = g_attrib_ref(attrib);
	io = g_attrib_get_channel(attrib);

	if (bt_io_get(io, &gerr, BT_IO_OPT_IMTU, &imtu,
				BT_IO_OPT_CID, &cid, BT_IO_OPT_INVALID) &&
							cid == ATT_CID) {
		gatt_exchange_mtu(gas->attrib, imtu, exchange_mtu_cb, gas);
		gas->mtu = imtu;
		DBG("MTU Exchange: Requesting %d", imtu);
	}

	if (device_get_appearance(gas->device, &app) < 0) {
		bt_uuid_t uuid;

		bt_uuid16_create(&uuid, GATT_CHARAC_APPEARANCE);

		gatt_read_char_by_uuid(gas->attrib, gas->gap.start,
						gas->gap.end, &uuid,
						gap_appearance_cb, gas);
	}

	/* TODO: Read other GAP characteristics - See Core spec page 1739 */

	/*
	 * When re-connecting <<Service Changed>> handle and characteristic
	 * value doesn't need to read again: known information from the
	 * previous interaction.
	 */
	if (gas->changed_handle == 0) {
		bt_uuid_t uuid;

		bt_uuid16_create(&uuid, GATT_CHARAC_SERVICE_CHANGED);

		gatt_discover_char(gas->attrib, gas->gatt.start, gas->gatt.end,
					&uuid, gatt_characteristic_cb, gas);
	}
}

static void attio_disconnected_cb(gpointer user_data)
{
	struct gas *gas = user_data;

	g_attrib_unregister(gas->attrib, gas->changed_ind);
	gas->changed_ind = 0;

	g_attrib_unref(gas->attrib);
	gas->attrib = NULL;
}

static int gas_register(struct btd_device *device, struct att_range *gap,
						struct att_range *gatt)
{
	struct gas *gas;

	gas = g_new0(struct gas, 1);
	gas->gap.start = gap->start;
	gas->gap.end = gap->end;
	gas->gatt.start = gatt->start;
	gas->gatt.end = gatt->end;

	gas->device = btd_device_ref(device);

	devices = g_slist_append(devices, gas);

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

	read_ctp_handle(gas->device, GATT_CHARAC_SERVICE_CHANGED,
					&gas->changed_handle);

	return 0;
}

static void gas_unregister(struct btd_device *device)
{
	struct gas *gas;
	GSList *l;

	l = g_slist_find_custom(devices, device, cmp_device);
	if (l == NULL)
		return;

	gas = l->data;
	devices = g_slist_remove(devices, gas);
	gas_free(gas);
}

static int gatt_driver_probe(struct btd_service *service)
{
	struct btd_device *device = btd_service_get_device(service);
	struct gatt_primary *gap, *gatt;

	gap = btd_device_get_primary(device, GAP_UUID);
	gatt = btd_device_get_primary(device, GATT_UUID);

	if (gap == NULL || gatt == NULL) {
		error("GAP and GATT are mandatory");
		return -EINVAL;
	}

	return gas_register(device, &gap->range, &gatt->range);
}

static void gatt_driver_remove(struct btd_service *service)
{
	struct btd_device *device = btd_service_get_device(service);

	gas_unregister(device);
}

static struct btd_profile gatt_profile = {
	.name		= "gap-gatt-profile",
	.remote_uuid	= GATT_UUID,
	.device_probe	= gatt_driver_probe,
	.device_remove	= gatt_driver_remove
};

static int gatt_init(void)
{
	btd_profile_register(&gatt_profile);

	return 0;
}

static void gatt_exit(void)
{
	btd_profile_unregister(&gatt_profile);
}

BLUETOOTH_PLUGIN_DEFINE(gatt, VERSION, BLUETOOTH_PLUGIN_PRIORITY_DEFAULT,
					gatt_init, gatt_exit)
