#include <cheri.hh>
#include <cstdlib>
#include <errno.h>
#include <locks.hh>
#include <queue.h>
#include <stddef.h>
#include <stdint.h>
#include <timeout.h>
#include <type_traits>

using namespace CHERI;
using cheriot::atomic;

using Debug = ConditionalDebug<false, "Queue library">;

#ifdef __cplusplus
using MessageQueueCounter = atomic<uint32_t>;
#else
typedef uint32_t MessageQueueCounter;
#endif

#include <assembly-helpers.h>

namespace
{
	/**
	 * Helpers for the queue.  The queue uses two counters that wrap on double
	 * the number of elements.  This ensures that full and empty conditions
	 * have different values: a queue is full when the producer is one queue
	 * length ahead of the consumer, and empty when the producer and consumer
	 * are equal.
	 */

	/**
	 * Helper for wrapping increment.  Increments `counter`, wrapping to zero
	 * if it reaches double `size`.
	 */
	constexpr uint32_t increment_and_wrap(uint32_t size, uint32_t counter)
	{
		counter++;
		if (2 * size == counter)
		{
			return 0;
		}
		return counter;
	}

	/**
	 * Returns the number of items in the queue for the given size with the
	 * specified producer and consumer counters.
	 */
	constexpr uint32_t
	items_remaining(uint32_t size, uint32_t producer, uint32_t consumer)
	{
		// If the consumer is ahead of the producer then the producer has
		// wrapped.  In this case, treat the consumer as a negative offset
		if (consumer > producer)
		{
			return (2 * size) - consumer + producer;
		}
		return producer - consumer;
	}

	/**
	 * Returns true if and only if the `size`, `producer`, and `consumer`
	 * counters indicate a full queue.
	 */
	constexpr bool is_full(uint32_t size, uint32_t producer, uint32_t consumer)
	{
		return items_remaining(size, producer, consumer) == size;
	}

	/**
	 * Returns true if and only if the `producer`, and `consumer` counters
	 * indicate an empty queue.
	 */
	constexpr bool is_empty(uint32_t producer, uint32_t consumer)
	{
		return producer == consumer;
	}

	/**
	 * Helper that exhaustively checks the correctness of the is-full
	 * calculation for a size.
	 *
	 * This is purely constexpr logic for compile-time checks, it generates no
	 * code.
	 */
	template<uint32_t Size>
	struct CheckIsFull
	{
		/**
		 * Check that the template arguments return false for is-full.  This is
		 * a separate template so that we see the values in a compiler error.
		 */
		template<uint32_t Producer, uint32_t Consumer>
		static constexpr void check_not_full()
		{
			static_assert(!is_full(Size, Producer, Consumer),
			              "is-full calculation is incorrect");
		}

		/**
		 * Check that the template arguments return true for is-full.  This is a
		 * separate template so that we see the values in a compiler error.
		 */
		template<uint32_t Producer, uint32_t Consumer>
		static constexpr void check_full()
		{
			static_assert(is_full(Size, Producer, Consumer),
			              "is-full calculation is incorrect");
		}

		/**
		 * Helper that uses `increment_and_wrap` to add `displacement` to
		 * `start`, giving the value of a counter after `displacement`
		 * increments.
		 */
		static constexpr uint32_t add(uint32_t start, uint32_t displacement)
		{
			for (uint32_t i = 0; i < displacement; i++)
			{
				start = increment_and_wrap(Size, start);
			}
			return start;
		}

		/**
		 * Check that items-remaining returns the correct value for the given
		 * counter values.
		 */
		template<uint32_t Producer, uint32_t Consumer, uint32_t Displacement>
		static constexpr void check_items_remaining()
		{
			static_assert(items_remaining(Size, Producer, Consumer) ==
			                Displacement,
			              "items-remaining calculation is incorrect");
		}

