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

#pragma once
#include <__debug.h>
#include <cheri.hh>
#include <compartment.h>
#include <concepts>
#include <cstddef>
#include <platform-uart.hh>
#include <string.h>
#include <switcher.h>

#include <array>
#include <string_view>
#include <type_traits>

namespace DebugConcepts
{
	/// Helper concept for matching booleans
	template<typename T>
	concept IsBool = std::is_same_v<T, bool>;

	/// Helper concept for matching enumerations.
	template<typename T>
	concept IsEnum = std::is_enum_v<T>;

	/// Concept for something that can be lazily called to produce a bool.
	template<typename T>
	concept LazyAssertion = requires(T v)
	{
		{
			v()
			} -> IsBool;
	};

	template<typename T>
	concept IsPointerButNotCString =
	  std::is_pointer_v<T> && !std::is_same_v<T, const char *>;

	template<typename T>
	concept IsConvertibleToAddress =
	  std::convertible_to<T, ptraddr_t> && !IsEnum<T>;

} // namespace DebugConcepts

/**
 * Abstract class for writing debug output.  This is used for custom output.
 *
 * This may be changed in the future to provide better support for custom
 * formatting.
 */
struct DebugWriter
{
	/**
	 * Write a single character.
	 */
	virtual void write(char) = 0;
	/**
	 * Write a C string.
	 */
	virtual void write(const char *) = 0;
	/**
	 * Write a string view.
	 */
	virtual void write(std::string_view) = 0;
	/**
	 * Write a 32-bit unsigned integer.
	 */
	virtual void write(uint32_t) = 0;
	/**
	 * Write a 32-bit signed integer.
	 */
	virtual void write(int32_t) = 0;
	/**
	 * Write a 64-bit unsigned integer.
	 */
	virtual void write(uint64_t) = 0;
	/**
	 * Write a 64-bit signed integer.
	 */
	virtual void write(int64_t) = 0;
};

/**
 * Helper function for writing enumerations.  Enumerations are written using
 * magic_enum to provide a string and then a numeric value.
 */
template<typename T>
void debug_enum_helper(uintptr_t    value,
                       DebugWriter &writer) requires DebugConcepts::IsEnum<T>
{
	writer.write(magic_enum::enum_name<T>(static_cast<T>(value)));
	writer.write('(');
	writer.write(uint32_t(value));
	writer.write(')');
}

/**
 * Callback for custom types in debug output.  This should use the second
 * argument to write the first argument to the debug output.
 */
using DebugCallback = void (*)(uintptr_t, DebugWriter &);

/**
 * Adaptor that turns an argument of type `T` into a `DebugFormatArgument`.
 *
 * Users may specialise these to provide custom formatters.  See the
 * specialisation for enumerations for an example.
 */
template<typename T>
struct DebugFormatArgumentAdaptor;

/**
 * Boolean specialisation, prints "true" or "false".
 */
template<>
struct DebugFormatArgumentAdaptor<bool>
{
	__always_inline static DebugFormatArgument construct(bool value)
	{
		return {static_cast<uintptr_t>(value),
		        DebugFormatArgumentKind::DebugFormatArgumentBool};
	}
};

/**
 * Character specialisation, prints the character.
 */
template<>
struct DebugFormatArgumentAdaptor<char>
{
	__always_inline static DebugFormatArgument construct(char value)
	{
		return {static_cast<uintptr_t>(value),
		        DebugFormatArgumentKind::DebugFormatArgumentCharacter};
	}
};

/**
 * Unsigned character specialisation, prints the character as a hex number.
 */
template<>
struct DebugFormatArgumentAdaptor<uint8_t>
{
	__always_inline static DebugFormatArgument construct(uint8_t value)
	{
		return {static_cast<uintptr_t>(value),
		        DebugFormatArgumentKind::DebugFormatArgumentUnsignedNumber32};
	}
};

/**
 * Unsigned 16-bit integer specialisation, prints the integer as a hex number.
 */
