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

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

#include <zephyr/irq_offload.h>
#include <zephyr/kernel_structs.h>

#define TIMEOUT		(100)
#define SIGNAL1		(0x00000020)
#define SIGNAL2		(0x00000004)
#define SIGNAL		(SIGNAL1 | SIGNAL2)

#define SIGNAL_FLAG 0x00000001
#define ISR_SIGNAL 0x50

#define SIGNAL_ALL_FLAGS ((1 << osFeature_Signals) - 1)
#define SIGNAL_OUTOFLIMIT_FLAG ((1 << (osFeature_Signals + 1))-1)

void Thread_1(void const *arg)
{
	int signals = osSignalSet((osThreadId)arg, SIGNAL1);

	zassert_not_equal(signals, 0x80000000, "");
}

void Thread_2(void const *arg)
{
	int signals = osSignalSet((osThreadId)arg, SIGNAL2);

	zassert_not_equal(signals, 0x80000000, "");
}

void test_multiple_signal_flags(void const *thread_id)
{
	int max_signal_cnt = osFeature_Signals;
	int signals, sig_cnt;

	for (sig_cnt = 0; sig_cnt < max_signal_cnt; sig_cnt++) {
		/* create unique signal flags to set one flag at a time */
		int32_t signal_each_flag = SIGNAL_FLAG << sig_cnt;
		/* check if each signal flag is set properly */
		signals = osSignalSet((osThreadId)thread_id, signal_each_flag);
		zassert_not_equal(signals, 0x80000000,
				  "Setting each signal flag failed");
	}
	/* clear all the bits to check next scenario */
	signals = osSignalClear((osThreadId)thread_id, SIGNAL_ALL_FLAGS);
	zassert_not_equal(signals, 0x80000000, "");

	/* signal all the available flags at one shot */
	signals = osSignalSet((osThreadId)thread_id, SIGNAL_ALL_FLAGS);
	zassert_not_equal(signals, 0x80000000,
					  "Signal flags maximum limit failed");
	/* clear all the bits to check next scenario */
	signals = osSignalClear((osThreadId)thread_id, SIGNAL_ALL_FLAGS);
	zassert_not_equal(signals, 0x80000000, "");

	/* signal invalid flag to validate permissible flag limit */
	signals = osSignalSet((osThreadId)thread_id, SIGNAL_OUTOFLIMIT_FLAG);
	zassert_equal(signals, 0x80000000, "Signal flags set unexpectedly");
}

osThreadDef(Thread_1, osPriorityHigh, 3, 0);
osThreadDef(Thread_2, osPriorityHigh, 1, 0);

ZTEST(cmsis_signal, test_signal_events_no_wait)
{
	osThreadId id1;
	osEvent evt;

	id1 = osThreadCreate(osThread(Thread_1), osThreadGetId());
	zassert_true(id1 != NULL, "Thread creation failed");

	/* Let id1 run to trigger SIGNAL1 */
	osDelay(10);

	/* wait for SIGNAL1. It should return immediately as it is
	 * already triggered.
	 */
	evt = osSignalWait(SIGNAL1, 0);
	zassert_equal(evt.status, osEventSignal, "");
	zassert_equal((evt.value.signals & SIGNAL1), SIGNAL1, "");
	osThreadTerminate(id1);
}

ZTEST(cmsis_signal, test_signal_events_timeout)
{
	osThreadId id1;
	int signals;
	osEvent evt;

	id1 = osThreadCreate(osThread(Thread_1), osThreadGetId());
	zassert_true(id1 != NULL, "Thread creation failed");

	/* Let id1 run to trigger SIGNAL1 */
	osDelay(10);

	signals = osSignalClear(osThreadGetId(), SIGNAL1);
	zassert_not_equal(signals, 0x80000000, "signal clear failed");

	/* wait for SIGNAL1. It should timeout here as the signal
	 * though triggered, gets cleared in the previous step.
	 */
	evt = osSignalWait(SIGNAL1, TIMEOUT);
	zassert_equal(evt.status, osEventTimeout, "signal timeout failed");
	osThreadTerminate(id1);
}

ZTEST(cmsis_signal, test_signal_events_signalled)
{
	osThreadId id1, id2;
	osEvent evt;
	int signals;

	id1 = osThreadCreate(osThread(Thread_1), osThreadGetId());
	zassert_true(id1 != NULL, "Thread creation failed");

	id2 = osThreadCreate(osThread(Thread_2), osThreadGetId());
	zassert_true(id2 != NULL, "Thread creation failed");

	/* wait for multiple signals */
	evt = osSignalWait(SIGNAL, TIMEOUT);
	zassert_equal(evt.status, osEventSignal,
		      "wait signal returned unexpected error");
	zassert_equal((evt.value.signals & SIGNAL), SIGNAL,
		      "wait signal failed unexpectedly");

	signals = osSignalClear(osThreadGetId(), SIGNAL);
	zassert_not_equal(signals, 0x80000000, "clear signal failed");

	/* Set any single signal */
	signals = osSignalSet(osThreadGetId(), SIGNAL1);
	zassert_not_equal(signals, 0x80000000, "set any signal failed");

	/* wait for any single signal flag */
	evt = osSignalWait(0, TIMEOUT);
	zassert_equal(evt.status, osEventSignal, "wait for single flag failed");
	zassert_equal(evt.value.signals, SIGNAL1,
				  "wait single flag returned invalid value");

	/* validate by passing invalid parameters */
	zassert_equal(osSignalSet(NULL, 0), 0x80000000,
				  "NULL signal set unexpectedly");
	zassert_equal(osSignalClear(NULL, 0), 0x80000000,
				  "NULL signal cleared unexpectedly");
	/* cannot wait for Flag mask with MSB set */
	zassert_equal(osSignalWait((int32_t)0x80010000, 0).status, osErrorValue,
				  "signal wait passed unexpectedly");
	zassert_equal(osSignalSet(osThreadGetId(), (int32_t)0x80010000),
				  0x80000000, "signal set unexpectedly");
	zassert_equal(osSignalClear(osThreadGetId(), (int32_t)0x80010000),
				    0x80000000, "signal cleared unexpectedly");

	test_multiple_signal_flags(osThreadGetId());
}

/* IRQ offload function handler to set signal flag */
static void offload_function(const void *param)
{
	osThreadId tid = (osThreadId)param;
	int signals;

	/* Make sure we're in IRQ context */
	zassert_true(k_is_in_isr(), "Not in IRQ context!");

	signals = osSignalSet(tid, ISR_SIGNAL);
	zassert_not_equal(signals, 0x80000000, "signal set failed in ISR");
}

void test_signal_from_isr(void const *thread_id)
{
	/**TESTPOINT: Offload to IRQ context*/
	irq_offload(offload_function, (const void *)thread_id);
}

osThreadDef(test_signal_from_isr, osPriorityHigh, 1, 0);

ZTEST(cmsis_signal, test_signal_events_isr)
{
	osThreadId id;
	osEvent evt;

	id = osThreadCreate(osThread(test_signal_from_isr), osThreadGetId());
	zassert_true(id != NULL, "Thread creation failed");
	evt = osSignalWait(ISR_SIGNAL, TIMEOUT);
	zassert_equal(evt.status, osEventSignal,
		      "signal wait failed unexpectedly");
	zassert_equal((evt.value.signals & ISR_SIGNAL),
		       ISR_SIGNAL, "unexpected signal wait value");
}
ZTEST_SUITE(cmsis_signal, NULL, NULL, NULL, NULL, NULL);
