/*
 * Copyright (c) 2021 Xiaomi Corporation
 * Copyright (c) 2018 Nordic Semiconductor ASA
 * Copyright (c) 2017 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/kernel.h>
#include <zephyr/debug/stack.h>

#include <zephyr/net/buf.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/hci.h>
#include <zephyr/bluetooth/mesh.h>

#include "common/bt_str.h"

#include "host/hci_core.h"

#include "adv.h"
#include "net.h"
#include "proxy.h"

#define LOG_LEVEL CONFIG_BT_MESH_ADV_LOG_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(bt_mesh_adv_ext);

/* Convert from ms to 0.625ms units */
#define ADV_INT_FAST_MS    20

#ifndef CONFIG_BT_MESH_RELAY_ADV_SETS
#define CONFIG_BT_MESH_RELAY_ADV_SETS 0
#endif

enum {
	/** Controller is currently advertising */
	ADV_FLAG_ACTIVE,
	/** Advertising sending completed */
	ADV_FLAG_SENT,
	/** Currently performing proxy advertising */
	ADV_FLAG_PROXY,
	/** The send-call has been scheduled. */
	ADV_FLAG_SCHEDULED,
	/** The send-call has been pending. */
	ADV_FLAG_SCHEDULE_PENDING,
	/** Custom adv params have been set, we need to update the parameters on
	 *  the next send.
	 */
	ADV_FLAG_UPDATE_PARAMS,

	/* Number of adv flags. */
	ADV_FLAGS_NUM
};

struct bt_mesh_ext_adv {
	uint8_t tag;
	ATOMIC_DEFINE(flags, ADV_FLAGS_NUM);
	struct bt_le_ext_adv *instance;
	struct net_buf *buf;
	uint64_t timestamp;
	struct k_work_delayable work;
	struct bt_le_adv_param adv_param;
};

static void send_pending_adv(struct k_work *work);
static bool schedule_send(struct bt_mesh_ext_adv *adv);

static STRUCT_SECTION_ITERABLE(bt_mesh_ext_adv, adv_main) = {
	.tag = (
#if !defined(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE)
		BT_MESH_FRIEND_ADV |
#endif
#if !defined(CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE)
		BT_MESH_PROXY_ADV |
#endif /* !CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE */
#if defined(CONFIG_BT_MESH_ADV_EXT_RELAY_USING_MAIN_ADV_SET)
		BT_MESH_RELAY_ADV |
#endif /* CONFIG_BT_MESH_ADV_EXT_RELAY_USING_MAIN_ADV_SET */
		BT_MESH_LOCAL_ADV),

	.work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv),
};

#if CONFIG_BT_MESH_RELAY_ADV_SETS
static STRUCT_SECTION_ITERABLE(bt_mesh_ext_adv, adv_relay[CONFIG_BT_MESH_RELAY_ADV_SETS]) = {
	[0 ... CONFIG_BT_MESH_RELAY_ADV_SETS - 1] = {
		.tag = BT_MESH_RELAY_ADV,
		.work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv),
	}
};
#endif /* CONFIG_BT_MESH_RELAY_ADV_SETS */

#if defined(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE)
#define ADV_EXT_FRIEND 1
static STRUCT_SECTION_ITERABLE(bt_mesh_ext_adv, adv_friend) = {
	.tag = BT_MESH_FRIEND_ADV,
	.work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv),
};
#else /* CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE */
#define ADV_EXT_FRIEND 0
#endif /* CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE */

#if defined(CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE)
#define ADV_EXT_GATT 1
static STRUCT_SECTION_ITERABLE(bt_mesh_ext_adv, adv_gatt) = {
	.tag = BT_MESH_PROXY_ADV,
	.work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv),
};
#else /* CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE */
#define ADV_EXT_GATT 0
#endif /* CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE */

#define BT_MESH_ADV_COUNT (1 + CONFIG_BT_MESH_RELAY_ADV_SETS + ADV_EXT_FRIEND + ADV_EXT_GATT)

BUILD_ASSERT(CONFIG_BT_EXT_ADV_MAX_ADV_SET >= BT_MESH_ADV_COUNT,
	     "Insufficient adv instances");

