/*
 *
 *  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 <glib.h>
#include <bluetooth/sdp.h>
#include <adapter.h>

#include "lib/uuid.h"
#include "gattrib.h"
#include "att.h"
#include "gatt.h"
#include "att-database.h"
#include "attrib-server.h"
#include "gatt-service.h"
#include "log.h"

struct gatt_info {
	bt_uuid_t uuid;
	uint8_t props;
	int authentication;
	int authorization;
	GSList *callbacks;
	unsigned int num_attrs;
	uint16_t *value_handle;
	uint16_t *ccc_handle;
};

struct attrib_cb {
	attrib_event_t event;
	void *fn;
	void *user_data;
};

static GSList *parse_opts(gatt_option opt1, va_list args)
{
	gatt_option opt = opt1;
	struct gatt_info *info;
	struct attrib_cb *cb;
	GSList *l = NULL;

	info = g_new0(struct gatt_info, 1);
	l = g_slist_append(l, info);

	while (opt != GATT_OPT_INVALID) {
		switch (opt) {
		case GATT_OPT_CHR_UUID16:
			bt_uuid16_create(&info->uuid, va_arg(args, int));
			/* characteristic declaration and value */
			info->num_attrs += 2;
			break;
		case GATT_OPT_CHR_UUID:
			memcpy(&info->uuid, va_arg(args, bt_uuid_t *),
							sizeof(bt_uuid_t));
			/* characteristic declaration and value */
			info->num_attrs += 2;
			break;
		case GATT_OPT_CHR_PROPS:
			info->props = va_arg(args, int);

			if (info->props & (ATT_CHAR_PROPER_NOTIFY |
						ATT_CHAR_PROPER_INDICATE))
				/* client characteristic configuration */
				info->num_attrs += 1;

			/* TODO: "Extended Properties" property requires a
			 * descriptor, but it is not supported yet. */
			break;
		case GATT_OPT_CHR_VALUE_CB:
			cb = g_new0(struct attrib_cb, 1);
			cb->event = va_arg(args, attrib_event_t);
			cb->fn = va_arg(args, void *);
			cb->user_data = va_arg(args, void *);
			info->callbacks = g_slist_append(info->callbacks, cb);
			break;
		case GATT_OPT_CHR_VALUE_GET_HANDLE:
			info->value_handle = va_arg(args, void *);
			break;
		case GATT_OPT_CCC_GET_HANDLE:
			info->ccc_handle = va_arg(args, void *);
			break;
		case GATT_OPT_CHR_AUTHENTICATION:
			info->authentication = va_arg(args, gatt_option);
			break;
		case GATT_OPT_CHR_AUTHORIZATION:
			info->authorization = va_arg(args, gatt_option);
			break;
		default:
			error("Invalid option: %d", opt);
		}

		opt = va_arg(args, gatt_option);
		if (opt == GATT_OPT_CHR_UUID16 || opt == GATT_OPT_CHR_UUID) {
			info = g_new0(struct gatt_info, 1);
			l = g_slist_append(l, info);
		}
	}

	return l;
}

static struct attribute *add_service_declaration(struct btd_adapter *adapter,
				uint16_t handle, uint16_t svc, bt_uuid_t *uuid)
{
	bt_uuid_t bt_uuid;
	uint8_t atval[16];
	int len;

	if (uuid->type == BT_UUID16) {
		att_put_u16(uuid->value.u16, &atval[0]);
		len = 2;
	} else if (uuid->type == BT_UUID128) {
		att_put_u128(uuid->value.u128, &atval[0]);
		len = 16;
	} else
		return NULL;

	bt_uuid16_create(&bt_uuid, svc);

	return attrib_db_add(adapter, handle, &bt_uuid, ATT_NONE,
						ATT_NOT_PERMITTED, atval, len);
}

static int att_read_req(int authorization, int authentication, uint8_t props)
{
	if (authorization == GATT_CHR_VALUE_READ ||
				authorization == GATT_CHR_VALUE_BOTH)
		return ATT_AUTHORIZATION;
	else if (authentication == GATT_CHR_VALUE_READ ||
				authentication == GATT_CHR_VALUE_BOTH)
		return ATT_AUTHENTICATION;
	else if (!(props & ATT_CHAR_PROPER_READ))
		return ATT_NOT_PERMITTED;

	return ATT_NONE;
}

static int att_write_req(int authorization, int authentication, uint8_t props)
{
	if (authorization == GATT_CHR_VALUE_WRITE ||
				authorization == GATT_CHR_VALUE_BOTH)
		return ATT_AUTHORIZATION;
	else if (authentication == GATT_CHR_VALUE_WRITE ||
				authentication == GATT_CHR_VALUE_BOTH)
		return ATT_AUTHENTICATION;
	else if (!(props & (ATT_CHAR_PROPER_WRITE |
					ATT_CHAR_PROPER_WRITE_WITHOUT_RESP)))
		return ATT_NOT_PERMITTED;

	return ATT_NONE;
}

static int find_callback(gconstpointer a, gconstpointer b)
{
	const struct attrib_cb *cb = a;
	unsigned int event = GPOINTER_TO_UINT(b);

	return cb->event - event;
}

