/*
 * Copyright (c) 2022 Rodrigo Peixoto <rodrigopex@gmail.com>
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zephyr/sys/heap_listener.h>
#include <zephyr/zbus/zbus.h>
LOG_MODULE_REGISTER(sample, CONFIG_LOG_MAX_LEVEL);

extern struct sys_heap _system_heap;
static size_t total_allocated;

void on_heap_alloc(uintptr_t heap_id, void *mem, size_t bytes)
{
	total_allocated += bytes;
	LOG_INF(" AL Memory allocated %u bytes. Total allocated %u bytes", (unsigned int)bytes,
		(unsigned int)total_allocated);
}

void on_heap_free(uintptr_t heap_id, void *mem, size_t bytes)
{
	total_allocated -= bytes;
	LOG_INF(" FR Memory freed %u bytes. Total allocated %u bytes", (unsigned int)bytes,
		(unsigned int)total_allocated);
}

#if defined(CONFIG_ZBUS_MSG_SUBSCRIBER_NET_BUF_DYNAMIC)

HEAP_LISTENER_ALLOC_DEFINE(my_heap_listener_alloc, HEAP_ID_FROM_POINTER(&_system_heap),
			   on_heap_alloc);

HEAP_LISTENER_FREE_DEFINE(my_heap_listener_free, HEAP_ID_FROM_POINTER(&_system_heap), on_heap_free);

#endif /* CONFIG_ZBUS_MSG_SUBSCRIBER_NET_BUF_DYNAMIC */
struct acc_msg {
	int x;
	int y;
	int z;
};

ZBUS_CHAN_DEFINE(acc_data_chan,  /* Name */
		 struct acc_msg, /* Message type */

		 NULL, /* Validator */
		 NULL, /* User data */
		 ZBUS_OBSERVERS(bar_sub1, bar_msg_sub1, bar_msg_sub2, bar_msg_sub3, bar_msg_sub4,
				bar_msg_sub5, bar_msg_sub6, bar_msg_sub7, bar_msg_sub8,
				bar_msg_sub9, foo_lis), /* observers */
		 ZBUS_MSG_INIT(.x = 0, .y = 0, .z = 0)  /* Initial value */
);

static void listener_callback_example(const struct zbus_channel *chan)
{
	const struct acc_msg *acc = zbus_chan_const_msg(chan);

	LOG_INF("From listener foo_lis -> Acc x=%d, y=%d, z=%d", acc->x, acc->y, acc->z);
}

ZBUS_LISTENER_DEFINE(foo_lis, listener_callback_example);

ZBUS_MSG_SUBSCRIBER_DEFINE(bar_msg_sub1);
ZBUS_MSG_SUBSCRIBER_DEFINE(bar_msg_sub2);
ZBUS_MSG_SUBSCRIBER_DEFINE(bar_msg_sub3);
ZBUS_MSG_SUBSCRIBER_DEFINE(bar_msg_sub4);
ZBUS_MSG_SUBSCRIBER_DEFINE(bar_msg_sub5);
ZBUS_MSG_SUBSCRIBER_DEFINE(bar_msg_sub6);
ZBUS_MSG_SUBSCRIBER_DEFINE(bar_msg_sub7);
ZBUS_MSG_SUBSCRIBER_DEFINE(bar_msg_sub8);
ZBUS_MSG_SUBSCRIBER_DEFINE(bar_msg_sub9);
ZBUS_MSG_SUBSCRIBER_DEFINE(bar_msg_sub10);
ZBUS_MSG_SUBSCRIBER_DEFINE(bar_msg_sub11);
ZBUS_MSG_SUBSCRIBER_DEFINE(bar_msg_sub12);
ZBUS_MSG_SUBSCRIBER_DEFINE(bar_msg_sub13);
ZBUS_MSG_SUBSCRIBER_DEFINE(bar_msg_sub14);
ZBUS_MSG_SUBSCRIBER_DEFINE(bar_msg_sub15);
ZBUS_MSG_SUBSCRIBER_DEFINE(bar_msg_sub16);

ZBUS_SUBSCRIBER_DEFINE(bar_sub1, 4);
ZBUS_SUBSCRIBER_DEFINE(bar_sub2, 4);

static void msg_subscriber_task(void *sub)
{
	const struct zbus_channel *chan;

	struct acc_msg acc;

	const struct zbus_observer *subscriber = sub;

	while (!zbus_sub_wait_msg(subscriber, &chan, &acc, K_FOREVER)) {
		if (&acc_data_chan != chan) {
			LOG_ERR("Wrong channel %p!", chan);

			continue;
		}
		LOG_INF("From msg subscriber %s -> Acc x=%d, y=%d, z=%d", zbus_obs_name(subscriber),
			acc.x, acc.y, acc.z);
	}
}

K_THREAD_DEFINE(subscriber_task_id1, CONFIG_MAIN_STACK_SIZE, msg_subscriber_task, &bar_msg_sub1,
		NULL, NULL, 3, 0, 0);
K_THREAD_DEFINE(subscriber_task_id2, CONFIG_MAIN_STACK_SIZE, msg_subscriber_task, &bar_msg_sub2,
		NULL, NULL, 3, 0, 0);
K_THREAD_DEFINE(subscriber_task_id3, CONFIG_MAIN_STACK_SIZE, msg_subscriber_task, &bar_msg_sub3,
		NULL, NULL, 3, 0, 0);
