/*
 * Copyright (c) 2018 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/ztest.h>
#include <zephyr/kernel.h>

#define STACK_SIZE (512 + CONFIG_TEST_EXTRA_STACK_SIZE)
#define MAIL_LEN 64
#define HIGH_PRIO 1
#define LOW_PRIO  8

static K_THREAD_STACK_DEFINE(tstack, STACK_SIZE);
static K_THREAD_STACK_DEFINE(high_stack, STACK_SIZE);
static K_THREAD_STACK_DEFINE(low_stack, STACK_SIZE);

static struct k_thread tdata, high_tdata, low_tdata;
static struct k_mbox mbox, multi_tmbox;
static struct k_sem sync_sema;
static k_tid_t tid1, receiver_tid;
static char msg_data[2][MAIL_LEN] = {
	"send to high prio",
	"send to low prio"};

static enum mmsg_type {
	PUT_GET_NULL = 0,
	TARGET_SOURCE
} info_type;

static void msg_sender(struct k_mbox *pmbox, k_timeout_t timeout)
{
	static struct k_mbox_msg mmsg;

	(void)memset(&mmsg, 0, sizeof(mmsg));

	switch (info_type) {
	case PUT_GET_NULL:
		/* mbox sync put empty message */
		mmsg.info = PUT_GET_NULL;
		mmsg.size = 0;
		mmsg.tx_data = NULL;
		if (K_TIMEOUT_EQ(timeout, K_FOREVER)) {
			k_mbox_put(pmbox, &mmsg, K_FOREVER);
		} else if (K_TIMEOUT_EQ(timeout, K_NO_WAIT)) {
			k_mbox_put(pmbox, &mmsg, K_NO_WAIT);
		} else {
			k_mbox_put(pmbox, &mmsg, timeout);
		}
		break;
	default:
		break;
	}
}

static void msg_receiver(struct k_mbox *pmbox, k_tid_t thd_id,
			 k_timeout_t timeout)
{
	static struct k_mbox_msg mmsg;
	static char rxdata[MAIL_LEN];

	switch (info_type) {
	case PUT_GET_NULL:
		mmsg.size = sizeof(rxdata);
		mmsg.rx_source_thread = thd_id;
		if (K_TIMEOUT_EQ(timeout, K_FOREVER)) {
			zassert_true(k_mbox_get(pmbox, &mmsg,
				     rxdata, K_FOREVER) == 0, NULL);
		} else if (K_TIMEOUT_EQ(timeout, K_NO_WAIT)) {
			zassert_false(k_mbox_get(pmbox, &mmsg,
				      rxdata, K_NO_WAIT) == 0, NULL);
		} else {
			zassert_true(k_mbox_get(pmbox, &mmsg,
				     rxdata, timeout) == 0, NULL);
		}
		break;
	default:
		break;
	}
}

static void test_mbox_init(void)
{
	k_mbox_init(&mbox);
	k_mbox_init(&multi_tmbox);

	k_sem_init(&sync_sema, 0, 2);
}

static void test_send(void *p1, void *p2, void *p3)
{
	msg_sender((struct k_mbox *)p1, K_NO_WAIT);
}

/* Receive message from any thread with no wait */
ZTEST(mbox_usage, test_msg_receiver)
{
	static k_tid_t tid;

	info_type = PUT_GET_NULL;
	msg_receiver(&mbox, K_ANY, K_NO_WAIT);

	tid = k_thread_create(&tdata, tstack, STACK_SIZE,
			      test_send, &mbox, NULL, NULL,
			      K_PRIO_PREEMPT(0), 0, K_NO_WAIT);

	msg_receiver(&mbox, K_ANY, K_MSEC(2));
	k_thread_abort(tid);
}

static void test_send_un(void *p1, void *p2, void *p3)
{
	TC_PRINT("Sender UNLIMITED\n");
	msg_sender((struct k_mbox *)p1, K_FOREVER);
}

/* Receive message from thread tid1 */
ZTEST(mbox_usage, test_msg_receiver_unlimited)
{
	info_type = PUT_GET_NULL;

	receiver_tid = k_current_get();
	tid1 = k_thread_create(&tdata, tstack, STACK_SIZE,
			      test_send_un, &mbox, NULL, NULL,
			      K_PRIO_PREEMPT(0), 0, K_NO_WAIT);

	msg_receiver(&mbox, tid1, K_FOREVER);
	k_thread_abort(tid1);
}

static void thread_low_prio(void *p1, void *p2, void *p3)
{
	static struct k_mbox_msg mmsg = {0};
	static char rxdata[MAIL_LEN];
	int ret;

	mmsg.rx_source_thread = K_ANY;
	mmsg.size = sizeof(rxdata);
	ret = k_mbox_get(&multi_tmbox, &mmsg, rxdata, K_FOREVER);

	zassert_equal(ret, 0, "low prio get msg failed");
	zassert_equal(memcmp(rxdata, msg_data[1], MAIL_LEN), 0,
		      "low prio data error");

	k_sem_give(&sync_sema);
}

static void thread_high_prio(void *p1, void *p2, void *p3)
{
	static struct k_mbox_msg mmsg = {0};
	static char rxdata[MAIL_LEN];
	int ret;

	mmsg.rx_source_thread = K_ANY;
	mmsg.size = sizeof(rxdata);
	ret = k_mbox_get(&multi_tmbox, &mmsg, rxdata, K_FOREVER);

	zassert_equal(ret, 0, "high prio get msg failed");
	zassert_equal(memcmp(rxdata, msg_data[0], MAIL_LEN), 0,
		      "high prio data error");

	k_sem_give(&sync_sema);
}

ZTEST_USER(mbox_usage_1cpu, test_multi_thread_send_get)
{
	static k_tid_t low_prio, high_prio;
	struct k_mbox_msg mmsg = {0};

	k_sem_reset(&sync_sema);
	/* Create diff priority thread to receive msg with same mbox */
	low_prio = k_thread_create(&low_tdata, low_stack, STACK_SIZE,
				  thread_low_prio, &multi_tmbox, NULL, NULL,
				  LOW_PRIO, 0, K_NO_WAIT);

	high_prio = k_thread_create(&high_tdata, high_stack, STACK_SIZE,
				    thread_high_prio, &multi_tmbox, NULL, NULL,
				    HIGH_PRIO, 0, K_NO_WAIT);

	k_sleep(K_MSEC(20));
	mmsg.size = sizeof(msg_data[0]);
	mmsg.tx_data = msg_data[0];
	mmsg.tx_target_thread = K_ANY;
	k_mbox_put(&multi_tmbox, &mmsg, K_FOREVER);

	mmsg.size = sizeof(msg_data[1]);
	mmsg.tx_data = msg_data[1];
	mmsg.tx_target_thread = K_ANY;
	k_mbox_put(&multi_tmbox, &mmsg, K_FOREVER);

	/* Sync with threads to ensure process end */
	k_sem_take(&sync_sema, K_FOREVER);
	k_sem_take(&sync_sema, K_FOREVER);

	k_thread_abort(low_prio);
	k_thread_abort(high_prio);
}

void *setup_mbox_usage(void)
{
	test_mbox_init();

	return NULL;
}

ZTEST_SUITE(mbox_usage, NULL, setup_mbox_usage, NULL, NULL, NULL);

ZTEST_SUITE(mbox_usage_1cpu, NULL, setup_mbox_usage,
	ztest_simple_1cpu_before, ztest_simple_1cpu_after, NULL);
