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

/**
 * @file Ring/circular buffer state machine.
 */

#pragma once

#include <cdefs.h>
#include <type_traits>

namespace ds::ring_buffer
{
	/**
	 * A statically-sized, non-atomic ring buffer state machine.  The actual
	 * element storage must be provided externally; all this does is manage the
	 * cursors.  This representation uses an explicit empty flag, rather than
	 * considering equal cursors to be empty, so as to not need an extra element
	 * of store Capacity-many items.
	 *
	 * The type of the cursors is parametric, but must be unsigned.
	 *
	 * The consumer workflow is:
	 *   - use head_get() to test emptiness and, if nonempty, read the index
	 *     of the head element
	 *   - make use of the element in the (external!) storage at that index
	 *   - call head_advance() to discard the head element
	 *
	 * The producer workflow is:
	 *   - use tail_next() to retrieve the index for the next element,
	 *     if there is room
	 *   - populate the element in the (external!) storage at that index
	 *   - call tail_advance() to make that element available to the
	 *     consumer
	 */
	template<typename Debug, std::size_t Capacity, typename IxTy = std::size_t>
	class Cursors
	{
		static_assert(std::is_arithmetic_v<IxTy> && std::is_unsigned_v<IxTy>,
		              "Ring buffer cursor type must be unsigned arithmetic");

		template<typename... Args>
		using Assert = typename Debug::template Assert<Args...>;

		public:
		using Ix = IxTy;

		private:
		Ix   head;
		Ix   tail;
		bool empty;

		Ix advance(Ix v)
		{
			if constexpr ((Capacity & (Capacity - 1)) == 0)
			{
				/* For power of two sizes, we can rely on bit masking. */
				return (v - 1) & (Capacity - 1);
			}
			else
			{
				/*
				 * For non-power-of-two, we can use unsigned underflow and
				 * signed arithmetic right shift to avoid branching.  mask is
				 * all zeros if next is non-negative and all ones otherwise.
				 */
				Ix next   = v - 1;
				using SIx = std::make_signed_t<Ix>;
				Ix mask   = static_cast<SIx>(next) >> (8 * sizeof(SIx) - 1);
				return (mask & (Capacity - 1)) | (~mask & next);
			}
		}

		public:
		/**
		 * Reset cursors to an empty state.
		 */
		void reset()
		{
			tail  = 0;
			head  = advance(tail);
			empty = true;
		}

		/**
		 * Is this ring empty?
		 */
		__always_inline bool is_empty()
		{
			return empty;
		}

		/**
		 * Try to retrieve the head index; returns true if available and
		 * false otherwise.
		 */
		bool head_get(Ix &v)
		{
			if (is_empty())
			{
				return false;
			}

			v = head;
			return true;
		}

		/**
		 * Retrieve the head index while bypassing the emptiness check.  The
		 * caller must have reason to believe that the ring is not empty.
		 */
		Ix head_get_unsafe()
		{
			return head;
		}

		/**
		 * Discard the element at the index returned by head_get().
		 *
		 * Do not call this unless there was a matching call to
		 * head_get() that has returned true.
		 */
		__always_inline void head_advance()
		{
			Assert<>(!empty, "Cannot advance head of empty ring buffer!");
			if (head == tail)
			{
				empty = true;
			}
			head = advance(head);
		}

		/**
		 * Try to retrieve the index of the tail, if nonempty.
		 */
		bool tail_get(Ix &v)
		{
			if (is_empty())
			{
				return false;
			}

			v = tail;
			return true;
		}

		/**
		 * Try to retrieve the index beyond the tail, if there is room.
		 * Returns true and sets the index if so, or returns false if
		 * not.
		 */

		bool tail_next(Ix &v)
		{
			Ix nt = advance(tail);
			if (!empty && head == nt)
			{
				return false;
			}

			v = nt;
			return true;
		}

		/**
		 * Make the next element available.
		 *
		 * Do not call this unless there was a matching call to
		 * tail_next() that returned true.
		 */
		__always_inline void tail_advance()
		{
			Assert<>(empty || head != advance(tail),
			         "Cannot advance tail of full ring buffer!");
			tail  = advance(tail);
			empty = false;
		}
	};
} // namespace ds::ring_buffer
