#include <cheri.hh>
#include <compartment.h>
#include <cstdlib>
#include <errno.h>
#include <locks.hh>
#include <queue.h>
#include <token.h>

using namespace CHERI;

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

namespace
{
	__always_inline SKey receive_key()
	{
		return STATIC_SEALING_TYPE(ReceiveHandle);
	}
	__always_inline SKey send_key()
	{
		return STATIC_SEALING_TYPE(SendHandle);
	}

	struct QueueEndpoint
	{
		QueueHandle handle;
		void       *allocation;
		// Lock that protects against double free.
		FlagLockPriorityInherited lock;
	};

} // namespace

int queue_create_sealed(Timeout            *timeout,
                        struct SObjStruct  *heapCapability,
                        struct SObjStruct **outQueueSend,
                        struct SObjStruct **outQueueReceive,
                        size_t              elementSize,
                        size_t              elementCount)
{
	if (!check_timeout_pointer(timeout))
	{
		return -EPERM;
	}

	// Allocate the queue endpoints
	auto [send, sendSealed] =
	  token_allocate<QueueEndpoint>(timeout, heapCapability, send_key());
	if (!send)
	{
		return timeout->may_block() ? -ENOMEM : -ETIMEDOUT;
	}
	auto [receive, receiveSealed] =
	  token_allocate<QueueEndpoint>(timeout, heapCapability, receive_key());
	if (!receive)
	{
		token_obj_destroy(heapCapability, send_key(), sendSealed);
		return timeout->may_block() ? -ENOMEM : -ETIMEDOUT;
	}

	// Bidirectional queue handle
	QueueHandle handle;
	// The pointer to the queue that is used when freeing
	void *freeBuffer;
	// Allocate the queue object
	int ret = queue_create(
	  timeout, heapCapability, &handle, &freeBuffer, elementSize, elementCount);
	if (ret != 0)
	{
		token_obj_destroy(heapCapability, send_key(), sendSealed);
		token_obj_destroy(heapCapability, receive_key(), receiveSealed);
		return ret;
	}

	send->handle        = queue_make_send_handle(handle);
	send->allocation    = freeBuffer;
	receive->handle     = queue_make_receive_handle(handle);
	receive->allocation = freeBuffer;
	// Add a second claim on the buffer so that we can free the queue by freeing
	// it twice, once in each endpoint.
	heap_claim(heapCapability, freeBuffer);

	if (int claimed = heap_claim_fast(timeout, outQueueSend, outQueueReceive);
	    claimed != 0)
	{
		return claimed;
	}
	if (!check_pointer<PermissionSet{Permission::Load,
	                                 Permission::Store,
	                                 Permission::LoadStoreCapability}>(
	      outQueueReceive, sizeof(void *)) ||
	    !check_pointer<PermissionSet{Permission::Load,
	                                 Permission::Store,
	                                 Permission::LoadStoreCapability}>(
	      outQueueSend, sizeof(void *)))
	{
		// Free twice because we claimed it once in addition to the original
		// allocation.
		heap_free(heapCapability, freeBuffer);
		heap_free(heapCapability, freeBuffer);
		return -EPERM;
	}
	*outQueueSend    = sendSealed;
	*outQueueReceive = receiveSealed;
	return 0;
}

int queue_destroy_sealed(Timeout           *timeout,
                         struct SObjStruct *heapCapability,
                         struct SObjStruct *queueHandle)
{
	if (!check_timeout_pointer(timeout))
	{
		return -EPERM;
	}
	Debug::log("Destroying queue {}", queueHandle);
	auto  token = receive_key();
	auto *end   = token_unseal(token, Sealed<QueueEndpoint>{queueHandle});
	// This function takes either endpoint, so we need to try unsealing with
	// both keys.
	if (!end)
	{
		token = send_key();
		end   = token_unseal(token, Sealed<QueueEndpoint>{queueHandle});
	}
	if (!end)
	{
		return -EINVAL;
	}
	// Don't bother with a lock guard: we will destroy this lock if we reach the
	// end. If we lose a race here, this will trap and we will implicitly return
	// `-ECOMPARTMENTFAIL`.
	if (!end->lock.try_lock(timeout))
	{
		return -ETIMEDOUT;
	}
	if (heap_free(heapCapability, end->allocation) != 0)
	{
		end->lock.unlock();
		return -EPERM;
	}
	token_obj_destroy(heapCapability, token, queueHandle);
	return 0;
}

int queue_send_sealed(Timeout           *timeout,
                      struct SObjStruct *handle,
                      const void        *src)
{
	auto *end = token_unseal(send_key(), Sealed<QueueEndpoint>{handle});
	// If we failed to unseal, or if the timeout pointer is invalid, invalid
	// argument error.
	if (!end || !check_timeout_pointer(timeout))
	{
		return -EINVAL;
	}
	return queue_send(timeout, &end->handle, src);
}

int queue_receive_sealed(Timeout *timeout, struct SObjStruct *handle, void *dst)
{
	auto *end = token_unseal(receive_key(), Sealed<QueueEndpoint>{handle});
	// If we failed to unseal, or if the timeout is on the heap, invalid
	// argument error.
	if (!end || !check_timeout_pointer(timeout))
	{
		return -EINVAL;
	}
	return queue_receive(timeout, &end->handle, dst);
}

int multiwaiter_queue_receive_init_sealed(struct EventWaiterSource *source,
                                          struct SObjStruct        *handle)
{
	auto *end = token_unseal(receive_key(), Sealed<QueueEndpoint>{handle});
	if (!end)
	{
		return -EINVAL;
	}
	multiwaiter_queue_receive_init(source, &end->handle);
	return 0;
}

int multiwaiter_queue_send_init_sealed(struct EventWaiterSource *source,
                                       struct SObjStruct        *handle)
{
	auto *end = token_unseal(send_key(), Sealed<QueueEndpoint>{handle});
	if (!end)
	{
		return -EINVAL;
	}
	multiwaiter_queue_send_init(source, &end->handle);
	return 0;
}

int queue_items_remaining_sealed(struct SObjStruct *queueHandle, size_t *items)
{
	auto *end = token_unseal(receive_key(), Sealed<QueueEndpoint>{queueHandle});
	// This function takes either endpoint, so we need to try unsealing with
	// both keys.
	if (!end)
	{
		end = token_unseal(send_key(), Sealed<QueueEndpoint>{queueHandle});
	}
	queue_items_remaining(&end->handle, items);
	return 0;
}