template<>
struct DebugFormatArgumentAdaptor<uint16_t>
{
	__always_inline static DebugFormatArgument construct(uint16_t value)
	{
		return {static_cast<uintptr_t>(value),
		        DebugFormatArgumentKind::DebugFormatArgumentUnsignedNumber32};
	}
};

/**
 * Unsigned 32-bit integer specialisation, prints the integer as a hex number.
 */
template<>
struct DebugFormatArgumentAdaptor<uint32_t>
{
	__always_inline static DebugFormatArgument construct(uint32_t value)
	{
		return {static_cast<uintptr_t>(value),
		        DebugFormatArgumentKind::DebugFormatArgumentUnsignedNumber32};
	}
};

/**
 * Unsigned 64-bit integer specialisation, prints the integer as a hex number.
 *
 * All smaller sizes are handled by zero extending to 32 bits.  We treat 64-bit
 * separately because it requires decomposing the two halves for printing and
 * that's redundant overhead for the majority of cases.
 */
template<>
struct DebugFormatArgumentAdaptor<uint64_t>
{
	__always_inline static DebugFormatArgument construct(uint64_t value)
	{
		uintptr_t fudgedValue;
		memcpy(&fudgedValue, &value, sizeof(fudgedValue));
		return {fudgedValue,
		        DebugFormatArgumentKind::DebugFormatArgumentUnsignedNumber64};
	}
};

/**
 * Signed 8-bit integer specialisations, print the integer as a decimal number.
 */
template<>
struct DebugFormatArgumentAdaptor<int8_t>
{
	__always_inline static DebugFormatArgument construct(int8_t value)
	{
		return {static_cast<uintptr_t>(value),
		        DebugFormatArgumentKind::DebugFormatArgumentSignedNumber32};
	}
};

/**
 * Signed 16-bit integer specialisations, print the integer as a decimal number.
 */
template<>
struct DebugFormatArgumentAdaptor<int16_t>
{
	__always_inline static DebugFormatArgument construct(int16_t value)
	{
		return {static_cast<uintptr_t>(value),
		        DebugFormatArgumentKind::DebugFormatArgumentSignedNumber32};
	}
};

/**
 * Signed 32-bit integer specialisations, print the integer as a decimal number.
 */
template<>
struct DebugFormatArgumentAdaptor<int32_t>
{
	__always_inline static DebugFormatArgument construct(int32_t value)
	{
		return {static_cast<uintptr_t>(value),
		        DebugFormatArgumentKind::DebugFormatArgumentSignedNumber32};
	}
};

/**
 * Signed 64-bit integer specialisations, print the integer as a decimal number.
 *
 * All smaller sizes are handled by sign extending to 32 bits.  We treat 64-bit
 * separately because it requires 64-bit division to convert a 64-bit integer
 * to a decimal and that, in turn, requires libcalls.
 */
template<>
struct DebugFormatArgumentAdaptor<int64_t>
{
	__always_inline static DebugFormatArgument construct(int64_t value)
	{
		static_assert(sizeof(uintptr_t) == sizeof(uint64_t));
		uintptr_t fudgedValue;
		memcpy(&fudgedValue, &value, sizeof(fudgedValue));
		return {fudgedValue,
		        DebugFormatArgumentKind::DebugFormatArgumentSignedNumber64};
	}
};

/**
 * C string specialisation, prints the string as-is.
 */
template<>
struct DebugFormatArgumentAdaptor<const char *>
{
	__always_inline static DebugFormatArgument construct(const char *value)
	{
		return {reinterpret_cast<uintptr_t>(value),
		        DebugFormatArgumentKind::DebugFormatArgumentCString};
	}
};

/**
 * String view specialisation, prints the string as-is.
 *
 * Note that this relies on the string view persisting for the duration of the
 * call.  It passes a pointer to the string-view argument.
 */
