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

/**
 * @file A (circular) doubly linked list, abstracted over cons cell
 * representations.
 *
 * See `tests/list-test.cc` for additional information on how to use it.
 */

#pragma once

#include <concepts>
#include <ds/pointer.h>

namespace ds::linked_list
{

	namespace cell
	{
		/**
		 * The primitive, required, abstract interface to our cons cells.
		 *
		 * All methods are "namespaced" with `cell_` to support the case where
		 * the encoded forms are also representing other state (for example,
		 * bit-packed flags in pointer address bits).
		 */
		template<typename T>
		concept HasCellOperations = requires(T &t)
		{
			/** Proxies for list linkages */
			{
				t.cell_next()
				} -> ds::pointer::proxy::Proxies<T>;
			{
				t.cell_prev()
				} -> ds::pointer::proxy::Proxies<T>;
		};

		/**
		 * Reset a cell to a singleton ring.  Not all cons cells are required to
		 * be able to do this, though if you're sticking to rings and not
		 * (ab)using the machinery here in interesting ways, this should be easy
		 * to specify.
		 *
		 * This is a method, and not a constructor, to handle cases where the
		 * cell is also packing other state into its representation.
		 */
		template<typename T>
		concept HasReset = requires(T &t)
		{
			{
				t.cell_reset()
				} -> std::same_as<void>;
		};

		template<typename T>
		concept HasCellOperationsReset = HasCellOperations<T> && HasReset<T>;

		/**
		 * Additional, optional overrides available within implementation of
		 * cons cells.  It may be useful to static_assert() these in
		 * implementations to make sure we are not falling back to the defaults
		 * in terms of the above primops.
		 *
		 * @{
		 */
		template<typename T>
		concept HasIsSingleton = requires(T &t)
		{
			{
				t.cell_is_singleton()
				} -> std::same_as<bool>;
		};

		template<typename T>
		concept HasIsSingletonCheck = requires(T &t)
		{
			{
				t.cell_is_singleton_check()
				} -> std::same_as<bool>;
		};

		template<typename T>
		concept HasIsDoubleton = requires(T &t)
		{
			{
				t.cell_is_doubleton()
				} -> std::same_as<bool>;
		};

		/** @} */

	} // namespace cell

	/**
	 * Self-loops indicate either the sentinels of an empty list or,
	 * less often, singletons without their sentinels; it's up to
	 * the caller to know which is being tested for, here.
	 *
	 * The default implementation decodes and compares one link;
	 * implementations may have more efficient mechanisms.
	 *
	 * @{
	 */
	template<cell::HasCellOperations T>
	requires(!cell::HasIsSingleton<T>) __always_inline bool is_singleton(T *e)
	{
		return e == e->cell_prev();
	}

	template<cell::HasCellOperations T>
	requires(cell::HasIsSingleton<T>) __always_inline bool is_singleton(T *e)
	{
		return e->cell_is_singleton();
	}
	/** @} */

	/**
	 * Like is_singleton(), but checks both edges.  Useful only for
	 * testing invariants.
	 *
	 * The default implementation decodes and compares both links.
	 */
	template<cell::HasCellOperations T>
	requires(!cell::HasIsSingletonCheck<T>) __always_inline
	  bool is_singleton_check(T *e)
	{
		return (e == e->cell_next()) && (e == e->cell_prev());
	}

	template<cell::HasCellOperations T>
	requires(cell::HasIsSingletonCheck<T>) __always_inline
	  bool is_singleton_check(T *e)
	{
		return e->is_singleton_check();
	}
	/** @} */

	/**
	 * Doubletons are either singleton collections (with both the sentinel
	 * and the single element satisfying this test) or, less often, a pair
	 * of elements without a sentinel.  The caller is expected to know
	 * what's meant by this test.
	 *
	 * The default implementation decodes and compares both links.
	 * @{
	 */
	template<cell::HasCellOperations T>
	requires(!cell::HasIsDoubleton<T>) __always_inline bool is_doubleton(T *e)
	{
		return e->cell_prev() == e->cell_next();
	}

	template<cell::HasCellOperations T>
	requires(cell::HasIsDoubleton<T>) __always_inline bool is_doubleton(T *e)
	{
		return e->cell_is_doubleton();
	}
	/** @} */

