// Copyright Microsoft and CHERIoT Contributors.
// SPDX-License-Identifier: MIT

#pragma once

#include "loaderinfo.h"
#include <cdefs.h>
#include <cheri.hh>
#include <debug.hh>
#include <stdlib.h>
#include <token.h>
#include <type_traits>

namespace
{
	constexpr bool DebugScheduler =
#ifdef DEBUG_SCHEDULER
	  DEBUG_SCHEDULER
#else
	  false
#endif
	  ;

	/// Is scheduler accounting enabled?
	constexpr bool Accounting =
#ifdef SCHEDULER_ACCOUNTING
	  SCHEDULER_ACCOUNTING
#else
	  false
#endif
	  ;

	using Debug = ConditionalDebug<DebugScheduler, "Scheduler">;

	constexpr StackCheckMode StackMode =
#if CHERIOT_STACK_CHECKS_SCHEDULER
	  StackCheckMode::Asserting
#else
	  StackCheckMode::Disabled
	// Uncomment if checks failed to find the correct values
	// StackCheckMode::Logging
#endif
	  ;

#define STACK_CHECK(expected)                                                  \
	StackUsageCheck<StackMode, expected, __PRETTY_FUNCTION__> stackCheck

	/**
	 * Base class for sealed objects that are exported from the scheduler.
	 *
	 * Subclasses must implement a static `sealing_type` method that returns
	 * the sealing key.
	 */
	template<bool IsDynamicArg>
	struct Handle
	{
		/**
		 * Some Handle types must reside in static memory, and some may be built
		 * on the fly, and in particular in the shared heap, at runtime.  Is
		 * this type among the latter?
		 */
		static constexpr bool IsDynamic = IsDynamicArg;

		/**
		 * Unseal `unsafePointer` as a pointer to an object of the specified
		 * type.  Returns nullptr if `unsafePointer` is not a valid sealed
		 * pointer to an object of the correct type.
		 */
		template<typename T>
		static T *unseal(void *unsafePointer)
		{
			return static_cast<Handle *>(unsafePointer)->unseal_as<T>();
		}

		/**
		 * Unseal this object as the specified type.  Returns nullptr if this
		 * is not a valid sealed object of the correct type.
		 */
		template<typename T>
		T *unseal_as()
		{
			static_assert(std::is_base_of_v<Handle, T>,
			              "Cannot down-cast something that is not a subclass "
			              "of Handle");
			void *result;
			if constexpr (IsDynamic)
			{
				result = token_obj_unseal_dynamic(T::sealing_type(),
				                                  reinterpret_cast<SObj>(this));
			}
			else
			{
				result = token_obj_unseal_static(T::sealing_type(),
				                                 reinterpret_cast<SObj>(this));
			}
			return static_cast<T *>(result);
		}
	};

	/**
	 * RAII class for preventing nested exceptions.
	 */
	struct ExceptionGuard
	{
		/// The number of exception's currently being handled.
		static inline uint8_t exceptionLevel;

		/// RAII type, no copy constructor.
		ExceptionGuard(const ExceptionGuard &) = delete;
		/// RAII type, no move constructor.
		ExceptionGuard(ExceptionGuard &&) = delete;

		/**
		 * Constructor.  Increments the exception level and calls the handler
		 * if we are in a nested exception.
		 */
		__always_inline ExceptionGuard(auto &&errorHandler)
		{
			exceptionLevel++;
			if (exceptionLevel > 1)
			{
				errorHandler();
			}
		}

		/**
		 * Destructor, decrements the current exception level.
		 */
		__always_inline ~ExceptionGuard()
		{
			exceptionLevel--;
		}

		/**
		 * Panic if we are in a trying to block in an interrupt handler.
		 *
		 * In debug builds, this will report an error message with the caller's
		 * source location.
		 */
		static void
		assert_safe_to_block(SourceLocation loc = SourceLocation::current())
		{
			Debug::Invariant<>(exceptionLevel == 0,
			                   "Trying to block in an interrupt context.",
			                   loc);
		}
	};

	__BEGIN_DECLS
	void exception_entry_asm(void);
	__END_DECLS

} // namespace
