/*
 * Copyright (c) 2021 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#include "mesh_test.h"

#define LOG_MODULE_NAME mesh_test

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(LOG_MODULE_NAME);

/* Max number of messages that can be pending on RX at the same time */
#define RECV_QUEUE_SIZE 32

const struct bt_mesh_test_cfg *cfg;

K_MEM_SLAB_DEFINE_STATIC(msg_pool, sizeof(struct bt_mesh_test_msg),
			 RECV_QUEUE_SIZE, 4);
static K_QUEUE_DEFINE(recv);
struct bt_mesh_test_stats test_stats;
struct bt_mesh_msg_ctx test_send_ctx;
static void (*ra_cb)(uint8_t *, size_t);

static int msg_rx(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx,
		   struct net_buf_simple *buf)
{
	size_t len = buf->len + BT_MESH_MODEL_OP_LEN(TEST_MSG_OP_1);
	static uint8_t prev_seq;
	struct bt_mesh_test_msg *msg;
	uint8_t seq = 0;

	if (buf->len) {
		seq = net_buf_simple_pull_u8(buf);
		if (prev_seq == seq) {
			FAIL("Received same message twice");
			return -EINVAL;
		}

		prev_seq = seq;
	}

	LOG_INF("Received packet 0x%02x:", seq);
	LOG_INF("\tlen: %d bytes", len);
	LOG_INF("\tsrc: 0x%04x", ctx->addr);
	LOG_INF("\tdst: 0x%04x", ctx->recv_dst);
	LOG_INF("\tttl: %u", ctx->recv_ttl);
	LOG_INF("\trssi: %d", ctx->recv_rssi);

	for (int i = 1; buf->len; i++) {
		if (net_buf_simple_pull_u8(buf) != (i & 0xff)) {
			FAIL("Invalid message content (byte %u)", i);
			return -EINVAL;
		}
	}

	test_stats.received++;

	if (k_mem_slab_alloc(&msg_pool, (void **)&msg, K_NO_WAIT)) {
		test_stats.recv_overflow++;
		return -EOVERFLOW;
	}

	msg->len = len;
	msg->seq = seq;
	msg->ctx = *ctx;

	k_queue_append(&recv, msg);

	return 0;
}

static int ra_rx(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx,
		 struct net_buf_simple *buf)
{
	LOG_INF("\tlen: %d bytes", buf->len);
	LOG_INF("\tsrc: 0x%04x", ctx->addr);
	LOG_INF("\tdst: 0x%04x", ctx->recv_dst);
	LOG_INF("\tttl: %u", ctx->recv_ttl);
	LOG_INF("\trssi: %d", ctx->recv_rssi);

	if (ra_cb) {
		ra_cb(net_buf_simple_pull_mem(buf, buf->len), buf->len);
	}

	return 0;
}

static const struct bt_mesh_model_op model_op[] = {
	{ TEST_MSG_OP_1, 0, msg_rx },
	{ TEST_MSG_OP_2, 0, ra_rx },
	BT_MESH_MODEL_OP_END
};

int __weak test_model_pub_update(struct bt_mesh_model *mod)
{
	return -1;
}

int __weak test_model_settings_set(struct bt_mesh_model *model,
				   const char *name, size_t len_rd,
				   settings_read_cb read_cb, void *cb_arg)
{
	return -1;
}

void __weak test_model_reset(struct bt_mesh_model *model)
{
	/* No-op. */
}

static const struct bt_mesh_model_cb test_model_cb = {
	.settings_set = test_model_settings_set,
	.reset = test_model_reset,
};

static struct bt_mesh_model_pub pub = {
	.msg = NET_BUF_SIMPLE(BT_MESH_TX_SDU_MAX),
	.update = test_model_pub_update,
};

static const struct bt_mesh_model_op vnd_model_op[] = {
	BT_MESH_MODEL_OP_END,
};

int __weak test_vnd_model_pub_update(struct bt_mesh_model *mod)
{
	return -1;
}

int __weak test_vnd_model_settings_set(struct bt_mesh_model *model,
				       const char *name, size_t len_rd,
				       settings_read_cb read_cb, void *cb_arg)
{
	return -1;
}

void __weak test_vnd_model_reset(struct bt_mesh_model *model)
{
	/* No-op. */
}

static const struct bt_mesh_model_cb test_vnd_model_cb = {
	.settings_set = test_vnd_model_settings_set,
	.reset = test_vnd_model_reset,
};

static struct bt_mesh_model_pub vnd_pub = {
	.msg = NET_BUF_SIMPLE(BT_MESH_TX_SDU_MAX),
	.update = test_vnd_model_pub_update,
};

static struct bt_mesh_cfg_cli cfg_cli;

static struct bt_mesh_health_srv health_srv;
static struct bt_mesh_model_pub health_pub = {
	.msg = NET_BUF_SIMPLE(BT_MESH_TX_SDU_MAX),
};

static struct bt_mesh_model models[] = {
	BT_MESH_MODEL_CFG_SRV,
	BT_MESH_MODEL_CFG_CLI(&cfg_cli),
	BT_MESH_MODEL_CB(TEST_MOD_ID, model_op, &pub, NULL, &test_model_cb),
	BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub),
};