	/**
	 * Verify linkage invariants.  Again, useful only for testing.
	 *
	 * The default implementation decodes all four relevant links.
	 */
	template<cell::HasCellOperations T>
	__always_inline bool is_well_formed(T *e)
	{
		return (e == e->cell_prev()->cell_next()) &&
		       (e == e->cell_next()->cell_prev());
	}

	/**
	 * Insert a ring of `elem`-ents (typically, a singleton ring) before the
	 * `curr`-ent element (or sentinel) in the ring.  In general, you will
	 * probably want to make sure that at most one of `elem` or `curr`
	 * points to a ring with a sentinel node.
	 *
	 * If `curr` is the sentinel, this is appending to the list, in the
	 * sense that the element(s) occupy (or span) the next-most and
	 * prev-least position from the sentinel.
	 *
	 * By symmetry, if `elem` is, instead, the sentinel, then `curr` is
	 * prepended to the list in the same sense.
	 */
	template<cell::HasCellOperations Cell>
	__always_inline void insert_before(Cell *curr, Cell *elem)
	{
		curr->cell_prev()->cell_next() = elem->cell_next();
		elem->cell_next()->cell_prev() = curr->cell_prev();
		curr->cell_prev()              = elem;
		elem->cell_next()              = curr;
	}

	/**
	 * Emplacement before.  This fuses initialization and insertion, so that
	 *
	 *    emplace_before(c, e);
	 *
	 * is semantically equivalent to
	 *
	 *    e->cell_reset(); insert_before(c, e);
	 *
	 * but spelled in a way that the compiler can understand a bit better, with
	 * less effort spent in provenance and/or alias analysis.
	 */
	template<cell::HasCellOperations Cell, typename P>
	requires std::same_as<P, Cell *> || ds::pointer::proxy::Proxies<P, Cell>
	  __always_inline void emplace_before(P curr, Cell *elem)
	{
		auto prev         = curr->cell_prev();
		elem->cell_next() = curr;
		elem->cell_prev() = prev;
		prev->cell_next() = elem;
		prev              = elem;
	}

	/**
	 * Emplacement after.  This fuses initialization and insertion, so that
	 *
	 *    emplace_after(c, e);
	 *
	 * is semantically equivalent to
	 *
	 *    e->cell_reset(); insert_before(e, c);
	 *
	 * but spelled in a way that the compiler can understand a bit better, with
	 * less effort spent in provenance and/or alias analysis.
	 */
	template<cell::HasCellOperations Cell, typename P>
	requires std::same_as<P, Cell *> || ds::pointer::proxy::Proxies<P, Cell>
	  __always_inline void emplace_after(P curr, Cell *elem)
	{
		auto next         = curr->cell_next();
		elem->cell_prev() = curr;
		elem->cell_next() = next;
		next->cell_prev() = elem;
		next              = elem;
	}

	/**
	 * Remove from the list without turning the removed span into a
	 * well-formed ring.  This is useful only if that invariant will be
	 * restored later (prior to insertion, at the very least).
	 *
	 * The removed element or span instead retains links into the ring
	 * whence it was removed, but is no longer well-formed, since that ring
	 * no longer references the removed element or span.
	 *
	 * This can be used to remove...
	 *
	 *   - a single element (`el == er`)
	 *
	 *   - the sentinel (`el == er`), leaving the rest of the ring, if any,
	 *     as a sentinel-free ring
	 *
	 *   - a span of elements from `el` to `er` via the `next` links; the
	 *     removed span is damaged and must be corrected, while the residual
	 *     ring remains well-formed.
	 *
	 * In all cases, `el`'s previous element is returned as a handle to the
	 * residual ring.
	 */
	template<cell::HasCellOperations Cell>
	__always_inline Cell *unsafe_remove(Cell *el, Cell *er)
	{
		auto p         = el->cell_prev();
		auto n         = er->cell_next();
		n->cell_prev() = p;
		p->cell_next() = n;
		return p;
	}

	template<cell::HasCellOperations Cell>
	__always_inline Cell *unsafe_remove(Cell *e)
	{
		return unsafe_remove(e, e);
	}

