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

/**
 * @addtogroup t_alert_api
 * @{
 * @defgroup t_alert_context test_alert_send_recv_context
 * @brief TestPurpose: verify zephyr alert send/recv across different contexts
 */

#include <ztest.h>
#include <irq_offload.h>

#define TIMEOUT 100
#define STACK_SIZE 512
#define PENDING_MAX 2
static int alert_handler0(struct k_alert *);
static int alert_handler1(struct k_alert *);

/**TESTPOINT: init via K_ALERT_DEFINE*/
K_ALERT_DEFINE(kalert_pending, alert_handler1, PENDING_MAX);
K_ALERT_DEFINE(kalert_consumed, alert_handler0, PENDING_MAX);

static char __noinit __stack tstack[STACK_SIZE];
static struct k_alert *palert;
static volatile int handler_executed;

/*handlers*/
static int alert_handler0(struct k_alert *alt)
{
	handler_executed++;
	return 0;
}

static int alert_handler1(struct k_alert *alt)
{
	handler_executed++;
	return 1;
}

static void alert_send(void)
{
	/**TESTPOINT: alert send*/
	for (int i = 0; i < PENDING_MAX; i++) {
		k_alert_send(palert);
	}
}

static void alert_recv(void)
{
	int ret;

	if (palert->handler == K_ALERT_IGNORE ||
			palert->handler == alert_handler0){
		if (palert->handler == alert_handler0)
			assert_equal(handler_executed, PENDING_MAX, NULL);
		ret = k_alert_recv(palert, TIMEOUT);
		assert_equal(ret, -EAGAIN, NULL);
	}

	if (palert->handler == K_ALERT_DEFAULT ||
			palert->handler == alert_handler1){
		if (palert->handler == alert_handler1)
			assert_equal(handler_executed, PENDING_MAX, NULL);
		for (int i = 0; i < PENDING_MAX; i++) {
			/**TESTPOINT: alert recv*/
			ret = k_alert_recv(palert, K_NO_WAIT);
			assert_false(ret, NULL);
		}
		/**TESTPOINT: alert recv -EAGAIN*/
		ret = k_alert_recv(palert, TIMEOUT);
		assert_equal(ret, -EAGAIN, NULL);
		/**TESTPOINT: alert recv -EBUSY*/
		ret = k_alert_recv(palert, K_NO_WAIT);
		assert_equal(ret, -EBUSY, NULL);
	}
}

static void tThread_entry(void *p1, void *p2, void *p3)
{
	alert_recv();
}

static void thread_alert(void)
{
	handler_executed = 0;
	/**TESTPOINT: thread-thread sync via alert*/
	k_tid_t tid = k_thread_spawn(tstack, STACK_SIZE,
		tThread_entry, NULL, NULL, NULL,
		K_PRIO_PREEMPT(0), 0, 0);
	alert_send();
	k_sleep(TIMEOUT);
	k_thread_abort(tid);
}

static void tIsr_entry(void *p)
{
	alert_send();
}

static void isr_alert(void)
{
	handler_executed = 0;
	/**TESTPOINT: thread-isr sync via alert*/
	irq_offload(tIsr_entry, NULL);
	k_sleep(TIMEOUT);
	alert_recv();
}

/*test cases*/
void test_thread_alert_default(void)
{
	struct k_alert alert;
	/**TESTPOINT: init via k_alert_init*/
	k_alert_init(&alert, K_ALERT_DEFAULT, PENDING_MAX);

	/**TESTPOINT: alert handler default*/
	palert = &alert;
	thread_alert();

}

void test_thread_alert_ignore(void)
{
	/**TESTPOINT: alert handler ignore*/
	struct k_alert alert;
	/**TESTPOINT: init via k_alert_init*/
	k_alert_init(&alert, K_ALERT_IGNORE, PENDING_MAX);
	palert = &alert;
	thread_alert();
}

void test_thread_alert_consumed(void)
{
	struct k_alert alert;
	/**TESTPOINT: init via k_alert_init*/
	k_alert_init(&alert, alert_handler0, PENDING_MAX);

	/**TESTPOINT: alert handler return 0*/
	palert = &alert;
	thread_alert();
}

void test_thread_alert_pending(void)
{
	struct k_alert alert;
	/**TESTPOINT: init via k_alert_init*/
	k_alert_init(&alert, alert_handler1, PENDING_MAX);

	/**TESTPOINT: alert handler return 1*/
	palert = &alert;
	thread_alert();
}

void test_isr_alert_default(void)
{
	struct k_alert alert;
	/**TESTPOINT: init via k_alert_init*/
	k_alert_init(&alert, K_ALERT_DEFAULT, PENDING_MAX);

	/**TESTPOINT: alert handler default*/
	palert = &alert;
	isr_alert();
}

void test_isr_alert_ignore(void)
{
	/**TESTPOINT: alert handler ignore*/
	struct k_alert alert;
	/**TESTPOINT: init via k_alert_init*/
	k_alert_init(&alert, K_ALERT_IGNORE, PENDING_MAX);
	palert = &alert;
	isr_alert();
}

void test_isr_alert_consumed(void)
{
	struct k_alert alert;
	/**TESTPOINT: init via k_alert_init*/
	k_alert_init(&alert, alert_handler0, PENDING_MAX);

	/**TESTPOINT: alert handler return 0*/
	palert = &alert;
	isr_alert();
}

void test_isr_alert_pending(void)
{
	struct k_alert alert;
	/**TESTPOINT: init via k_alert_init*/
	k_alert_init(&alert, alert_handler1, PENDING_MAX);

	/**TESTPOINT: alert handler return 0*/
	palert = &alert;
	isr_alert();
}

void test_thread_kinit_alert(void)
{
	palert = &kalert_consumed;
	thread_alert();
	palert = &kalert_pending;
	thread_alert();
}

void test_isr_kinit_alert(void)
{
	palert = &kalert_consumed;
	isr_alert();
	palert = &kalert_pending;
	isr_alert();
}