static gboolean add_characteristic(struct btd_adapter *adapter,
				uint16_t *handle, struct gatt_info *info)
{
	int read_req, write_req;
	uint16_t h = *handle;
	struct attribute *a;
	bt_uuid_t bt_uuid;
	uint8_t atval[ATT_MAX_VALUE_LEN];
	GSList *l;

	if ((info->uuid.type != BT_UUID16 && info->uuid.type != BT_UUID128) ||
								!info->props) {
		error("Characteristic UUID or properties are missing");
		return FALSE;
	}

	read_req = att_read_req(info->authorization, info->authentication,
								info->props);
	write_req = att_write_req(info->authorization, info->authentication,
								info->props);

	/* TODO: static characteristic values are not supported, therefore a
	 * callback must be always provided if a read/write property is set */
	if (read_req != ATT_NOT_PERMITTED) {
		gpointer reqs = GUINT_TO_POINTER(ATTRIB_READ);

		if (!g_slist_find_custom(info->callbacks, reqs,
							find_callback)) {
			error("Callback for read required");
			return FALSE;
		}
	}

	if (write_req != ATT_NOT_PERMITTED) {
		gpointer reqs = GUINT_TO_POINTER(ATTRIB_WRITE);

		if (!g_slist_find_custom(info->callbacks, reqs,
							find_callback)) {
			error("Callback for write required");
			return FALSE;
		}
	}

	/* characteristic declaration */
	bt_uuid16_create(&bt_uuid, GATT_CHARAC_UUID);
	atval[0] = info->props;
	att_put_u16(h + 1, &atval[1]);
	att_put_uuid(info->uuid, &atval[3]);
	if (attrib_db_add(adapter, h++, &bt_uuid, ATT_NONE, ATT_NOT_PERMITTED,
				atval, 3 + info->uuid.type / 8) == NULL)
		return FALSE;

	/* characteristic value */
	a = attrib_db_add(adapter, h++, &info->uuid, read_req, write_req,
								NULL, 0);
	if (a == NULL)
		return FALSE;

	for (l = info->callbacks; l != NULL; l = l->next) {
		struct attrib_cb *cb = l->data;

		switch (cb->event) {
		case ATTRIB_READ:
			a->read_cb = cb->fn;
			break;
		case ATTRIB_WRITE:
			a->write_cb = cb->fn;
			break;
		}

		a->cb_user_data = cb->user_data;
	}

	if (info->value_handle != NULL)
		*info->value_handle = a->handle;

	/* client characteristic configuration descriptor */
	if (info->props & (ATT_CHAR_PROPER_NOTIFY | ATT_CHAR_PROPER_INDICATE)) {
		uint8_t cfg_val[2];

		bt_uuid16_create(&bt_uuid, GATT_CLIENT_CHARAC_CFG_UUID);
		cfg_val[0] = 0x00;
		cfg_val[1] = 0x00;
		a = attrib_db_add(adapter, h++, &bt_uuid, ATT_NONE,
				ATT_AUTHENTICATION, cfg_val, sizeof(cfg_val));
		if (a == NULL)
			return FALSE;

		if (info->ccc_handle != NULL)
			*info->ccc_handle = a->handle;
	}

	*handle = h;

	return TRUE;
}

static void free_gatt_info(void *data)
{
	struct gatt_info *info = data;

	g_slist_free_full(info->callbacks, g_free);
	g_free(info);
}

static void service_attr_del(struct btd_adapter *adapter, uint16_t start_handle,
							uint16_t end_handle)
{
	uint16_t handle;

	for (handle = start_handle; handle <= end_handle; handle++)
		if (attrib_db_del(adapter, handle) < 0)
			error("Can't delete handle 0x%04x", handle);
}

gboolean gatt_service_add(struct btd_adapter *adapter, uint16_t uuid,
				bt_uuid_t *svc_uuid, gatt_option opt1, ...)
{
	char uuidstr[MAX_LEN_UUID_STR];
	uint16_t start_handle, h;
	unsigned int size;
	va_list args;
	GSList *chrs, *l;

	bt_uuid_to_string(svc_uuid, uuidstr, MAX_LEN_UUID_STR);

	if (svc_uuid->type != BT_UUID16 && svc_uuid->type != BT_UUID128) {
		error("Invalid service uuid: %s", uuidstr);
		return FALSE;
	}

	va_start(args, opt1);
	chrs = parse_opts(opt1, args);
	va_end(args);

	/* calculate how many attributes are necessary for this service */
	for (l = chrs, size = 1; l != NULL; l = l->next) {
		struct gatt_info *info = l->data;
		size += info->num_attrs;
	}

	start_handle = attrib_db_find_avail(adapter, svc_uuid, size);
	if (start_handle == 0) {
		error("Not enough free handles to register service");
		goto fail;
	}

	DBG("New service: handle 0x%04x, UUID %s, %d attributes",
						start_handle, uuidstr, size);

	/* service declaration */
	h = start_handle;
	if (add_service_declaration(adapter, h++, uuid, svc_uuid) == NULL)
		goto fail;

	for (l = chrs; l != NULL; l = l->next) {
		struct gatt_info *info = l->data;

		DBG("New characteristic: handle 0x%04x", h);
		if (!add_characteristic(adapter, &h, info)) {
			service_attr_del(adapter, start_handle, h - 1);
			goto fail;
		}
	}

	g_assert(size < USHRT_MAX);
	g_assert(h == 0 || (h - start_handle == (uint16_t) size));
	g_slist_free_full(chrs, free_gatt_info);

	return TRUE;

fail:
	g_slist_free_full(chrs, free_gatt_info);
	return FALSE;
}
