/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2015  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.
 *
 */

#include "advertising.h"

#include <stdint.h>
#include <stdbool.h>

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

#include "lib/bluetooth.h"
#include "lib/mgmt.h"
#include "lib/sdp.h"

#include "adapter.h"
#include "dbus-common.h"
#include "error.h"
#include "log.h"
#include "src/shared/ad.h"
#include "src/shared/mgmt.h"
#include "src/shared/queue.h"
#include "src/shared/util.h"

#define LE_ADVERTISING_MGR_IFACE "org.bluez.LEAdvertisingManager1"
#define LE_ADVERTISEMENT_IFACE "org.bluez.LEAdvertisement1"

struct btd_advertising {
	struct btd_adapter *adapter;
	struct queue *ads;
	struct mgmt *mgmt;
	uint16_t mgmt_index;
	uint8_t max_adv_len;
	uint8_t max_ads;
	unsigned int instance_bitmap;
};

#define AD_TYPE_BROADCAST 0
#define AD_TYPE_PERIPHERAL 1

struct advertisement {
	struct btd_advertising *manager;
	char *owner;
	char *path;
	GDBusClient *client;
	GDBusProxy *proxy;
	DBusMessage *reg;
	uint8_t type; /* Advertising type */
	bool include_tx_power;
	struct bt_ad *data;
	uint8_t instance;
};

struct dbus_obj_match {
	const char *owner;
	const char *path;
};

static bool match_advertisement(const void *a, const void *b)
{
	const struct advertisement *ad = a;
	const struct dbus_obj_match *match = b;

	if (match->owner && !g_strcmp0(ad->owner, match->owner))
		return false;

	if (match->path && !g_strcmp0(ad->path, match->path))
		return false;

	return true;
}

static void advertisement_free(void *data)
{
	struct advertisement *ad = data;

	if (ad->client) {
		g_dbus_client_set_disconnect_watch(ad->client, NULL, NULL);
		g_dbus_client_unref(ad->client);
	}

	bt_ad_unref(ad->data);

	g_dbus_proxy_unref(ad->proxy);

	if (ad->owner)
		g_free(ad->owner);

	if (ad->path)
		g_free(ad->path);

	free(ad);
}

static gboolean advertisement_free_idle_cb(void *data)
{
	advertisement_free(data);

	return FALSE;
}

static void advertisement_release(void *data)
{
	struct advertisement *ad = data;
	DBusMessage *message;

	DBG("Releasing advertisement %s, %s", ad->owner, ad->path);

	message = dbus_message_new_method_call(ad->owner, ad->path,
							LE_ADVERTISEMENT_IFACE,
							"Release");

	if (!message) {
		error("Couldn't allocate D-Bus message");
		return;
	}

	g_dbus_send_message(btd_get_dbus_connection(), message);
}

static void advertisement_destroy(void *data)
{
	advertisement_release(data);
	advertisement_free(data);
}

static void advertisement_remove(void *data)
{
	struct advertisement *ad = data;
	struct mgmt_cp_remove_advertising cp;

	g_dbus_client_set_disconnect_watch(ad->client, NULL, NULL);

	cp.instance = ad->instance;

	mgmt_send(ad->manager->mgmt, MGMT_OP_REMOVE_ADVERTISING,
			ad->manager->mgmt_index, sizeof(cp), &cp, NULL, NULL,
			NULL);

	queue_remove(ad->manager->ads, ad);

	util_clear_uid(&ad->manager->instance_bitmap, ad->instance);

	g_idle_add(advertisement_free_idle_cb, ad);
}

static void client_disconnect_cb(DBusConnection *conn, void *user_data)
{
	DBG("Client disconnected");

	advertisement_remove(user_data);
}

static bool parse_advertising_type(GDBusProxy *proxy, uint8_t *type)
{
	DBusMessageIter iter;
	const char *msg_type;

	if (!g_dbus_proxy_get_property(proxy, "Type", &iter))
		return false;

	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
		return false;

	dbus_message_iter_get_basic(&iter, &msg_type);

	if (!g_strcmp0(msg_type, "broadcast")) {
		*type = AD_TYPE_BROADCAST;
		return true;
	}

	if (!g_strcmp0(msg_type, "peripheral")) {
		*type = AD_TYPE_PERIPHERAL;
		return true;
	}

	return false;
}