template<>
struct DebugFormatArgumentAdaptor<std::string_view>
{
	__always_inline static DebugFormatArgument
	construct(std::string_view &value)
	{
		return {reinterpret_cast<uintptr_t>(&value),
		        DebugFormatArgumentKind::DebugFormatArgumentStringView};
	}
};

/**
 * String view specialisation, use the C string handler.
 */
template<>
struct DebugFormatArgumentAdaptor<std::string>
{
	__always_inline static DebugFormatArgument construct(std::string &value)
	{
		return DebugFormatArgumentAdaptor<const char *>::construct(
		  value.c_str());
	}
};

/**
 * Enum specialisation, prints the enum as a string and then the numeric value.
 *
 * This specialisation uses the generic printing facility in the library call
 * and passes a callback that will map the enumeration to a string.
 */
template<DebugConcepts::IsEnum T>
struct DebugFormatArgumentAdaptor<T>
{
	__always_inline static DebugFormatArgument construct(T value)
	{
#ifdef CHERIOT_AVOID_CAPRELOCS
		return {static_cast<uintptr_t>(value),
		        DebugFormatArgumentKind::DebugFormatArgumentUnsignedNumber32};
#else
		return {static_cast<uintptr_t>(value),
		        reinterpret_cast<uintptr_t>(&debug_enum_helper<T>)};
#endif
	}
};

/**
 * Permission set specialisation.
 */
template<>
struct DebugFormatArgumentAdaptor<CHERI::PermissionSet>
{
	__always_inline static DebugFormatArgument
	construct(CHERI::PermissionSet value)
	{
		return {static_cast<uintptr_t>(value.as_raw()),
		        DebugFormatArgumentKind::DebugFormatArgumentPermissionSet};
	}
};

/**
 * Null pointer specialisation.
 */
template<>
struct DebugFormatArgumentAdaptor<std::nullptr_t>
{
	__always_inline static DebugFormatArgument construct(std::nullptr_t)
	{
		return {0, DebugFormatArgumentKind::DebugFormatArgumentPointer};
	}
};

/**
 * Pointer specialisation, prints the pointer as a full capability.
 */
template<DebugConcepts::IsPointerButNotCString T>
struct DebugFormatArgumentAdaptor<T>
{
	__always_inline static DebugFormatArgument construct(T value)
	{
		return {reinterpret_cast<uintptr_t>(
		          static_cast<const volatile void *>(value)),
		        DebugFormatArgumentKind::DebugFormatArgumentPointer};
	}
};

/**
 * Specialisation for the CHERI capability wrapper class, prints the capability
 * in the same format as bare pointers.
 */
template<typename T>
struct DebugFormatArgumentAdaptor<CHERI::Capability<T>>
{
	__always_inline static DebugFormatArgument
	construct(CHERI::Capability<T> value)
	{
		return {reinterpret_cast<uintptr_t>(
		          static_cast<const volatile void *>(value)),
		        DebugFormatArgumentKind::DebugFormatArgumentPointer};
	}
};

/**
 * Specialisation for things that can be converted to addresses, prints as an
 * unsigned number.
 */
template<DebugConcepts::IsConvertibleToAddress T>
struct DebugFormatArgumentAdaptor<T>
{
	__always_inline static DebugFormatArgument construct(ptraddr_t value)
	{
		return {static_cast<uintptr_t>(value),

		        DebugFormatArgumentKind::DebugFormatArgumentUnsignedNumber32};
	}
};

/**
 * Recursive helper that maps from a tuple representing the arguments into a
 * type-erased array.
 */
template<size_t I>
__always_inline inline void map_debug_argument(DebugFormatArgument *arguments,
                                               auto &&argumentTuple)
{
	arguments[I] =
	  DebugFormatArgumentAdaptor<
	    std::remove_cvref_t<decltype(std::get<I>(argumentTuple))>>{}
	    .construct(std::get<I>(argumentTuple));
	if constexpr (I > 0)
	{
		map_debug_argument<I - 1>(arguments, argumentTuple);
	}
}

