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

#include <ztest.h>
#include <kernel.h>
#include <cmsis_os2.h>

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

#define TIMEOUT_TICKS   (100)
#define FLAG1           (0x00000020)
#define FLAG2           (0x00000004)
#define FLAG            (FLAG1 | FLAG2)
#define ISR_FLAG        0x50
#define STACKSZ         CONFIG_CMSIS_V2_THREAD_MAX_STACK_SIZE

osEventFlagsId_t evt_id;

static void thread1(void *arg)
{
	int flags = osEventFlagsSet((osEventFlagsId_t)arg, FLAG1);

	zassert_equal(flags & FLAG1, FLAG1, "");
}

static void thread2(void *arg)
{
	int flags = osEventFlagsSet((osEventFlagsId_t)arg, FLAG2);

	/* Please note that as soon as the last flag that a thread is waiting
	 * on is set, the control shifts to that thread and that thread may
	 * choose to clear the flags as part of its osEventFlagsWait operation.
	 * In this test case, the main thread is waiting for FLAG1 and FLAG2.
	 * FLAG1 gets set first and then FLAG2 gets set. As soon as FLAG2 gets
	 * set, control shifts to the waiting thread where osEventFlagsWait
	 * clears FLAG1 and FLAG2 internally. When this thread eventually gets
	 * scheduled we should hence check if FLAG2 is cleared.
	 */
	zassert_equal(flags & FLAG2, 0, "");
}

static K_THREAD_STACK_DEFINE(test_stack1, STACKSZ);
static osThreadAttr_t thread1_attr = {
	.name = "Thread1",
	.stack_mem = &test_stack1,
	.stack_size = STACKSZ,
	.priority = osPriorityHigh,
};

static K_THREAD_STACK_DEFINE(test_stack2, STACKSZ);
static osThreadAttr_t thread2_attr = {
	.name = "Thread2",
	.stack_mem = &test_stack2,
	.stack_size = STACKSZ,
	.priority = osPriorityHigh,
};

static osEventFlagsAttr_t event_flags_attrs = {
	.name = "MyEvent",
	.attr_bits = 0,
	.cb_mem = NULL,
	.cb_size = 0,
};

void test_event_flags_no_wait_timeout(void)
{
	osThreadId_t id1;
	u32_t flags;
	const char *name;
	osEventFlagsId_t dummy_id = NULL;

	evt_id = osEventFlagsNew(&event_flags_attrs);
	zassert_true(evt_id != NULL, "Failed creating event flags");

	name = osEventFlagsGetName(dummy_id);
	zassert_true(name == NULL,
		     "Invalid event Flags ID is unexpectedly working!");

	name = osEventFlagsGetName(evt_id);
	zassert_true(strcmp(event_flags_attrs.name, name) == 0,
		     "Error getting event_flags object name");

	id1 = osThreadNew(thread1, evt_id, &thread1_attr);
	zassert_true(id1 != NULL, "Failed creating thread1");

	/* Let id1 run to trigger FLAG1 */
	osDelay(2);

	/* wait for FLAG1. It should return immediately as it is
	 * already triggered.
	 */
	flags = osEventFlagsWait(evt_id, FLAG1,
				 osFlagsWaitAny | osFlagsNoClear, 0);
	zassert_equal(flags & FLAG1, FLAG1, "");

	/* Since the flags are not cleared automatically in the previous step,
	 * we should be able to get the same flags upon query below.
	 */
	flags = osEventFlagsGet(evt_id);
	zassert_equal(flags & FLAG1, FLAG1, "");

	flags = osEventFlagsGet(dummy_id);
	zassert_true(flags == 0U,
		     "Invalid event Flags ID is unexpectedly working!");
	/* Clear the Flag explicitly */
	flags = osEventFlagsClear(evt_id, FLAG1);
	zassert_not_equal(flags, osFlagsErrorParameter, "Event clear failed");

	/* wait for FLAG1. It should timeout here as the event
	 * though triggered, gets cleared in the previous step.
	 */
	flags = osEventFlagsWait(evt_id, FLAG1, osFlagsWaitAny, TIMEOUT_TICKS);
	zassert_equal(flags, osFlagsErrorTimeout, "EventFlagsWait failed");
}