		/**
		 * For every producer counter value from 0 up to `Size` after a consumer
		 * counter value, check that it returns the correct value for the
		 * items-remaining, is-empty, and is-full calculations.
		 */
		template<uint32_t Consumer, uint32_t Displacement = 0>
		static constexpr void check_offsets()
		{
			constexpr auto Producer = add(Consumer, Displacement);
			check_items_remaining<Producer, Consumer, Displacement>();
			if constexpr (Displacement == 0)
			{
				static_assert(is_empty(Producer, Consumer),
				              "is-empty calculation is incorrect");
			}
			else
			{
				static_assert(!is_empty(Producer, Consumer),
				              "is-empty calculation is incorrect");
			}
			if constexpr (Displacement == Size)
			{
				check_full<Producer, Consumer>();
			}
			else
			{
				static_assert(Displacement < Size,
				              "Displacement overflowed somehow");
				check_not_full<Producer, Consumer>();
				check_offsets<Consumer, Displacement + 1>();
			}
		}

		/**
		 * Check every valid consumer value for the given size, and every valid
		 * producer value for each consumer value.
		 */
		template<uint32_t Consumer = 0>
		static constexpr bool check_sizes()
		{
			check_offsets<Consumer>();
			if constexpr (Consumer < Size * 2)
			{
				check_sizes<Consumer + 1>();
			}
			return true;
		}

		static constexpr bool Value = check_sizes();
	};

	/**
	 * Helper.  This is never false, it is always either true or compile
	 * failure.
	 */
	template<uint32_t Size>
	constexpr bool CheckIsFullValue = CheckIsFull<Size>::Value;

	// Check some sizes that are likely to be wrong (powers of two, primes, and
	// some other values)
	static_assert(CheckIsFullValue<1>, "CheckIsFull failed");
	static_assert(CheckIsFullValue<3>, "CheckIsFull failed");
	static_assert(CheckIsFullValue<4>, "CheckIsFull failed");
	static_assert(CheckIsFullValue<10>, "CheckIsFull failed");
	static_assert(CheckIsFullValue<17>, "CheckIsFull failed");
	static_assert(CheckIsFullValue<32>, "CheckIsFull failed");
	static_assert(CheckIsFullValue<33>, "CheckIsFull failed");

	/**
	 * Returns a pointer to the element in the queue indicated by `counter`.
	 */
	Capability<void> buffer_at_counter(struct QueueHandle &handle,
	                                   uint32_t            counter)
	{
		// Handle wrap for the second run around the counter.
		size_t index =
		  counter >= handle.queueSize ? counter - handle.queueSize : counter;
		auto             offset = index * handle.elementSize;
		Capability<void> pointer{handle.buffer};
		pointer.address() += offset;
		return pointer;
	}

	/**
	 * Flag lock that uses the two high bits of a word for the lock.
	 *
	 * The remaining bits are free for other uses, but should not be modified
	 * while the lock is not held.
	 */
	struct HighBitFlagLock
	{
		/**
		 * A reference to the word that holds the lock.
		 */
		atomic<uint32_t> &lockWord;

		/**
		 * The bit to use for the lock.
		 */
		static constexpr uint32_t LockBit                 = 1U << 31;
		static constexpr uint32_t WaitersBit              = 1U << 30;
		static constexpr uint32_t LockedInDestructModeBit = 1U << 29;

		// Function required to conform to the Lock concept.
		void lock()
		{
			__builtin_unreachable();
		}

		static constexpr uint32_t reserved_bits()
		{
			return LockBit | WaitersBit | LockedInDestructModeBit;
		}

		/**
		 * Try to acquire the lock.  Returns true on success, false on failure.
		 */
		bool try_lock(Timeout *t)
		{
			uint32_t value;
			do
			{
				value = lockWord.load();
				if ((value & LockedInDestructModeBit) != 0)
				{
					return false;
				}
				if (value & LockBit)
				{
					// If the lock is held, set the flag that indicates that
					// there are waiters.
					if ((value & WaitersBit) == 0)
					{
						if (!lockWord.compare_exchange_strong(
						      value, value | WaitersBit))
						{
							continue;
						}
					}
					if (lockWord.wait(t, value) == -ETIMEDOUT)
					{
						return false;
					}
					continue;
				}
			} while (
			  !lockWord.compare_exchange_strong(value, (value | LockBit)));
			return true;
		}

		/**
		 * Release the lock.
		 */
		void unlock()
		{
			uint32_t value;
			// Clear the lock bit.
			value = lockWord.load();
			// If we're releasing the lock with waiters, wake them up.
			if (lockWord.exchange(value & ~LockBit) & WaitersBit)
			{
				lockWord.notify_all();
			}
		}