/**
 * Convert `args` into a type-erased array of `DebugFormatArgument`s in
 * `arguments`.
 */
template<typename... Args>
__always_inline inline void
make_debug_arguments_list(DebugFormatArgument *arguments, Args... args)
{
	if constexpr (sizeof...(Args) > 0)
	{
		map_debug_argument<sizeof...(Args) - 1>(arguments,
		                                        std::forward_as_tuple(args...));
	}
}

/**
 * Library function that writes a debug message.  This runs with interrupts
 * disabled (to avoid interleaving) and prints an array of debug messages. This
 * is intended to allow a single call to print multiple format strings without
 * requiring the format strings to be copied, so that the debugging APIs can
 * wrap a user-provided format string.
 */
__cheri_libcall void debug_log_message_write(const char          *context,
                                             const char          *format,
                                             DebugFormatArgument *messages,
                                             size_t               messageCount);

__cheri_libcall void debug_report_failure(const char          *kind,
                                          const char          *file,
                                          const char          *function,
                                          int                  line,
                                          const char          *fmt,
                                          DebugFormatArgument *arguments,
                                          size_t               argumentCount);

namespace
{
	/**
	 * Helper class wrapping a string for use as a template argument.  This is
	 * used to describe a context for conditional debugging that will be
	 * prefixed to debug lines.
	 */
	template<size_t N>
	struct DebugContext
	{
		/**
		 * Constructor, captures the string argument.
		 */
		constexpr DebugContext(const char (&str)[N])
		{
			std::copy_n(str, N, value);
		}

		/**
		 * Implicit conversion to a C string.
		 */
		constexpr operator const char *() const
		{
			return value;
		}

		/**
		 * The captured string.  Must be public for this class to meet the
		 * requirements of a structural type for use as a template argument.
		 */
		char value[N];
	};

	/**
	 * Our libc++ does not currently provide source_location, but our clang
	 * provides the necessary builtins for one.
	 */
	struct SourceLocation
	{
		/**
		 * Explicitly construct a source location.
		 */
		constexpr SourceLocation(int         lineNumber,
		                         int         columnNumber,
		                         const char *fileName,
		                         const char *functionName)
		  : lineNumber(lineNumber),
		    columnNumber(columnNumber),
		    fileName(fileName),
		    functionName(functionName)
		{
		}

		/**
		 * Construct a source location for the caller.
		 */
		static constexpr SourceLocation __always_inline
		current(int         lineNumber   = __builtin_LINE(),
		        int         columnNumber = __builtin_COLUMN(),
		        const char *fileName     = __builtin_FILE(),
		        const char *functionName = __builtin_FUNCTION()) noexcept
		{
			return {lineNumber, columnNumber, fileName, functionName};
		}

		/// Returns the line number for this source location.
		[[nodiscard]] __always_inline constexpr int line() const noexcept
		{
			return lineNumber;
		}
		/// Returns the column number for this source location.
		[[nodiscard]] __always_inline constexpr int column() const noexcept
		{
			return columnNumber;
		}
		/// Returns the file name for this source location.
		[[nodiscard]] __always_inline constexpr const char *
		file_name() const noexcept
		{
			return fileName;
		}
		/// Returns the function name for this source location.
		[[nodiscard]] __always_inline constexpr const char *
		function_name() const noexcept
		{
			return functionName;
		}

		private:
		/// The line number of this source location.
		int lineNumber;
		/// The column number of this source location.
		int columnNumber;
		/// The file name of this source location.
		const char *fileName;
		/// The function name of this source location.
		const char *functionName;
	};