static bool parse_advertising_service_uuids(GDBusProxy *proxy,
					struct bt_ad *data)
{
	DBusMessageIter iter, ariter;

	if (!g_dbus_proxy_get_property(proxy, "ServiceUUIDs", &iter))
		return true;

	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY)
		return false;

	dbus_message_iter_recurse(&iter, &ariter);

	bt_ad_clear_service_uuid(data);

	while (dbus_message_iter_get_arg_type(&ariter) == DBUS_TYPE_STRING) {
		const char *uuid_str;
		bt_uuid_t uuid;

		dbus_message_iter_get_basic(&ariter, &uuid_str);

		DBG("Adding ServiceUUID: %s", uuid_str);

		if (bt_string_to_uuid(&uuid, uuid_str) < 0)
			goto fail;

		if (!bt_ad_add_service_uuid(data, &uuid))
			goto fail;

		dbus_message_iter_next(&ariter);
	}

	return true;

fail:
	bt_ad_clear_service_uuid(data);
	return false;
}

static bool parse_advertising_solicit_uuids(GDBusProxy *proxy,
							struct bt_ad *data)
{
	DBusMessageIter iter, ariter;

	if (!g_dbus_proxy_get_property(proxy, "SolicitUUIDs", &iter))
		return true;

	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY)
		return false;

	dbus_message_iter_recurse(&iter, &ariter);

	bt_ad_clear_solicit_uuid(data);

	while (dbus_message_iter_get_arg_type(&ariter) == DBUS_TYPE_STRING) {
		const char *uuid_str;
		bt_uuid_t uuid;

		dbus_message_iter_get_basic(&ariter, &uuid_str);

		DBG("Adding SolicitUUID: %s", uuid_str);

		if (bt_string_to_uuid(&uuid, uuid_str) < 0)
			goto fail;

		if (!bt_ad_add_solicit_uuid(data, &uuid))
			goto fail;

		dbus_message_iter_next(&ariter);
	}

	return true;

fail:
	bt_ad_clear_solicit_uuid(data);
	return false;
}

static bool parse_advertising_manufacturer_data(GDBusProxy *proxy,
							struct bt_ad *data)
{
	DBusMessageIter iter, entries;

	if (!g_dbus_proxy_get_property(proxy, "ManufacturerData", &iter))
		return true;

	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY)
		return false;

	dbus_message_iter_recurse(&iter, &entries);

	bt_ad_clear_manufacturer_data(data);

	while (dbus_message_iter_get_arg_type(&entries)
						== DBUS_TYPE_DICT_ENTRY) {
		DBusMessageIter value, entry;
		uint16_t manuf_id;
		uint8_t *manuf_data;
		int len;

		dbus_message_iter_recurse(&entries, &entry);
		dbus_message_iter_get_basic(&entry, &manuf_id);

		dbus_message_iter_next(&entry);
		if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_ARRAY)
			goto fail;

		dbus_message_iter_recurse(&entry, &value);

		if (dbus_message_iter_get_arg_type(&value) != DBUS_TYPE_BYTE)
			goto fail;

		dbus_message_iter_get_fixed_array(&value, &manuf_data, &len);

		DBG("Adding ManufacturerData for %04x", manuf_id);

		if (!bt_ad_add_manufacturer_data(data, manuf_id, manuf_data,
									len))
			goto fail;

		dbus_message_iter_next(&entries);
	}

	return true;

fail:
	bt_ad_clear_manufacturer_data(data);
	return false;
}

static bool parse_advertising_service_data(GDBusProxy *proxy,
							struct bt_ad *data)
{
	DBusMessageIter iter, entries;

	if (!g_dbus_proxy_get_property(proxy, "ServiceData", &iter))
		return true;

	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY)
		return false;

	dbus_message_iter_recurse(&iter, &entries);

	bt_ad_clear_service_data(data);

	while (dbus_message_iter_get_arg_type(&entries)
						== DBUS_TYPE_DICT_ENTRY) {
		DBusMessageIter value, entry;
		const char *uuid_str;
		bt_uuid_t uuid;
		uint8_t *service_data;
		int len;

		dbus_message_iter_recurse(&entries, &entry);
		dbus_message_iter_get_basic(&entry, &uuid_str);

		if (bt_string_to_uuid(&uuid, uuid_str) < 0)
			goto fail;

		dbus_message_iter_next(&entry);
		if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_ARRAY)
			goto fail;

		dbus_message_iter_recurse(&entry, &value);

		if (dbus_message_iter_get_arg_type(&value) != DBUS_TYPE_BYTE)
			goto fail;

		dbus_message_iter_get_fixed_array(&value, &service_data, &len);

		DBG("Adding ServiceData for %s", uuid_str);

		if (!bt_ad_add_service_data(data, &uuid, service_data, len))
			goto fail;

		dbus_message_iter_next(&entries);
	}

	return true;

