/*
 * Copyright (c) 2021 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @brief Generic double buffer data structure header.
 *
 * The structure may be used as a header for any kind of data structure that requires
 * double buffering.
 */
struct dbuf_hdr {
	/* The current element that is in use. */
	uint8_t volatile first;
	/* Last enqueued element. It will be used after buffer is swapped. */
	uint8_t last;
	/* Size in a bytes of a single element stored in double buffer. */
	uint8_t elem_size;
	/* Pointer for actual buffer memory. Its size should be 2 times @p elem_size. */
	uint8_t data[0];
};

/**
 * @brief Allocate element in double buffer.
 *
 * The function provides pointer to new element that may be modified by the user.
 * For consecutive calls it always returns the same pointer until buffer is swapped
 * by dbuf_latest_get operation.
 *
 * @param hdr Pointer to double buffer header.
 * @param idx Pointer to return new element index.
 *
 * @return Pointer to new element memory.
 */
void *dbuf_alloc(struct dbuf_hdr *hdr, uint8_t *idx);

/**
 * @brief Provides pointer to last allocated element.
 *
 * If it is called before dbuf_alloc it will return pointer to memory that was recently
 * enqueued.
 *
 * @param hdr Pointer to double buffer header.
 *
 * @return Pointer to last allocated element.
 */
static inline void *dbuf_peek(struct dbuf_hdr *hdr)
{
	return &hdr->data[hdr->last * hdr->elem_size];
}

/**
 * @brief  Enqueue new element for buffer swap.
 *
 * @param hdr Pointer to double buffer header.
 * @param idx Intex of element to be swapped.
 */
static inline void dbuf_enqueue(struct dbuf_hdr *hdr, uint8_t idx)
{
	hdr->last = idx;
}

/**
 * @brief Get latest element in buffer.
 *
 * Latest enqueued element is pointed by last member of dbuf_hdr.
 * If it points to a different index than member first, then buffer will be
 * swapped and @p is_modified will be set to true.
 *
 * Pointer to lates element is returned.
 *
 * @param[in] hdr Pointer to double buffer header.
 * @param[out] is_modifled Pointer to return information if buffer was swapped.
 *
 * @return Pointer to latest enqueued buffer element.
 */
void *dbuf_latest_get(struct dbuf_hdr *hdr, uint8_t *is_modified);

/**
 * @brief Retruns pointer to the current element, the one after last swap operation.
 *
 * The function provides access to element that is pointed by member first of dbuf_hrd.
 * Returned value always points to latest one, that was swapped after most recent call to
 * dbuf_latest_get. The pointer will be the same as the one pointed by last if the dbuf_alloc
 * is not called after last dbuf_latest_get call.
 *
 * @param hdr Pointer to double buffer header.

 * @return Pointer to element after last buffer swap.
 */
static inline void *dbuf_curr_get(struct dbuf_hdr *hdr)
{
	return &hdr->data[hdr->first * hdr->elem_size];
}

/**
 * @brief Return information whether new element was enqueued to a buffer.
 *
 * @param hdr Pointer to double buffer header.
 *
 * @return True if there were new element enqueued, false in other case.
 */
static inline bool dbuf_is_modified(const struct dbuf_hdr *hdr)
{
	return hdr->first != hdr->last;
}