static inline struct bt_mesh_ext_adv *relay_adv_get(void)
{
#if CONFIG_BT_MESH_RELAY_ADV_SETS
	return adv_relay;
#else /* !CONFIG_BT_MESH_RELAY_ADV_SETS */
	return &adv_main;
#endif /* CONFIG_BT_MESH_RELAY_ADV_SETS */
}

static inline struct bt_mesh_ext_adv *gatt_adv_get(void)
{
#if defined(CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE)
	return &adv_gatt;
#else /* !CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE */
	return &adv_main;
#endif /* CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE */
}

static int adv_start(struct bt_mesh_ext_adv *adv,
		     const struct bt_le_adv_param *param,
		     struct bt_le_ext_adv_start_param *start,
		     const struct bt_data *ad, size_t ad_len,
		     const struct bt_data *sd, size_t sd_len)
{
	int err;

	if (!adv->instance) {
		LOG_ERR("Mesh advertiser not enabled");
		return -ENODEV;
	}

	if (atomic_test_and_set_bit(adv->flags, ADV_FLAG_ACTIVE)) {
		LOG_ERR("Advertiser is busy");
		return -EBUSY;
	}

	if (atomic_test_bit(adv->flags, ADV_FLAG_UPDATE_PARAMS)) {
		err = bt_le_ext_adv_update_param(adv->instance, param);
		if (err) {
			LOG_ERR("Failed updating adv params: %d", err);
			atomic_clear_bit(adv->flags, ADV_FLAG_ACTIVE);
			return err;
		}

		atomic_set_bit_to(adv->flags, ADV_FLAG_UPDATE_PARAMS,
				  param != &adv->adv_param);
	}

	err = bt_le_ext_adv_set_data(adv->instance, ad, ad_len, sd, sd_len);
	if (err) {
		LOG_ERR("Failed setting adv data: %d", err);
		atomic_clear_bit(adv->flags, ADV_FLAG_ACTIVE);
		return err;
	}

	adv->timestamp = k_uptime_get();

	err = bt_le_ext_adv_start(adv->instance, start);
	if (err) {
		LOG_ERR("Advertising failed: err %d", err);
		atomic_clear_bit(adv->flags, ADV_FLAG_ACTIVE);
	}

	return err;
}

static int buf_send(struct bt_mesh_ext_adv *adv, struct net_buf *buf)
{
	struct bt_le_ext_adv_start_param start = {
		.num_events =
			BT_MESH_TRANSMIT_COUNT(BT_MESH_ADV(buf)->xmit) + 1,
	};
	uint16_t duration, adv_int;
	struct bt_data ad;
	int err;

	adv_int = MAX(ADV_INT_FAST_MS,
		      BT_MESH_TRANSMIT_INT(BT_MESH_ADV(buf)->xmit));
	/* Upper boundary estimate: */
	duration = start.num_events * (adv_int + 10);

	LOG_DBG("type %u len %u: %s", BT_MESH_ADV(buf)->type, buf->len,
		bt_hex(buf->data, buf->len));
	LOG_DBG("count %u interval %ums duration %ums",
		BT_MESH_TRANSMIT_COUNT(BT_MESH_ADV(buf)->xmit) + 1, adv_int, duration);

	ad.type = bt_mesh_adv_type[BT_MESH_ADV(buf)->type];
	ad.data_len = buf->len;
	ad.data = buf->data;

	/* Only update advertising parameters if they're different */
	if (adv->adv_param.interval_min != BT_MESH_ADV_SCAN_UNIT(adv_int)) {
		adv->adv_param.interval_min = BT_MESH_ADV_SCAN_UNIT(adv_int);
		adv->adv_param.interval_max = adv->adv_param.interval_min;
		atomic_set_bit(adv->flags, ADV_FLAG_UPDATE_PARAMS);
	}

	err = adv_start(adv, &adv->adv_param, &start, &ad, 1, NULL, 0);
	if (!err) {
		adv->buf = net_buf_ref(buf);
	}

	bt_mesh_adv_send_start(duration, err, BT_MESH_ADV(buf));

	return err;
}