	/**
	 * Conditional debug class.  Used to control conditional output and
	 * assertion checking.  Enables debug log messages and assertions if
	 * `Enabled` is true.  Uses `Context` to print additional detail on debug
	 * lines.  Each line is prefixed with the context string in magenta to make
	 * it easy to see debug output from different subsystems in the same trace.
	 *
	 * This class is expected to be used as a type alias, something like:
	 *
	 * ```c++
	 * constexpr bool DebugFoo = DEBUG_FOO;
	 * using Debug = ConditionalDebug<DebugFoo, "Foo">;
	 * ```
	 */
	template<bool Enabled, DebugContext Context>
	class ConditionalDebug
	{
		public:
		/**
		 * Log a message.
		 *
		 * This function does nothing if the `Enabled` condition is false.
		 */
		template<typename... Args>
		static void log(const char *fmt, Args... args)
		{
			if constexpr (Enabled)
			{
				asm volatile("" ::: "memory");
				DebugFormatArgument arguments[sizeof...(Args)];
				make_debug_arguments_list(arguments, args...);
				const char *context = Context;
				debug_log_message_write(
				  context, fmt, arguments, sizeof...(Args));
				asm volatile("" ::: "memory");
			}
		}

		/**
		 * Helper to report failure.
		 *
		 * This must not take the `SourceLocation` directly because doing so
		 * prevents the compiler from decomposing and subsequently
		 * constant-propagating its fields in the caller, resulting in 24 bytes
		 * of stack space consumed for every assert or invariant.
		 */
		template<typename... Args>
		static inline void report_failure(const char *kind,
		                                  const char *file,
		                                  const char *function,
		                                  int         line,
		                                  const char *fmt,
		                                  Args... args)
		{
			// Ensure that the compiler does not reorder messages.
			DebugFormatArgument arguments[sizeof...(Args)];
			make_debug_arguments_list(arguments, args...);
			const char *context = Context;
			debug_report_failure(
			  kind, file, function, line, fmt, arguments, sizeof...(Args));
		}

		/**
		 * Function-like class for invariants that is expected to be used via
		 * the deduction guide as:
		 *
		 * ConditionalDebug::Invariant(someCondition, "A message...", ...);
		 *
		 * Invariants are checked unconditionally but will log a verbose
		 * message only if `Enabled` is true.
		 */
		template<typename... Args>
		struct Invariant
		{
			/**
			 * Constructor, performs the invariant check.
			 */
			__always_inline
			Invariant(bool        condition,
			          const char *fmt,
			          Args... args,
			          SourceLocation loc = SourceLocation::current())
			{
				if (__predict_false(!condition))
				{
					if constexpr (Enabled)
					{
						report_failure("Invariant",
						               loc.file_name(),
						               loc.function_name(),
						               loc.line(),
						               fmt,
						               std::forward<Args>(args)...);
					}
					__builtin_trap();
				}
			}
		};
		/**
		 * Function-like class for assertions that is expected to be used via
		 * the deduction guide as:
		 *
		 * ConditionalDebug::Assert(someCondition, "A message...", ...);
		 *
		 * Assertions are checked only if `Enabled` is true.
		 */
		template<typename... Args>
		struct Assert
		{
			/**
			 * Constructor, performs the assertion check.
			 */
			template<typename T>
			requires DebugConcepts::IsBool<T> __always_inline
			Assert(T           condition,
			       const char *fmt,
			       Args... args,
			       SourceLocation loc = SourceLocation::current())
			{
				if constexpr (Enabled)
				{
					if (__predict_false(!condition))
					{
						report_failure("Assertion",
						               loc.file_name(),
						               loc.function_name(),
						               loc.line(),
						               fmt,
						               std::forward<Args>(args)...);
						__builtin_trap();
					}
				}
			}

			/**
			 * Constructor, performs an assertion check.
			 *
			 * This version is passed a lambda that returns a bool, rather than
			 * a boolean condition.  This allows the compiler to completely
			 * elide the contents of the lambda in builds where this component
			 * is not being debugged.  This version should be used for places
			 * where the assertion condition has side effects.
			 */
			template<typename T>
			requires DebugConcepts::LazyAssertion<T> __always_inline
			Assert(T         &&condition,
			       const char *fmt,
			       Args... args,
			       SourceLocation loc = SourceLocation::current())
			{
				if constexpr (Enabled)
				{
					if (__predict_false(!condition()))
					{
						report_failure("Assertion",
						               loc.file_name(),
						               loc.function_name(),
						               loc.line(),
						               fmt,
						               std::forward<Args>(args)...);
						__builtin_trap();
					}
				}
			}
		};