		/**
		 * Set the lock in destruction mode. This has the same
		 * semantics as `flaglock_upgrade_for_destruction`.
		 */
		void upgrade_for_destruction()
		{
			// Atomically set the destruction bit.
			lockWord |= LockedInDestructModeBit;
			if (lockWord & WaitersBit)
			{
				lockWord.notify_all();
			}
		}
	};

	uint32_t counter_load(std::atomic<uint32_t> *counter)
	{
		return counter->load() & ~(HighBitFlagLock::reserved_bits());
	}

	void counter_store(std::atomic<uint32_t> *counter, uint32_t value)
	{
		uint32_t old;
		do
		{
			old = counter->load();
		} while (!counter->compare_exchange_strong(
		  old, (old & HighBitFlagLock::reserved_bits()) | value));
	}

	/// Permissions for read-only access to a counter.
	static constexpr PermissionSet ReadOnly{Permission::Global,
	                                        Permission::Load};
	/// Permissions for read-only access to a buffer.
	static constexpr PermissionSet ReadOnlyCapability{
	  Permission::Global,
	  Permission::Load,
	  Permission::LoadStoreCapability,
	  Permission::LoadGlobal,
	  Permission::LoadGlobal};
	/// Permissions for write-only access to a buffer.
	static constexpr PermissionSet WriteOnlyCapability{
	  Permission::Global,
	  Permission::Store,
	  Permission::LoadStoreCapability};

	/**
	 * Helper to drop our short-lived claims.
	 */
	void drop_claims()
	{
		Timeout t{0};
		heap_claim_fast(&t, nullptr, nullptr);
	}

	void bound_queue_buffer(struct QueueHandle handle)
	{
		Capability buffer   = handle.buffer;
		Capability producer = handle.producer;
		// Restrict the bounds using the address of the producer, which
		// comes immediately after the queue buffer. This should be
		// strictly equivalent to calculating the size of the queue
		// from the number of elements and the size of elements (we
		// assert that below).
		buffer.bounds() = producer.address() - buffer.address();
		Debug::Assert(
		  [&]() -> bool {
			  size_t bufferSize;
			  bool   overflow = __builtin_mul_overflow(
			      handle.queueSize, handle.elementSize, &bufferSize);
			  bufferSize = CHERI::representable_length(bufferSize);
			  return (!overflow) && (buffer.bounds() == bufferSize);
		  },
		  "Mismatch between the size of the queue as reported by `queueSize` "
		  "and `elementSize` and its real size.");
	}

} // namespace

struct QueueHandle queue_make_receive_handle(struct QueueHandle handle)
{
	Capability buffer   = handle.buffer;
	Capability producer = handle.producer;
	bound_queue_buffer(handle);
	buffer.permissions() &= ReadOnlyCapability;
	producer.permissions() &= ReadOnly;
	handle.buffer   = buffer;
	handle.producer = producer;
	return handle;
}

struct QueueHandle queue_make_send_handle(struct QueueHandle handle)
{
	Capability buffer   = handle.buffer;
	Capability consumer = handle.consumer;
	bound_queue_buffer(handle);
	buffer.permissions() &= WriteOnlyCapability;
	consumer.permissions() &= ReadOnly;
	handle.buffer   = buffer;
	handle.consumer = consumer;
	return handle;
}

int queue_destroy(struct SObjStruct *heapCapability, struct QueueHandle *handle)
{
	int ret = 0;
	// Only upgrade the locks for destruction if we know that we will be
	// able to free the queue at the end. This will fail if passed a
	// restricted buffer, which will happen if `queue_destroy` is called on
	// a restricted queue.
	if (ret = heap_can_free(heapCapability, handle->buffer); ret != 0)
	{
		return ret;
	}

	auto           *producer = handle->producer;
	HighBitFlagLock producerLock{*producer};
	producerLock.upgrade_for_destruction();

	auto           *consumer = handle->consumer;
	HighBitFlagLock consumerLock{*consumer};
	consumerLock.upgrade_for_destruction();

	// This should not fail because of the `heap_can_free` check, unless we
	// run out of stack.
	if (ret = heap_free(heapCapability, handle->buffer); ret != 0)
	{
		return ret;
	}

	return ret;
}