K_THREAD_DEFINE(subscriber_task_id4, CONFIG_MAIN_STACK_SIZE, msg_subscriber_task, &bar_msg_sub4,
		NULL, NULL, 3, 0, 0);
K_THREAD_DEFINE(subscriber_task_id5, CONFIG_MAIN_STACK_SIZE, msg_subscriber_task, &bar_msg_sub5,
		NULL, NULL, 3, 0, 0);
K_THREAD_DEFINE(subscriber_task_id6, CONFIG_MAIN_STACK_SIZE, msg_subscriber_task, &bar_msg_sub6,
		NULL, NULL, 3, 0, 0);
K_THREAD_DEFINE(subscriber_task_id7, CONFIG_MAIN_STACK_SIZE, msg_subscriber_task, &bar_msg_sub7,
		NULL, NULL, 3, 0, 0);
K_THREAD_DEFINE(subscriber_task_id8, CONFIG_MAIN_STACK_SIZE, msg_subscriber_task, &bar_msg_sub8,
		NULL, NULL, 3, 0, 0);
K_THREAD_DEFINE(subscriber_task_id9, CONFIG_MAIN_STACK_SIZE, msg_subscriber_task, &bar_msg_sub9,
		NULL, NULL, 3, 0, 0);
K_THREAD_DEFINE(subscriber_task_id10, CONFIG_MAIN_STACK_SIZE, msg_subscriber_task, &bar_msg_sub10,
		NULL, NULL, 3, 0, 0);
K_THREAD_DEFINE(subscriber_task_id11, CONFIG_MAIN_STACK_SIZE, msg_subscriber_task, &bar_msg_sub11,
		NULL, NULL, 3, 0, 0);
K_THREAD_DEFINE(subscriber_task_id12, CONFIG_MAIN_STACK_SIZE, msg_subscriber_task, &bar_msg_sub12,
		NULL, NULL, 3, 0, 0);
K_THREAD_DEFINE(subscriber_task_id13, CONFIG_MAIN_STACK_SIZE, msg_subscriber_task, &bar_msg_sub13,
		NULL, NULL, 3, 0, 0);
K_THREAD_DEFINE(subscriber_task_id14, CONFIG_MAIN_STACK_SIZE, msg_subscriber_task, &bar_msg_sub14,
		NULL, NULL, 3, 0, 0);
K_THREAD_DEFINE(subscriber_task_id15, CONFIG_MAIN_STACK_SIZE, msg_subscriber_task, &bar_msg_sub15,
		NULL, NULL, 3, 0, 0);
K_THREAD_DEFINE(subscriber_task_id16, CONFIG_MAIN_STACK_SIZE, msg_subscriber_task, &bar_msg_sub16,
		NULL, NULL, 3, 0, 0);

static void subscriber_task(void *sub)
{
	const struct zbus_channel *chan;

	struct acc_msg acc;

	const struct zbus_observer *subscriber = sub;

	while (!zbus_sub_wait(subscriber, &chan, K_FOREVER)) {
		if (&acc_data_chan != chan) {
			LOG_ERR("Wrong channel %p!", chan);

			continue;
		}
		zbus_chan_read(chan, &acc, K_MSEC(250));

		LOG_INF("From subscriber %s -> Acc x=%d, y=%d, z=%d", zbus_obs_name(subscriber),
			acc.x, acc.y, acc.z);
	}
}

K_THREAD_DEFINE(subscriber_task_id17, CONFIG_MAIN_STACK_SIZE, subscriber_task, &bar_sub1, NULL,
		NULL, 3, 0, 0);
K_THREAD_DEFINE(subscriber_task_id18, CONFIG_MAIN_STACK_SIZE, subscriber_task, &bar_sub2, NULL,
		NULL, 3, 0, 0);

ZBUS_CHAN_ADD_OBS(acc_data_chan, bar_sub2, 3);
ZBUS_CHAN_ADD_OBS(acc_data_chan, bar_msg_sub10, 3);
ZBUS_CHAN_ADD_OBS(acc_data_chan, bar_msg_sub11, 3);
ZBUS_CHAN_ADD_OBS(acc_data_chan, bar_msg_sub12, 3);
ZBUS_CHAN_ADD_OBS(acc_data_chan, bar_msg_sub13, 3);
ZBUS_CHAN_ADD_OBS(acc_data_chan, bar_msg_sub14, 3);
ZBUS_CHAN_ADD_OBS(acc_data_chan, bar_msg_sub15, 3);
ZBUS_CHAN_ADD_OBS(acc_data_chan, bar_msg_sub16, 3);

int main(void)
{
	struct acc_msg acc = {.x = 1, .y = 10, .z = 100};

	total_allocated = 0;

#if defined(CONFIG_ZBUS_MSG_SUBSCRIBER_NET_BUF_DYNAMIC)

	heap_listener_register(&my_heap_listener_alloc);
	heap_listener_register(&my_heap_listener_free);

#endif /* CONFIG_ZBUS_MSG_SUBSCRIBER_NET_BUF_DYNAMIC */

	while (1) {
		LOG_INF("----> Publishing to %s channel", zbus_chan_name(&acc_data_chan));
		zbus_chan_pub(&acc_data_chan, &acc, K_SECONDS(1));
		acc.x += 1;
		acc.y += 10;
		acc.z += 100;

		k_msleep(1000);
	}

	return 0;
}