		/**
		 * Deduction guide, allows `Invariant` to be used as if it were a
		 * function.
		 */
		template<typename T, typename... Ts>
		Invariant(T, const char *, Ts &&...) -> Invariant<Ts...>;

		/**
		 * Deduction guide, allows `Assert` to be used as if it were a
		 * function.
		 */
		template<typename... Ts>
		Assert(bool, const char *, Ts &&...) -> Assert<Ts...>;

		/**
		 * Deduction guide, allows `Assert` to be used as if it were a
		 * function with a lambda argument.
		 */
		template<typename... Ts>
		Assert(auto, const char *, Ts &&...) -> Assert<Ts...>;
	};

	enum class StackCheckMode
	{
		Disabled,
		Logging,
		Asserting,
	};

	/**
	 * Check the (dynamic) stack usage of a function, including all of its
	 * callees.  This is intended to be used in compartment entry points to
	 * check the stack size that is required for that entry point.  Use this
	 * with some test vectors that explore different code paths to identify the
	 * maximum stack usage.  This can then be used with the
	 * [[cheriot::minimum_stack]] attribute to ensure that the switcher will
	 * never invoke the entry point with insufficient stack.
	 *
	 * Note that this records only the stack usage for the current compartment
	 * invocation (including any invoked shared libraries).  If this
	 * compartment calls others, then a larger stack may be required.  This
	 * failure is recoverable: cross-compartment calls should always be assumed
	 * to potentially fail.  This check is to ensure that an attacker cannot
	 * cause stack overflow to crash the compartment, not to ensure that an
	 * attacker cannot cause stack overflow to make the operation that they
	 * requested fail.
	 *
	 * Stack checks run in one of three modes:
	 *
	 *  - Disabled: The checks do not run.
	 *  - Logging: The checks run and print a message if the stack usage
	 *    exceeds expectations.
	 *  - Asserting: After printing the message, the function will trap.
	 *
	 * In logging mode, one message will be printed for each invocation of the
	 * function that exceeds the previous maximum stack usage.
	 *
	 * An instance of this should be created as a local variable on entry to a
	 * function.  The destructor (which prints the message) will then run after
	 * any other destructors, ensuring the most accurate stack usage
	 * measurement.
	 *
	 * Unfortunately, default arguments for templates are not evaluated in the
	 * enclosing scope and so `__builtin_FUNCTION()` cannot be used here.
	 * Instead, we must pass this explicitly, typically as something like:
	 *
	 * ```c++
	 * StackUsageCheck<DebugFlag, 128, __PRETTY_FUNCTION__> stackCheck;
	 * ```
	 */
	template<StackCheckMode Mode, size_t Expected, DebugContext Fn>
	class StackUsageCheck
	{
		/**
		 * The expected maximum.  This class is templated on the function name
		 * and so there is one copy of this per function.
		 */
		static inline size_t stackUsage = Expected;

		public:
		/**
		 * Default constructor, does nothing.
		 */
		StackUsageCheck() = default;

		/**
		 * Destructor, runs at the end of the function to print the message.
		 */
		__always_inline ~StackUsageCheck()
		{
			if constexpr (Mode != StackCheckMode::Disabled)
			{
				ptraddr_t lowest = stack_lowest_used_address();
				ptraddr_t highest =
				  CHERI::Capability{__builtin_cheri_stack_get()}.top();
				size_t used = highest - lowest;
				if (used > stackUsage)
				{
					stackUsage = used;
					ConditionalDebug<true, Fn>::log("Stack used: {} bytes",
					                                stackUsage);
					if constexpr (Mode == StackCheckMode::Asserting)
					{
						__builtin_trap();
					}
				}
			}
		}
	};

} // namespace