int queue_create(Timeout            *timeout,
                 struct SObjStruct  *heapCapability,
                 struct QueueHandle *outQueue,
                 void              **outAllocation,
                 size_t              elementSize,
                 size_t              elementCount)
{
	size_t bufferSize;
	size_t allocSize;
	bool   overflow =
	  __builtin_mul_overflow(elementCount, elementSize, &bufferSize);
	// We must be able to accurately represent the buffer, so round it up to a
	// representable length.
	bufferSize = CHERI::representable_length(bufferSize);
	static constexpr size_t CounterSize = sizeof(uint32_t);
	// Round up the size to be correctly aligned for the counters at the end
	// (if necessary) and add two counters worth of space.
	overflow |= __builtin_add_overflow(
	  bufferSize,
	  (2 * CounterSize) + (CounterSize - (bufferSize & (CounterSize - 1))),
	  &allocSize);
	if (overflow)
	{
		return -EINVAL;
	}
	// We need the counters to be able to run to double the queue size without
	// hitting the high bits.  Error if this is the case.
	//
	// This should never be reached: a queue needs to be at least 256 MiB
	// (assuming one-byte elements) to hit this limit.
	if (((elementCount | (elementCount * 2)) &
	     HighBitFlagLock::reserved_bits()) != 0)
	{
		return -EINVAL;
	}

	// Allocate the space for the queue.
	Capability buffer{heap_allocate(timeout, heapCapability, allocSize)};
	if (!buffer.is_valid())
	{
		return -ENOMEM;
	}

	Capability<std::atomic<uint32_t>> producer{
	  buffer.cast<std::atomic<uint32_t>>()};
	Capability<std::atomic<uint32_t>> consumer{
	  buffer.cast<std::atomic<uint32_t>>()};
	// Make the producer and consumer point after the buffer
	producer.address() += bufferSize;
	consumer.address() += bufferSize + CounterSize;
	// Set their bounds to 4 bytes.
	producer.bounds() = CounterSize;
	consumer.bounds() = CounterSize;
	// The pointer used to free the allocation
	*outAllocation = buffer;
	Debug::log("Created queue with buffer: {}", buffer);
	// The handle
	*outQueue = {elementSize, elementCount, buffer, producer, consumer};

	return 0;
}

int queue_send(Timeout *timeout, struct QueueHandle *handle, const void *src)
{
	Debug::log("Send called on: {}", handle);
	auto *producer   = handle->producer;
	auto *consumer   = handle->consumer;
	bool  shouldWake = false;
	{
		Debug::log("Lock word: {}", producer->load());
		HighBitFlagLock l{*producer};
		if (LockGuard g{l, timeout})
		{
			uint32_t producerCounter = counter_load(producer);
			uint32_t consumerValue   = consumer->load();
			uint32_t consumerCounter =
			  consumerValue & ~(HighBitFlagLock::reserved_bits());
			Debug::log("Producer counter: {}, consumer counter: {}, Size: {}",
			           producerCounter,
			           consumerCounter,
			           handle->queueSize);
			while (is_full(handle->queueSize, producerCounter, consumerCounter))
			{
				// Wait on the value to change.  If we hit this path while the
				// consumer lock is held, then the high bits will be set.  Make
				// sure that we yield.
				if (consumer->wait(timeout, consumerValue) == -ETIMEDOUT)
				{
					Debug::log("Timed out on futex");
					return -ETIMEDOUT;
				}
				consumerValue = consumer->load();
				consumerCounter =
				  consumerValue & ~(HighBitFlagLock::reserved_bits());
			}
			auto entry = buffer_at_counter(*handle, producerCounter);
			if (int claim = heap_claim_fast(timeout, handle->buffer, src);
			    claim != 0)
			{
				Debug::log("Claim failed: {}", claim);
				return claim;
			}
			if (!check_pointer<PermissionSet{Permission::Load}, false>(
			      src, handle->elementSize))
			{
				drop_claims();
				Debug::log("Load / bounds check failed: {}");
				return -EPERM;
			}
			Debug::log("Send copying {} bytes from {} to {}",
			           handle->elementSize,
			           src,
			           entry);
			memcpy(entry, src, handle->elementSize);
			drop_claims();
			counter_store(
			  handle->producer,
			  increment_and_wrap(handle->queueSize, producerCounter));
			// Check if the queue was empty before we updated the producer
			// counter.  By the time that we reach this point, anything on the
			// consumer side will be on the path to a futex_wait with the old
			// version of the producer counter and so will bounce out again.
			shouldWake = is_empty(producerCounter, counter_load(consumer));
		}
		else
		{
			Debug::log("Timed out on lock");
			return -ETIMEDOUT;
		}
	}
	if (shouldWake)
	{
		handle->producer->notify_all();
	}
	return 0;
}