static const char *adv_tag_to_str(enum bt_mesh_adv_tag tag)
{
	if (tag & BT_MESH_LOCAL_ADV) {
		return "local adv";
	} else if (tag & BT_MESH_PROXY_ADV) {
		return "proxy adv";
	} else if (tag & BT_MESH_RELAY_ADV) {
		return "relay adv";
	} else if (tag & BT_MESH_FRIEND_ADV) {
		return "friend adv";
	} else {
		return "(unknown tag)";
	}
}

static void send_pending_adv(struct k_work *work)
{
	struct bt_mesh_ext_adv *adv;
	struct net_buf *buf;
	int err;

	adv = CONTAINER_OF(work, struct bt_mesh_ext_adv, work.work);

	if (atomic_test_and_clear_bit(adv->flags, ADV_FLAG_SENT)) {
		/* Calling k_uptime_delta on a timestamp moves it to the current time.
		 * This is essential here, as schedule_send() uses the end of the event
		 * as a reference to avoid sending the next advertisement too soon.
		 */
		int64_t duration = k_uptime_delta(&adv->timestamp);

		LOG_DBG("Advertising stopped after %u ms for (%u) %s", (uint32_t)duration, adv->tag,
		       adv_tag_to_str(adv->tag));

		atomic_clear_bit(adv->flags, ADV_FLAG_ACTIVE);
		atomic_clear_bit(adv->flags, ADV_FLAG_PROXY);

		if (adv->buf) {
			net_buf_unref(adv->buf);
			adv->buf = NULL;
		}

		(void)schedule_send(adv);

		return;
	}

	atomic_clear_bit(adv->flags, ADV_FLAG_SCHEDULED);

	while ((buf = bt_mesh_adv_buf_get_by_tag(adv->tag, K_NO_WAIT))) {
		/* busy == 0 means this was canceled */
		if (!BT_MESH_ADV(buf)->busy) {
			net_buf_unref(buf);
			continue;
		}

		BT_MESH_ADV(buf)->busy = 0U;
		err = buf_send(adv, buf);

		net_buf_unref(buf);

		if (!err) {
			return; /* Wait for advertising to finish */
		}
	}

	if (!IS_ENABLED(CONFIG_BT_MESH_GATT_SERVER) ||
	    !(adv->tag & BT_MESH_PROXY_ADV)) {
		return;
	}

	if (!bt_mesh_adv_gatt_send()) {
		atomic_set_bit(adv->flags, ADV_FLAG_PROXY);
	}

	if (atomic_test_and_clear_bit(adv->flags, ADV_FLAG_SCHEDULE_PENDING)) {
		schedule_send(adv);
	}

}

static bool schedule_send(struct bt_mesh_ext_adv *adv)
{
	uint64_t timestamp;
	int64_t delta;

	timestamp = adv->timestamp;

	if (atomic_test_and_clear_bit(adv->flags, ADV_FLAG_PROXY)) {
		(void)bt_le_ext_adv_stop(adv->instance);
		atomic_clear_bit(adv->flags, ADV_FLAG_ACTIVE);
	}

	if (atomic_test_bit(adv->flags, ADV_FLAG_ACTIVE)) {
		atomic_set_bit(adv->flags, ADV_FLAG_SCHEDULE_PENDING);
		return false;
	} else if (atomic_test_and_set_bit(adv->flags, ADV_FLAG_SCHEDULED)) {
		return false;
	}

	atomic_clear_bit(adv->flags, ADV_FLAG_SCHEDULE_PENDING);

	if (IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) && adv->tag & BT_MESH_FRIEND_ADV) {
		k_work_reschedule(&adv->work, K_NO_WAIT);
	} else {
		/* The controller will send the next advertisement immediately.
		 * Introduce a delay here to avoid sending the next mesh packet closer
		 * to the previous packet than what's permitted by the specification.
		 */
		delta = k_uptime_delta(&timestamp);
		k_work_reschedule(&adv->work, K_MSEC(ADV_INT_FAST_MS - delta));
	}

	return true;
}

void bt_mesh_adv_gatt_update(void)
{
	(void)schedule_send(gatt_adv_get());
}

void bt_mesh_adv_buf_local_ready(void)
{
	(void)schedule_send(&adv_main);
}