	/**
	 * Remove a particular element `rem` from the ring, already knowing its
	 * adjacent, previous link `prev`.  `prev` remains connected to the ring
	 * but `rem` will no longer be well-formed.  Returns a proxy to prev's
	 * next field.
	 */
	template<cell::HasCellOperations Cell>
	__always_inline auto unsafe_remove_link(Cell *prev, Cell *rem)
	{
		auto next         = rem->cell_next();
		auto prevnext     = prev->cell_next();
		prevnext          = next;
		next->cell_prev() = prev;
		return prevnext;
	}

	/**
	 * Remove from the ring, cleaving the ring into two well-formed rings.
	 *
	 * This can be used to remove...
	 *
	 *   - a single element (`el == er`)
	 *
	 *   - the sentinel (`el == er`), leaving the rest of the ring, if any,
	 *     as a sentinel-free collection
	 *
	 *   - a span of elements from `el` to `er` via `next` links; the
	 *     removed span is made into a ring and the residual ring is left
	 *     well-formed.
	 *
	 * In all cases, `el`'s previous element is returned as a handle to the
	 * residual ring.  (The caller must already have a reference to the span
	 * being removed).  This is especially useful when `remove`-ing elements
	 * during a `search`, below: overwriting the callback's Cell pointer
	 * (passed by *reference*) will continue the iteration, calling back at
	 * the removed node's successor.
	 *
	 * Removing a singleton from its ring from itself causes no change, as
	 * any would-be residual ring is empty.  This corner case requires some
	 * care on occasion.
	 */
	template<cell::HasCellOperations Cell>
	__always_inline Cell *remove(Cell *el, Cell *er)
	{
		Cell *p         = unsafe_remove(el, er);
		el->cell_prev() = er;
		er->cell_next() = el;
		return p;
	}

	template<cell::HasCellOperations Cell>
	__always_inline Cell *remove(Cell *e)
	{
		return remove(e, e);
	}

	/**
	 * Search through a span of a ring, inclusively from `from` through
	 * exclusively to `to`, applying `f` to each cons cell in turn.  If `f`
	 * returns `true`, the search stops early and returns `true`; otherwise,
	 * search returns `false`.  To (side-effectfully) visit every node in the
	 * span, have `f` always return false.
	 */
	template<cell::HasCellOperations Cell, typename F>
	__always_inline bool search(Cell *from, Cell *to, F f)
	{
		Cell *elem;
		for (elem = from; elem != to; elem = elem->cell_next())
		{
			if (f(elem))
			{
				return true;
			}
		}
		return false;
	}

	/**
	 * Search through all elements of a ring *except* `elem`.  If `elem` is the
	 * sentinel of a ring, then this is, as one expects, a `search` over all
	 * non-sentinel members of the ring.
	 */
	template<cell::HasCellOperations Cell, typename F>
	__always_inline bool search(Cell *elem, F f)
	{
		return search(static_cast<Cell *>(elem->cell_next()), elem, f);
	}

	/**
	 * Convenience wrapper for a sentinel cons cell, encapsulating some common
	 * patterns.
	 */
	template<cell::HasCellOperationsReset CellTemplateArg>
	struct Sentinel
	{
		using Cell = CellTemplateArg;

		/**
		 * The sentinel node itself.  Viewing the ring as a list, this
		 * effectively serves as pointers to the head (next) and to the tail
		 * (prev) of the list.  Unlike more traditional nullptr-terminated
		 * lists, though, here, the sentinel participates in the ring.
		 *
		 * This is marked `cheri_no_subobject_bounds` because some of our cons
		 * cell implementations use pointer proxies that rely on the bounds
		 * provided by `this` (which, in turn, is likely to be
		 * `cheri_no_subobject_bounds`)
		 */
		Cell sentinel __attribute__((__cheri_no_subobject_bounds__)) = {};

		__always_inline void reset()
		{
			sentinel.cell_reset();
		}

		__always_inline bool is_empty()
		{
			return linked_list::is_singleton(&sentinel);
		}

		__always_inline void append(Cell *elem)
		{
			linked_list::insert_before(&sentinel, elem);
		}