struct bt_mesh_model *test_model = &models[2];

static struct bt_mesh_model vnd_models[] = {
	BT_MESH_MODEL_VND_CB(TEST_VND_COMPANY_ID, TEST_VND_MOD_ID, vnd_model_op, &vnd_pub,
			     NULL, &test_vnd_model_cb),
};

struct bt_mesh_model *test_vnd_model = &vnd_models[0];

static struct bt_mesh_elem elems[] = {
	BT_MESH_ELEM(0, models, vnd_models),
};

const struct bt_mesh_comp comp = {
	.elem = elems,
	.elem_count = ARRAY_SIZE(elems),
};

const uint8_t test_net_key[16] = { 1, 2, 3 };
const uint8_t test_app_key[16] = { 4, 5, 6 };
const uint8_t test_va_uuid[16] = "Mesh Label UUID";

static void bt_mesh_device_provision_and_configure(void)
{
	uint8_t status;
	int err;

	err = bt_mesh_provision(test_net_key, 0, 0, 0, cfg->addr, cfg->dev_key);
	if (err == -EALREADY) {
		LOG_INF("Using stored settings");
		return;
	} else if (err) {
		FAIL("Provisioning failed (err %d)", err);
		return;
	}

	/* Self configure */

	err = bt_mesh_cfg_app_key_add(0, cfg->addr, 0, 0, test_app_key,
				      &status);
	if (err || status) {
		FAIL("AppKey add failed (err %d, status %u)", err, status);
		return;
	}

	err = bt_mesh_cfg_mod_app_bind(0, cfg->addr, cfg->addr, 0, TEST_MOD_ID,
				       &status);
	if (err || status) {
		FAIL("Mod app bind failed (err %d, status %u)", err, status);
		return;
	}

	err = bt_mesh_cfg_net_transmit_set(0, cfg->addr,
					   BT_MESH_TRANSMIT(2, 20), &status);
	if (err || status != BT_MESH_TRANSMIT(2, 20)) {
		FAIL("Net transmit set failed (err %d, status %u)", err,
		     status);
		return;
	}
}

void bt_mesh_device_setup(const struct bt_mesh_prov *prov, const struct bt_mesh_comp *comp)
{
	int err;

	err = bt_enable(NULL);
	if (err) {
		FAIL("Bluetooth init failed (err %d)", err);
		return;
	}

	LOG_INF("Bluetooth initialized");

	err = bt_mesh_init(prov, comp);
	if (err) {
		FAIL("Initializing mesh failed (err %d)", err);
		return;
	}

	if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
		LOG_INF("Loading stored settings");
		settings_load();
	}

	LOG_INF("Mesh initialized");
}

void bt_mesh_test_setup(void)
{
	static struct bt_mesh_prov prov;

	net_buf_simple_init(pub.msg, 0);
	net_buf_simple_init(vnd_pub.msg, 0);

	bt_mesh_device_setup(&prov, &comp);
	bt_mesh_device_provision_and_configure();
}

void bt_mesh_test_timeout(bs_time_t HW_device_time)
{
	if (bst_result != Passed) {
		FAIL("Test timeout (not passed after %i seconds)",
		     HW_device_time / USEC_PER_SEC);
	}

	bs_trace_silent_exit(0);
}

void bt_mesh_test_cfg_set(const struct bt_mesh_test_cfg *my_cfg, int wait_time)
{
	bst_ticker_set_next_tick_absolute(wait_time * USEC_PER_SEC);
	bst_result = In_progress;
	cfg = my_cfg;
}

static struct bt_mesh_test_msg *blocking_recv(k_timeout_t timeout)
{
	if (K_TIMEOUT_EQ(timeout, K_NO_WAIT)) {
		return 0;
	}

	return k_queue_get(&recv, timeout);
}

int bt_mesh_test_recv(uint16_t len, uint16_t dst, k_timeout_t timeout)
{
	struct bt_mesh_test_msg *msg = blocking_recv(timeout);

	if (!msg) {
		return -ETIMEDOUT;
	}

	if (len != msg->len) {
		LOG_ERR("Recv: Invalid message length (%u, expected %u)", msg->len, len);
		return -EINVAL;
	}

	if (dst != BT_MESH_ADDR_UNASSIGNED && dst != msg->ctx.recv_dst) {
		LOG_ERR("Recv: Invalid dst 0x%04x, expected 0x%04x", msg->ctx.recv_dst, dst);
		return -EINVAL;
	}

	k_mem_slab_free(&msg_pool, (void **)&msg);

	return 0;
}

int bt_mesh_test_recv_msg(struct bt_mesh_test_msg *msg, k_timeout_t timeout)
{
	struct bt_mesh_test_msg *queued = blocking_recv(timeout);

	if (!queued) {
		return -ETIMEDOUT;
	}

	*msg = *queued;

	k_mem_slab_free(&msg_pool, (void **)&queued);

	return 0;
}