void bt_mesh_adv_buf_relay_ready(void)
{
	struct bt_mesh_ext_adv *adv = relay_adv_get();

	for (int i = 0; i < CONFIG_BT_MESH_RELAY_ADV_SETS; i++) {
		if (schedule_send(&adv[i])) {
			return;
		}
	}

	/* Attempt to use the main adv set for the sending of relay messages. */
	if (IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_RELAY_USING_MAIN_ADV_SET)) {
		(void)schedule_send(&adv_main);
	}
}

void bt_mesh_adv_buf_friend_ready(void)
{
#if defined(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE)
	(void)schedule_send(&adv_friend);
#endif
}

void bt_mesh_adv_init(void)
{
	struct bt_le_adv_param adv_param = {
		.id = BT_ID_DEFAULT,
		.interval_min = BT_MESH_ADV_SCAN_UNIT(ADV_INT_FAST_MS),
		.interval_max = BT_MESH_ADV_SCAN_UNIT(ADV_INT_FAST_MS),
#if defined(CONFIG_BT_MESH_DEBUG_USE_ID_ADDR)
		.options = BT_LE_ADV_OPT_USE_IDENTITY,
#endif
};
	STRUCT_SECTION_FOREACH(bt_mesh_ext_adv, adv) {
		(void)memcpy(&adv->adv_param, &adv_param, sizeof(adv_param));
	}
}

static struct bt_mesh_ext_adv *adv_instance_find(struct bt_le_ext_adv *instance)
{
	STRUCT_SECTION_FOREACH(bt_mesh_ext_adv, adv) {
		if (adv->instance == instance) {
			return adv;
		}
	}

	return NULL;
}

static void adv_sent(struct bt_le_ext_adv *instance,
		     struct bt_le_ext_adv_sent_info *info)
{
	struct bt_mesh_ext_adv *adv = adv_instance_find(instance);

	if (!adv) {
		LOG_WRN("Unexpected adv instance");
		return;
	}

	if (!atomic_test_bit(adv->flags, ADV_FLAG_ACTIVE)) {
		return;
	}

	atomic_set_bit(adv->flags, ADV_FLAG_SENT);

	k_work_submit(&adv->work.work);
}

#if defined(CONFIG_BT_MESH_GATT_SERVER)
static void connected(struct bt_le_ext_adv *instance,
		      struct bt_le_ext_adv_connected_info *info)
{
	struct bt_mesh_ext_adv *adv = gatt_adv_get();

	if (atomic_test_and_clear_bit(adv->flags, ADV_FLAG_PROXY)) {
		atomic_clear_bit(adv->flags, ADV_FLAG_ACTIVE);
		(void)schedule_send(adv);
	}
}
#endif /* CONFIG_BT_MESH_GATT_SERVER */

int bt_mesh_adv_enable(void)
{
	int err;

	static const struct bt_le_ext_adv_cb adv_cb = {
		.sent = adv_sent,
#if defined(CONFIG_BT_MESH_GATT_SERVER)
		.connected = connected,
#endif /* CONFIG_BT_MESH_GATT_SERVER */
	};

	if (adv_main.instance) {
		/* Already initialized */
		return 0;
	}


	STRUCT_SECTION_FOREACH(bt_mesh_ext_adv, adv) {
		err = bt_le_ext_adv_create(&adv->adv_param, &adv_cb,
					   &adv->instance);
		if (err) {
			return err;
		}
	}

	return 0;
}

int bt_mesh_adv_gatt_start(const struct bt_le_adv_param *param,
			   int32_t duration,
			   const struct bt_data *ad, size_t ad_len,
			   const struct bt_data *sd, size_t sd_len)
{
	struct bt_mesh_ext_adv *adv = gatt_adv_get();
	struct bt_le_ext_adv_start_param start = {
		/* Timeout is set in 10 ms steps, with 0 indicating "forever" */
		.timeout = (duration == SYS_FOREVER_MS) ? 0 : MAX(1, duration / 10),
	};

	LOG_DBG("Start advertising %d ms", duration);

	atomic_set_bit(adv->flags, ADV_FLAG_UPDATE_PARAMS);

	return adv_start(adv, param, &start, ad, ad_len, sd, sd_len);
}