fail:
	bt_ad_clear_service_data(data);
	return false;
}

static bool parse_advertising_include_tx_power(GDBusProxy *proxy,
							bool *included)
{
	DBusMessageIter iter;
	dbus_bool_t b;

	if (!g_dbus_proxy_get_property(proxy, "IncludeTxPower", &iter))
		return true;

	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_BOOLEAN)
		return false;

	dbus_message_iter_get_basic(&iter, &b);

	*included = b;

	return true;
}

static void add_adverting_complete(struct advertisement *ad, uint8_t status)
{
	DBusMessage *reply;

	if (status) {
		error("Failed to add advertisement: %s (0x%02x)",
						mgmt_errstr(status), status);
		reply = btd_error_failed(ad->reg,
					"Failed to register advertisement");
		queue_remove(ad->manager->ads, ad);
		g_idle_add(advertisement_free_idle_cb, ad);

	} else
		reply = dbus_message_new_method_return(ad->reg);

	g_dbus_send_message(btd_get_dbus_connection(), reply);
	dbus_message_unref(ad->reg);
	ad->reg = NULL;
}

static void add_advertising_callback(uint8_t status, uint16_t length,
					  const void *param, void *user_data)
{
	struct advertisement *ad = user_data;
	const struct mgmt_rp_add_advertising *rp = param;

	if (status)
		goto done;

	if (!param || length < sizeof(*rp)) {
		status = MGMT_STATUS_FAILED;
		goto done;
	}

	ad->instance = rp->instance;

	g_dbus_client_set_disconnect_watch(ad->client, client_disconnect_cb,
									ad);
	DBG("Advertisement registered: %s", ad->path);

done:
	add_adverting_complete(ad, status);
}

static size_t calc_max_adv_len(struct advertisement *ad, uint32_t flags)
{
	size_t max = ad->manager->max_adv_len;

	/*
	 * Flags which reduce the amount of space available for advertising.
	 * See doc/mgmt-api.txt
	 */
	if (flags & MGMT_ADV_FLAG_TX_POWER)
		max -= 3;

	if (flags & (MGMT_ADV_FLAG_DISCOV | MGMT_ADV_FLAG_LIMITED_DISCOV |
						MGMT_ADV_FLAG_MANAGED_FLAGS))
		max -= 3;

	if (flags & MGMT_ADV_FLAG_APPEARANCE)
		max -= 4;

	return max;
}

static DBusMessage *refresh_advertisement(struct advertisement *ad)
{
	struct mgmt_cp_add_advertising *cp;
	uint8_t param_len;
	uint8_t *adv_data;
	size_t adv_data_len;
	uint32_t flags = 0;

	DBG("Refreshing advertisement: %s", ad->path);

	if (ad->type == AD_TYPE_PERIPHERAL)
		flags = MGMT_ADV_FLAG_CONNECTABLE | MGMT_ADV_FLAG_DISCOV;

	if (ad->include_tx_power)
		flags |= MGMT_ADV_FLAG_TX_POWER;

	adv_data = bt_ad_generate(ad->data, &adv_data_len);

	if (!adv_data || (adv_data_len > calc_max_adv_len(ad, flags))) {
		error("Advertising data too long or couldn't be generated.");

		return g_dbus_create_error(ad->reg, ERROR_INTERFACE
						".InvalidLength",
						"Advertising data too long.");
	}

	param_len = sizeof(struct mgmt_cp_add_advertising) + adv_data_len;

	cp = malloc0(param_len);

	if (!cp) {
		error("Couldn't allocate for MGMT!");

		free(adv_data);

		return btd_error_failed(ad->reg, "Failed");
	}

	cp->flags = flags;
	cp->instance = ad->instance;
	cp->adv_data_len = adv_data_len;
	memcpy(cp->data, adv_data, adv_data_len);

	free(adv_data);

	if (!mgmt_send(ad->manager->mgmt, MGMT_OP_ADD_ADVERTISING,
					ad->manager->mgmt_index, param_len, cp,
					add_advertising_callback, ad, NULL)) {
		error("Failed to add Advertising Data");

		free(cp);

		return btd_error_failed(ad->reg, "Failed");
	}

	free(cp);

	return NULL;
}