		__always_inline void append_emplace(Cell *elem)
		{
			linked_list::emplace_before(&sentinel, elem);
		}

		__always_inline void prepend(Cell *elem)
		{
			linked_list::insert_before(elem, &sentinel);
		}

		__always_inline Cell *first()
		{
			return sentinel.cell_next();
		}

		__always_inline Cell *last()
		{
			return sentinel.cell_prev();
		}

		__always_inline Cell *unsafe_take_first()
		{
			Cell *f = sentinel.cell_next();
			linked_list::unsafe_remove_link(&sentinel, f);
			return f;
		}

		__always_inline Cell *take_all()
		{
			auto p = linked_list::unsafe_remove(&sentinel);
			sentinel.cell_reset();
			return p;
		}

		template<typename F>
		__always_inline bool search(F f)
		{
			return linked_list::search(&sentinel, f);
		}
	};

	namespace cell
	{

		/** Cons cell using two pointers */
		class Pointer
		{
			Pointer *prev, *next;

			public:
			Pointer()
			{
				this->cell_reset();
			}

			__always_inline void cell_reset()
			{
				prev = next = this;
			}

			__always_inline auto cell_next()
			{
				return ds::pointer::proxy::Pointer(next);
			}

			__always_inline auto cell_prev()
			{
				return ds::pointer::proxy::Pointer(prev);
			}
		};
		static_assert(HasCellOperationsReset<Pointer>);

		/**
		 * Encode a linked list cons cell as a pair of addresses (but present an
		 * interface in terms of pointers).  CHERI bounds on the returned
		 * pointers are inherited from the pointer to `this` cons cell.
		 */
		class PtrAddr
		{
			ptraddr_t prev, next;

			public:
			PtrAddr()
			{
				this->cell_reset();
			}
			/* Primops */

			__always_inline void cell_reset()
			{
				prev = next = CHERI::Capability{this}.address();
			}

			__always_inline auto cell_next()
			{
				return ds::pointer::proxy::PtrAddr(this, next);
			}

			__always_inline auto cell_prev()
			{
				return ds::pointer::proxy::PtrAddr(this, prev);
			}

			/*
			 * Specialized implementations that may be slightly fewer
			 * instructions than the generic approaches in terms of the primops.
			 */

			__always_inline bool cell_is_singleton()
			{
				return prev == CHERI::Capability{this}.address();
			}

			__always_inline bool cell_is_doubleton()
			{
				return prev == next;
			}
		};
		static_assert(HasCellOperationsReset<PtrAddr>);
		static_assert(HasIsSingleton<PtrAddr>);
		static_assert(HasIsDoubleton<PtrAddr>);

		/**
		 * Encode a linked list cons cell as a pair of addresses (but present an
		 * interface in terms of pointers).  CHERI bounds on the returned
		 * pointers are inherited from the pointer to `this` cons cell.
		 */
		template<ptrdiff_t Offset>
		class OffsetPtrAddr
		{
			ptraddr_t prev, next;

			public:
			OffsetPtrAddr()
			{
				this->cell_reset();
			}

			/* Primops */

			__always_inline void cell_reset()
			{
				prev = next = CHERI::Capability{this}.address() - Offset;
			}

			__always_inline auto cell_next()
			{
				return ds::pointer::proxy::OffsetPtrAddr<Offset, OffsetPtrAddr>(
				  this, next);
			}

			__always_inline auto cell_prev()
			{
				return ds::pointer::proxy::OffsetPtrAddr<Offset, OffsetPtrAddr>(
				  this, prev);
			}

			/*
			 * Specialized implementations that may be slightly fewer
			 * instructions than the generic approaches in terms of the primops.
			 */

			__always_inline bool cell_is_singleton()
			{
				return prev == CHERI::Capability{this}.address() - Offset;
			}

			__always_inline bool cell_is_doubleton()
			{
				return prev == next;
			}
		};
		static_assert(HasCellOperationsReset<OffsetPtrAddr<0>>);
		static_assert(HasIsSingleton<OffsetPtrAddr<0>>);
		static_assert(HasIsDoubleton<OffsetPtrAddr<0>>);

	} // namespace cell

} // namespace ds::linked_list