int queue_receive(Timeout *timeout, struct QueueHandle *handle, void *dst)
{
	Debug::log("Receive called on: {}", handle);
	auto *producer   = handle->producer;
	auto *consumer   = handle->consumer;
	bool  shouldWake = false;
	{
		HighBitFlagLock l{*consumer};
		if (LockGuard g{l, timeout})
		{
			uint32_t producerValue = producer->load();
			uint32_t producerCounter =
			  producerValue & ~(HighBitFlagLock::reserved_bits());
			uint32_t consumerCounter = counter_load(consumer);
			Debug::log("Producer counter: {}, consumer counter: {}, Size: {}",
			           producerCounter,
			           consumerCounter,
			           handle->queueSize);
			while (is_empty(producerCounter, consumerCounter))
			{
				// Wait on the value to change.  If we hit this path while the
				// producer lock is held, then the high bits will be set.  Make
				// sure that we yield.
				if (producer->wait(timeout, producerValue) == -ETIMEDOUT)
				{
					return -ETIMEDOUT;
				}
				producerValue = producer->load();
				producerCounter =
				  producerValue & ~(HighBitFlagLock::reserved_bits());
			}
			auto entry = buffer_at_counter(*handle, consumerCounter);
			if (int claim = heap_claim_fast(timeout, handle->buffer, dst);
			    claim != 0)
			{
				return claim;
			}
			if (!check_pointer<PermissionSet{Permission::Store}, false>(
			      dst, handle->elementSize))
			{
				drop_claims();
				Debug::log("Check pointer failed with {} for {} byte write",
				           dst,
				           handle->elementSize);
				return -EPERM;
			}
			Debug::log("Receive copying {} bytes from {} to {}",
			           handle->elementSize,
			           entry,
			           dst);
			memcpy(dst, entry, handle->elementSize);
			drop_claims();
			counter_store(
			  consumer, increment_and_wrap(handle->queueSize, consumerCounter));
			// Check if the queue was full before we updated the consumer
			// counter.  By the time that we reach this point, anything on the
			// producer side will be on the path to a futex_wait with the old
			// version of the consumer counter and so will bounce out again.
			shouldWake = is_full(
			  handle->queueSize, counter_load(producer), consumerCounter);
		}
		else
		{
			Debug::log("Timed out on lock");
			return -ETIMEDOUT;
		}
	}
	if (shouldWake)
	{
		handle->consumer->notify_all();
	}
	return 0;
}

int queue_items_remaining(struct QueueHandle *handle, size_t *items)
{
	auto producerCounter = counter_load(handle->producer);
	auto consumerCounter = counter_load(handle->consumer);
	*items =
	  items_remaining(handle->queueSize, producerCounter, consumerCounter);
	Debug::log("Producer counter: {}, consumer counter: {}, items: {}",
	           producerCounter,
	           consumerCounter,
	           *items);
	return 0;
}

void multiwaiter_queue_send_init(struct EventWaiterSource *source,
                                 struct QueueHandle       *handle)
{
	uint32_t producer   = counter_load(handle->producer);
	uint32_t consumer   = counter_load(handle->consumer);
	source->eventSource = handle->consumer;
	source->value =
	  is_full(handle->queueSize, producer, consumer) ? consumer : -1;
}

void multiwaiter_queue_receive_init(struct EventWaiterSource *source,
                                    struct QueueHandle       *handle)
{
	uint32_t producer   = counter_load(handle->producer);
	uint32_t consumer   = counter_load(handle->consumer);
	source->eventSource = handle->producer;
	source->value       = is_empty(producer, consumer) ? producer : -1;
}
