/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2012  Instituto Nokia de Tecnologia - INdT
 *  Copyright (C) 2014  Google Inc.
 *
 *  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.
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <ctype.h>
#include <stdbool.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>

#include <glib.h>

#include "lib/bluetooth.h"
#include "lib/hci.h"
#include "lib/sdp.h"
#include "lib/uuid.h"

#include "src/shared/util.h"
#include "src/shared/att.h"
#include "src/shared/queue.h"
#include "src/shared/gatt-db.h"
#include "src/shared/gatt-client.h"
#include "src/plugin.h"
#include "src/adapter.h"
#include "src/device.h"
#include "src/profile.h"
#include "src/service.h"
#include "src/log.h"

#define GAP_UUID16 0x1800

/* Generic Attribute/Access Service */
struct gas {
	struct btd_device *device;
	struct gatt_db *db;
	struct bt_gatt_client *client;
	struct gatt_db_attribute *attr;
};

static GSList *devices;

static void gas_free(struct gas *gas)
{
	gatt_db_unref(gas->db);
	bt_gatt_client_unref(gas->client);
	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 char *name2utf8(const uint8_t *name, uint16_t len)
{
	char utf8_name[HCI_MAX_NAME_LENGTH + 2];
	int i;

	if (g_utf8_validate((const char *) name, len, NULL))
		return g_strndup((char *) name, len);

	len = MIN(len, sizeof(utf8_name) - 1);

	memset(utf8_name, 0, sizeof(utf8_name));
	strncpy(utf8_name, (char *) name, len);

	/* Assume ASCII, and replace all non-ASCII with spaces */
	for (i = 0; utf8_name[i] != '\0'; i++) {
		if (!isascii(utf8_name[i]))
			utf8_name[i] = ' ';
	}

	/* Remove leading and trailing whitespace characters */
	g_strstrip(utf8_name);

	return g_strdup(utf8_name);
}

static void read_device_name_cb(bool success, uint8_t att_ecode,
					const uint8_t *value, uint16_t length,
					void *user_data)
{
	struct gas *gas = user_data;
	char *name;

	if (!success) {
		DBG("Reading device name failed with ATT errror: %u",
								att_ecode);
		return;
	}

	if (!length)
		return;

	name = name2utf8(value, length);

	DBG("GAP Device Name: %s", name);

	btd_device_device_set_name(gas->device, name);

	g_free(name);
}

static void handle_device_name(struct gas *gas, uint16_t value_handle)
{
	if (!bt_gatt_client_read_long_value(gas->client, value_handle, 0,
						read_device_name_cb, gas, NULL))
		DBG("Failed to send request to read device name");
}

static void read_appearance_cb(bool success, uint8_t att_ecode,
					const uint8_t *value, uint16_t length,
					void *user_data)
{
	struct gas *gas = user_data;
	uint16_t appearance;

	if (!success) {
		DBG("Reading appearance failed with ATT error: %u", att_ecode);
		return;
	}

	/* The appearance value is a 16-bit unsigned integer */
	if (length != 2) {
		DBG("Malformed appearance value");
		return;
	}

	appearance = get_le16(value);

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

	device_set_appearance(gas->device, appearance);
}

static void handle_appearance(struct gas *gas, uint16_t value_handle)
{
	if (!bt_gatt_client_read_value(gas->client, value_handle,
						read_appearance_cb, gas, NULL))
		DBG("Failed to send request to read appearance");
}

static bool uuid_cmp(uint16_t u16, const bt_uuid_t *uuid)
{
	bt_uuid_t lhs;

	bt_uuid16_create(&lhs, u16);

	return bt_uuid_cmp(&lhs, uuid) == 0;
}

static void handle_characteristic(struct gatt_db_attribute *attr,
								void *user_data)
{
	struct gas *gas = user_data;
	uint16_t value_handle;
	bt_uuid_t uuid;

	if (!gatt_db_attribute_get_char_data(attr, NULL, &value_handle, NULL,
								NULL, &uuid)) {
		error("Failed to obtain characteristic data");
		return;
	}

	if (uuid_cmp(GATT_CHARAC_DEVICE_NAME, &uuid))
		handle_device_name(gas, value_handle);
	else if (uuid_cmp(GATT_CHARAC_APPEARANCE, &uuid))
		handle_appearance(gas, value_handle);
	else {
		char uuid_str[MAX_LEN_UUID_STR];

		/* TODO: Support peripheral privacy feature */

		bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
		DBG("Unsupported characteristic: %s", uuid_str);
	}
}

static void handle_gap_service(struct gas *gas)
{
	gatt_db_service_foreach_char(gas->attr, handle_characteristic, gas);
}

static int gap_driver_probe(struct btd_service *service)
{
	struct btd_device *device = btd_service_get_device(service);
	struct gas *gas;
	GSList *l;
	char addr[18];

	ba2str(device_get_address(device), addr);
	DBG("GAP profile probe (%s)", addr);

	/* Ignore, if we were probed for this device already */
	l = g_slist_find_custom(devices, device, cmp_device);
	if (l) {
		error("Profile probed twice for the same device!");
		return -1;
	}

	gas = g_new0(struct gas, 1);
	if (!gas)
		return -1;

	gas->device = btd_device_ref(device);
	devices = g_slist_append(devices, gas);

	return 0;
}

static void gap_driver_remove(struct btd_service *service)
{
	struct btd_device *device = btd_service_get_device(service);
	struct gas *gas;
	GSList *l;
	char addr[18];

	ba2str(device_get_address(device), addr);
	DBG("GAP profile remove (%s)", addr);

	l = g_slist_find_custom(devices, device, cmp_device);
	if (!l) {
		error("GAP service not handled by profile");
		return;
	}

	gas = l->data;

	devices = g_slist_remove(devices, gas);
	gas_free(gas);
}

static void foreach_gap_service(struct gatt_db_attribute *attr, void *user_data)
{
	struct gas *gas = user_data;

	if (gas->attr) {
		error("More than one GAP service exists for this device");
		return;
	}

	gas->attr = attr;
	handle_gap_service(gas);
}

static int gap_driver_accept(struct btd_service *service)
{
	struct btd_device *device = btd_service_get_device(service);
	struct gatt_db *db = btd_device_get_gatt_db(device);
	struct bt_gatt_client *client = btd_device_get_gatt_client(device);
	struct gas *gas;
	GSList *l;
	char addr[18];
	bt_uuid_t gap_uuid;

	ba2str(device_get_address(device), addr);
	DBG("GAP profile accept (%s)", addr);

	l = g_slist_find_custom(devices, device, cmp_device);
	if (!l) {
		error("GAP service not handled by profile");
		return -1;
	}

	gas = l->data;

	/* Clean-up any old client/db and acquire the new ones */
	gas->attr = NULL;
	gatt_db_unref(gas->db);
	bt_gatt_client_unref(gas->client);

	gas->db = gatt_db_ref(db);
	gas->client = bt_gatt_client_ref(client);

	/* Handle the GAP services */
	bt_uuid16_create(&gap_uuid, GAP_UUID16);
	gatt_db_foreach_service(db, &gap_uuid, foreach_gap_service, gas);

	if (!gas->attr) {
		error("GAP attribute not found");
		return -1;
	}

	btd_service_connecting_complete(service, 0);

	return 0;
}

static struct btd_profile gap_profile = {
	.name		= "gap-profile",
	.remote_uuid	= GAP_UUID,
	.device_probe	= gap_driver_probe,
	.device_remove	= gap_driver_remove,
	.accept		= gap_driver_accept
};

static int gap_init(void)
{
	devices = NULL;

	btd_profile_register(&gap_profile);

	return 0;
}

static void gap_exit(void)
{
	btd_profile_unregister(&gap_profile);
}

BLUETOOTH_PLUGIN_DEFINE(gap, VERSION, BLUETOOTH_PLUGIN_PRIORITY_DEFAULT,
							gap_init, gap_exit)
