#pragma once
#include "FreeRTOS.h"
#include "thread.h"
#include <locks.h>
#define INC_TASK_H

/**
 * Initialise a timeout with the current number of elapsed ticks.  This is used
 * in a blocking function in conjunction with `xTaskCheckForTimeOut()`.  The
 * value returned here should be passed as the first argument of
 * `xTaskCheckForTimeOut()`.
 */
static inline void vTaskSetTimeOutState(TimeOut_t *timeout)
{
	SystickReturn ret = thread_systemtick_get();
	*timeout          = ((uint64_t)ret.hi << 32) | ret.lo;
}

/**
 * Return whether a timeout has expired.  The first argument should be a
 * pointer to the value returned by `vTaskSetTimeOutState()` before any
 * blocking operations.  The second argument is the number of ticks to wait.
 * This function returns `pdTRUE` if the timeout has expired, or `pdFALSE` if
 * the timeout has not expired, and updates the arguments to reflect the
 * remaining time to wait.
 */
static inline BaseType_t xTaskCheckForTimeOut(TimeOut_t  *pxTimeOut,
                                              TickType_t *pxTicksToWait)
{
	BaseType_t xReturn;
	uint64_t   timeBlock;
	TickType_t xElapsedTime;

	vTaskSetTimeOutState(&timeBlock);

	xElapsedTime = timeBlock - *pxTimeOut;
	if (xElapsedTime < *pxTicksToWait)
	{
		*pxTicksToWait -= xElapsedTime;
		*pxTimeOut = timeBlock;
		xReturn    = pdFALSE;
	}
	else
	{
		*pxTicksToWait = (TickType_t)0;
		xReturn        = pdTRUE;
	}

	return xReturn;
}

/**
 * Block the current thread for a given number of ticks.
 */
static inline void vTaskDelay(const TickType_t xTicksToDelay)
{
	struct Timeout timeout = {0, xTicksToDelay};
	thread_sleep(&timeout, ThreadSleepNoEarlyWake);
}

/**
 * Return the number of ticks elapsed since the system booted.  This is
 * truncated to a 32-bit value.
 */
static inline TickType_t xTaskGetTickCount(void)
{
	return thread_systemtick_get().lo;
}

/**
 * Returns the current thread ID.
 */
static inline TaskHandle_t xTaskGetCurrentTaskHandle(void)
{
	return thread_id_get();
}

__BEGIN_DECLS

/**
 * Lock used to simulate disabling interrupts in `taskENTER_CRITICAL` and
 * `taskEXIT_CRITICAL`.  Code using these APIs must provide a definition to
 * accompany this declaration.
 */
extern struct RecursiveMutexState __CriticalSectionFlagLock;

/**
 * Lock used to simulate disabling interrupts in `vTaskSuspendAll` and
 * `xTaskResumeAll`.  Code using these APIs must provide a definition to
 * accompany this declaration.
 */
extern struct RecursiveMutexState __SuspendFlagLock;

__END_DECLS

/**
 * Critical section.  This acquires a recursive mutex.  In FreeRTOS, this
 * disables interrupts.  The CHERIoT RTOS security model does not permit
 * interrupts to be arbitrarily disabled, only for designated scopes.  Callers
 * of this should be carefully audited to ensure that they are safe.
 */
static inline void taskENTER_CRITICAL(void)
{
	Timeout t = {0, UnlimitedTimeout};
	recursivemutex_trylock(&t, &__CriticalSectionFlagLock);
}

/**
 * Exit a critical section entered with `taskENTER_CRITICAL`.
 */
static inline void taskEXIT_CRITICAL(void)
{
	recursivemutex_unlock(&__CriticalSectionFlagLock);
}

/**
 * Critical section.  This acquires a recursive mutex.  In FreeRTOS, this
 * disables interrupts.  The CHERIoT RTOS security model does not permit
 * interrupts to be arbitrarily disabled, only for designated scopes.  Callers
 * of this should be carefully audited to ensure that they are safe.
 */
static inline void vTaskSuspendAll(void)
{
	Timeout t = {0, UnlimitedTimeout};
	recursivemutex_trylock(&t, &__SuspendFlagLock);
}

/**
 * Exit a critical section entered with `vTaskSuspendAll`.
 */
static inline BaseType_t xTaskResumeAll(void)
{
	recursivemutex_unlock(&__SuspendFlagLock);
	return pdTRUE;
}

/**
 * Exit a critical section entered with `vTaskSuspendAll`.
 */
static inline void vTaskResumeAll(void)
{
	recursivemutex_unlock(&__SuspendFlagLock);
}

/**
 * Task creation API.  CHERIoT RTOS does not permit dynamic thread creation and
 * so this simply provides a warning so that ported code can be modified to
 * avoid the API.
 */
#define xTaskCreate(...)                                                       \
	_Pragma("GCC warning \"Dynamic thread creation is not supported\"")(       \
	  TaskHandle_t) -                                                          \
	  1

/**
 * Task creation API.  CHERIoT RTOS does not permit dynamic thread creation and
 * so this simply provides a warning so that ported code can be modified to
 * avoid the API.
 */
#define xTaskCreateStatic(...)                                                 \
	_Pragma("GCC warning \"Dynamic thread creation is not supported\"")(       \
	  TaskHandle_t) -                                                          \
	  1