int bt_mesh_test_recv_clear(void)
{
	struct bt_mesh_test_msg *queued;
	int count = 0;

	while ((queued = k_queue_get(&recv, K_NO_WAIT))) {
		k_mem_slab_free(&msg_pool, (void **)&queued);
		count++;
	}

	return count;
}

struct sync_send_ctx {
	struct k_sem sem;
	int err;
};

static void tx_started(uint16_t dur, int err, void *data)
{
	struct sync_send_ctx *send_ctx = data;

	if (err) {
		LOG_ERR("Couldn't start sending (err: %d)", err);

		send_ctx->err = err;
		k_sem_give(&send_ctx->sem);

		return;
	}

	LOG_INF("Sending started");
}

static void tx_ended(int err, void *data)
{
	struct sync_send_ctx *send_ctx = data;

	send_ctx->err = err;

	if (err) {
		LOG_ERR("Send failed (%d)", err);
	} else {
		LOG_INF("Sending ended");
	}

	k_sem_give(&send_ctx->sem);
}

int bt_mesh_test_send_async(uint16_t addr, size_t len,
			    enum bt_mesh_test_send_flags flags,
			    const struct bt_mesh_send_cb *send_cb,
			    void *cb_data)
{
	const size_t mic_len =
		(flags & LONG_MIC) ? BT_MESH_MIC_LONG : BT_MESH_MIC_SHORT;
	static uint8_t count = 1;
	int err;

	test_send_ctx.addr = addr;
	test_send_ctx.send_rel = (flags & FORCE_SEGMENTATION);
	test_send_ctx.send_ttl = BT_MESH_TTL_DEFAULT;

	BT_MESH_MODEL_BUF_DEFINE(buf, TEST_MSG_OP_1, BT_MESH_TX_SDU_MAX);
	bt_mesh_model_msg_init(&buf, TEST_MSG_OP_1);

	if (len > BT_MESH_MODEL_OP_LEN(TEST_MSG_OP_1)) {
		net_buf_simple_add_u8(&buf, count);
	}

	/* Subtract the length of the opcode and the sequence ID */
	for (int i = 1; i < len - BT_MESH_MODEL_OP_LEN(TEST_MSG_OP_1); i++) {
		net_buf_simple_add_u8(&buf, i);
	}

	if (net_buf_simple_tailroom(&buf) < mic_len) {
		LOG_ERR("No room for MIC of len %u in %u byte buffer", mic_len,
			buf.len);
		return -EINVAL;
	}

	/* Seal the buffer to prevent accidentally long MICs: */
	buf.size = buf.len + mic_len;

	LOG_INF("Sending packet 0x%02x: %u %s to 0x%04x force seg: %u...",
		count, buf.len, (buf.len == 1 ? "byte" : "bytes"), addr,
		(flags & FORCE_SEGMENTATION));

	err = bt_mesh_model_send(test_model, &test_send_ctx, &buf, send_cb,
				 cb_data);
	if (err) {
		LOG_ERR("bt_mesh_model_send failed (err: %d)", err);
		return err;
	}

	count++;
	test_stats.sent++;
	return 0;
}

int bt_mesh_test_send(uint16_t addr, size_t len,
		      enum bt_mesh_test_send_flags flags, k_timeout_t timeout)
{
	if (K_TIMEOUT_EQ(timeout, K_NO_WAIT)) {
		return bt_mesh_test_send_async(addr, len, flags, NULL, NULL);
	}

	static const struct bt_mesh_send_cb send_cb = {
		.start = tx_started,
		.end = tx_ended,
	};
	int64_t uptime = k_uptime_get();
	struct sync_send_ctx send_ctx;
	int err;

	k_sem_init(&send_ctx.sem, 0, 1);
	err = bt_mesh_test_send_async(addr, len, flags, &send_cb, &send_ctx);
	if (err) {
		return err;
	}

	err = k_sem_take(&send_ctx.sem, timeout);
	if (err) {
		LOG_ERR("Send timed out");
		return err;
	}

	if (send_ctx.err) {
		return send_ctx.err;
	}

	LOG_INF("Sending completed (%lld ms)", k_uptime_delta(&uptime));

	return 0;
}

int bt_mesh_test_send_ra(uint16_t addr, uint8_t *data, size_t len,
			 const struct bt_mesh_send_cb *send_cb,
			 void *cb_data)
{
	int err;

	test_send_ctx.addr = addr;
	test_send_ctx.send_rel = 0;
	test_send_ctx.send_ttl = BT_MESH_TTL_DEFAULT;

	BT_MESH_MODEL_BUF_DEFINE(buf, TEST_MSG_OP_2, BT_MESH_TX_SDU_MAX);
	bt_mesh_model_msg_init(&buf, TEST_MSG_OP_2);

	net_buf_simple_add_mem(&buf, data, len);

	err = bt_mesh_model_send(test_model, &test_send_ctx, &buf, send_cb, cb_data);
	if (err) {
		LOG_ERR("bt_mesh_model_send failed (err: %d)", err);
		return err;
	}

	return 0;
}

void bt_mesh_test_ra_cb_setup(void (*cb)(uint8_t *, size_t))
{
	ra_cb = cb;
}