static DBusMessage *parse_advertisement(struct advertisement *ad)
{
	if (!parse_advertising_type(ad->proxy, &ad->type)) {
		error("Failed to read \"Type\" property of advertisement");
		goto fail;
	}

	if (!parse_advertising_service_uuids(ad->proxy, ad->data)) {
		error("Property \"ServiceUUIDs\" failed to parse");
		goto fail;
	}

	if (!parse_advertising_solicit_uuids(ad->proxy, ad->data)) {
		error("Property \"SolicitUUIDs\" failed to parse");
		goto fail;
	}

	if (!parse_advertising_manufacturer_data(ad->proxy, ad->data)) {
		error("Property \"ManufacturerData\" failed to parse");
		goto fail;
	}

	if (!parse_advertising_service_data(ad->proxy, ad->data)) {
		error("Property \"ServiceData\" failed to parse");
		goto fail;
	}

	if (!parse_advertising_include_tx_power(ad->proxy,
						&ad->include_tx_power)) {
		error("Property \"IncludeTxPower\" failed to parse");
		goto fail;
	}

	return refresh_advertisement(ad);

fail:
	return btd_error_failed(ad->reg, "Failed to parse advertisement.");
}

static void advertisement_proxy_added(GDBusProxy *proxy, void *data)
{
	struct advertisement *ad = data;
	DBusMessage *reply;

	reply = parse_advertisement(ad);
	if (!reply)
		return;

	/* Failed to publish for some reason, remove. */
	queue_remove(ad->manager->ads, ad);

	g_idle_add(advertisement_free_idle_cb, ad);

	g_dbus_send_message(btd_get_dbus_connection(), reply);

	dbus_message_unref(ad->reg);
	ad->reg = NULL;
}

static struct advertisement *advertisement_create(DBusConnection *conn,
					DBusMessage *msg, const char *path)
{
	struct advertisement *ad;
	const char *sender = dbus_message_get_sender(msg);

	if (!path || !g_str_has_prefix(path, "/"))
		return NULL;

	ad = new0(struct advertisement, 1);
	if (!ad)
		return NULL;

	ad->client = g_dbus_client_new_full(conn, sender, path, path);
	if (!ad->client)
		goto fail;

	ad->owner = g_strdup(sender);
	if (!ad->owner)
		goto fail;

	ad->path = g_strdup(path);
	if (!ad->path)
		goto fail;

	DBG("Adding proxy for %s", path);
	ad->proxy = g_dbus_proxy_new(ad->client, path, LE_ADVERTISEMENT_IFACE);
	if (!ad->proxy)
		goto fail;

	g_dbus_client_set_proxy_handlers(ad->client, advertisement_proxy_added,
								NULL, NULL, ad);

	ad->reg = dbus_message_ref(msg);

	ad->data = bt_ad_new();
	if (!ad->data)
		goto fail;

	return ad;

fail:
	advertisement_free(ad);
	return NULL;
}

static DBusMessage *register_advertisement(DBusConnection *conn,
						DBusMessage *msg,
						void *user_data)
{
	struct btd_advertising *manager = user_data;
	DBusMessageIter args;
	struct advertisement *ad;
	struct dbus_obj_match match;
	uint8_t instance;

	DBG("RegisterAdvertisement");

	if (!dbus_message_iter_init(msg, &args))
		return btd_error_invalid_args(msg);

	if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_OBJECT_PATH)
		return btd_error_invalid_args(msg);

	dbus_message_iter_get_basic(&args, &match.path);

	match.owner = dbus_message_get_sender(msg);

	if (queue_find(manager->ads, match_advertisement, &match))
		return btd_error_already_exists(msg);

	instance = util_get_uid(&manager->instance_bitmap, manager->max_ads);
	if (!instance)
		return btd_error_failed(msg, "Maximum advertisements reached");

	dbus_message_iter_next(&args);

	if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_ARRAY)
		return btd_error_invalid_args(msg);

	ad = advertisement_create(conn, msg, match.path);
	if (!ad)
		return btd_error_failed(msg,
					"Failed to register advertisement");

	DBG("Registered advertisement at path %s", match.path);

	ad->instance = instance;
	ad->manager = manager;

	queue_push_tail(manager->ads, ad);

	return NULL;
}