void test_event_flags_signalled(void)
{
	osThreadId_t id1, id2;
	u32_t flags;

	id1 = osThreadNew(thread1, evt_id, &thread1_attr);
	zassert_true(id1 != NULL, "Failed creating thread1");

	id2 = osThreadNew(thread2, evt_id, &thread2_attr);
	zassert_true(id2 != NULL, "Failed creating thread2");

	/* wait for multiple flags. The flags will be cleared automatically
	 * upon being set since "osFlagsNoClear" is not opted for.
	 */
	flags = osEventFlagsWait(evt_id, FLAG, osFlagsWaitAll, TIMEOUT_TICKS);
	zassert_equal(flags & FLAG, FLAG,
		      "osEventFlagsWait failed unexpectedly");

	/* set any single flag */
	flags = osEventFlagsSet(evt_id, FLAG1);
	zassert_equal(flags & FLAG1, FLAG1, "set any flag failed");

	flags = osEventFlagsWait(evt_id, FLAG1, osFlagsWaitAny, TIMEOUT_TICKS);
	zassert_equal(flags & FLAG1, FLAG1,
		      "osEventFlagsWait failed unexpectedly");

	/* validate by passing invalid parameters */
	zassert_equal(osEventFlagsSet(NULL, 0), osFlagsErrorParameter,
		      "Invalid event Flags ID is unexpectedly working!");
	zassert_equal(osEventFlagsSet(evt_id, 0x80010000),
		      osFlagsErrorParameter,
		      "Event with MSB set is set unexpectedly");

	zassert_equal(osEventFlagsClear(NULL, 0), osFlagsErrorParameter,
		      "Invalid event Flags ID is unexpectedly working!");
	zassert_equal(osEventFlagsClear(evt_id, 0x80010000),
		      osFlagsErrorParameter,
		      "Event with MSB set is cleared unexpectedly");

	/* cannot wait for Flag mask with MSB set */
	zassert_equal(osEventFlagsWait(evt_id, 0x80010000, osFlagsWaitAny, 0),
		      osFlagsErrorParameter,
		      "EventFlagsWait passed unexpectedly");
}

/* IRQ offload function handler to set event flag */
static void offload_function(void *param)
{
	int flags;

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

	flags = osEventFlagsSet((osEventFlagsId_t)param, ISR_FLAG);
	zassert_equal(flags & ISR_FLAG, ISR_FLAG,
		      "EventFlagsSet failed in ISR");
}

void test_event_from_isr(void *event_id)
{
	/**TESTPOINT: Offload to IRQ context*/
	irq_offload(offload_function, (void *)event_id);
}

static K_THREAD_STACK_DEFINE(test_stack3, STACKSZ);
static osThreadAttr_t thread3_attr = {
	.name = "Thread3",
	.stack_mem = &test_stack3,
	.stack_size = STACKSZ,
	.priority = osPriorityHigh,
};

void test_event_flags_isr(void)
{
	osThreadId_t id;
	int flags;
	osEventFlagsId_t dummy_id = NULL;

	id = osThreadNew(test_event_from_isr, evt_id, &thread3_attr);
	zassert_true(id != NULL, "Failed creating thread");

	flags = osEventFlagsWait(dummy_id, ISR_FLAG,
				 osFlagsWaitAll, TIMEOUT_TICKS);
	zassert_true(flags == osFlagsErrorParameter,
		     "Invalid event Flags ID is unexpectedly working!");

	flags = osEventFlagsWait(evt_id, ISR_FLAG,
				 osFlagsWaitAll, TIMEOUT_TICKS);
	zassert_equal((flags & ISR_FLAG),
		      ISR_FLAG, "unexpected event flags value");

	zassert_true(osEventFlagsDelete(dummy_id) == osErrorResource,
		     "Invalid event Flags ID is unexpectedly working!");

	zassert_true(osEventFlagsDelete(evt_id) == osOK,
		     "EventFlagsDelete failed");
}
