/* Copyright (c) 2023 Nordic Semiconductor ASA
 * SPDX-License-Identifier: Apache-2.0
 */

#include <stdint.h>
#include <zephyr/bluetooth/gatt.h>
#include <zephyr/kernel.h>
#include <zephyr/sys/__assert.h>
#include <zephyr/logging/log.h>

#include <testlib/scan.h>

LOG_MODULE_REGISTER(bt_testlib_scan, LOG_LEVEL_INF);

struct bt_scan_find_name_closure {
	const char *wanted_name;
	bt_addr_le_t *result;
	struct k_condvar done;
};

/* Context pool (with capacity of one). */
static K_SEM_DEFINE(g_ctx_free, 1, 1);
static K_MUTEX_DEFINE(g_ctx_lock);
static struct bt_scan_find_name_closure *g_ctx;

static bool bt_scan_find_name_cb_data_cb(struct bt_data *data, void *user_data)
{
	const char **wanted = user_data;

	if (data->type == BT_DATA_NAME_COMPLETE) {
		if (data->data_len == strlen(*wanted) &&
		    !memcmp(*wanted, data->data, data->data_len)) {
			*wanted = NULL;
			/* Stop bt_data_parse. */
			return false;
		}
	}

	/* Continue with next ad data. */
	return true;
}

static void bt_scan_find_name_cb(const bt_addr_le_t *addr, int8_t rssi, uint8_t adv_type,
				 struct net_buf_simple *buf)
{
	const char *wanted;

	k_mutex_lock(&g_ctx_lock, K_FOREVER);

	__ASSERT_NO_MSG(g_ctx);
	__ASSERT_NO_MSG(g_ctx->wanted_name);

	wanted = g_ctx->wanted_name;

	bt_data_parse(buf, bt_scan_find_name_cb_data_cb, &wanted);

	if (!wanted) {
		(void)bt_le_scan_stop();
		*g_ctx->result = *addr;
		k_condvar_signal(&g_ctx->done);
	}

	k_mutex_unlock(&g_ctx_lock);
}

int bt_testlib_scan_find_name(bt_addr_le_t *result, const char *name)
{
	int api_err;
	struct bt_scan_find_name_closure ctx = {
		.wanted_name = name,
		.result = result,
	};

	k_condvar_init(&ctx.done);

	k_sem_take(&g_ctx_free, K_FOREVER);
	k_mutex_lock(&g_ctx_lock, K_FOREVER);
	g_ctx = &ctx;

	api_err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, bt_scan_find_name_cb);
	if (!api_err) {
		k_condvar_wait(&ctx.done, &g_ctx_lock, K_FOREVER);
	}

	g_ctx = NULL;
	k_mutex_unlock(&g_ctx_lock);
	k_sem_give(&g_ctx_free);

	if (!api_err) {
		char str[BT_ADDR_LE_STR_LEN];
		(void)bt_addr_le_to_str(result, str, ARRAY_SIZE(str));
		LOG_INF("Scan match: %s", str);
	} else {
		LOG_ERR("Scan error: %d", api_err);
	}

	return api_err;
}