static DBusMessage *unregister_advertisement(DBusConnection *conn,
						DBusMessage *msg,
						void *user_data)
{
	struct btd_advertising *manager = user_data;
	DBusMessageIter args;
	struct advertisement *ad;
	struct dbus_obj_match match;

	DBG("UnregisterAdvertisement");

	if (!dbus_message_iter_init(msg, &args))
		return btd_error_invalid_args(msg);

	if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_OBJECT_PATH)
		return btd_error_invalid_args(msg);

	dbus_message_iter_get_basic(&args, &match.path);

	match.owner = dbus_message_get_sender(msg);

	ad = queue_find(manager->ads, match_advertisement, &match);
	if (!ad)
		return btd_error_does_not_exist(msg);

	advertisement_remove(ad);

	return dbus_message_new_method_return(msg);
}

static const GDBusMethodTable methods[] = {
	{ GDBUS_EXPERIMENTAL_ASYNC_METHOD("RegisterAdvertisement",
					GDBUS_ARGS({ "advertisement", "o" },
							{ "options", "a{sv}" }),
					NULL, register_advertisement) },
	{ GDBUS_EXPERIMENTAL_ASYNC_METHOD("UnregisterAdvertisement",
						GDBUS_ARGS({ "service", "o" }),
						NULL,
						unregister_advertisement) },
	{ }
};

static void advertising_manager_destroy(void *user_data)
{
	struct btd_advertising *manager = user_data;

	queue_destroy(manager->ads, advertisement_destroy);

	mgmt_unref(manager->mgmt);

	free(manager);
}

static void read_adv_features_callback(uint8_t status, uint16_t length,
					const void *param, void *user_data)
{
	struct btd_advertising *manager = user_data;
	const struct mgmt_rp_read_adv_features *feat = param;

	if (status || !param) {
		error("Failed to read advertising features: %s (0x%02x)",
						mgmt_errstr(status), status);
		return;
	}

	if (length < sizeof(*feat)) {
		error("Wrong size of read adv features response");
		return;
	}

	manager->max_adv_len = feat->max_adv_data_len;
	manager->max_ads = feat->max_instances;

	if (manager->max_ads == 0)
		return;

	if (!g_dbus_register_interface(btd_get_dbus_connection(),
					adapter_get_path(manager->adapter),
					LE_ADVERTISING_MGR_IFACE,
					methods, NULL, NULL, manager, NULL))
		error("Failed to register " LE_ADVERTISING_MGR_IFACE);
}

static struct btd_advertising *
advertising_manager_create(struct btd_adapter *adapter)
{
	struct btd_advertising *manager;

	manager = new0(struct btd_advertising, 1);
	if (!manager)
		return NULL;

	manager->adapter = adapter;

	manager->mgmt = mgmt_new_default();

	if (!manager->mgmt) {
		error("Failed to access management interface");
		free(manager);
		return NULL;
	}

	manager->mgmt_index = btd_adapter_get_index(adapter);

	if (!mgmt_send(manager->mgmt, MGMT_OP_READ_ADV_FEATURES,
				manager->mgmt_index, 0, NULL,
				read_adv_features_callback, manager, NULL)) {
		error("Failed to read advertising features");
		advertising_manager_destroy(manager);
		return NULL;
	}

	manager->ads = queue_new();

	return manager;
}

struct btd_advertising *
btd_advertising_manager_new(struct btd_adapter *adapter)
{
	struct btd_advertising *manager;

	if (!adapter)
		return NULL;

	manager = advertising_manager_create(adapter);
	if (!manager)
		return NULL;

	DBG("LE Advertising Manager created for adapter: %s",
						adapter_get_path(adapter));

	return manager;
}

void btd_advertising_manager_destroy(struct btd_advertising *manager)
{
	if (!manager)
		return;

	g_dbus_unregister_interface(btd_get_dbus_connection(),
					adapter_get_path(manager->adapter),
					LE_ADVERTISING_MGR_IFACE);

	advertising_manager_destroy(manager);
}
