/* Ringbuffer implementation, tailored for logging.
 * This is a lossy ringbuffer. It keeps up to N of the newest messages,
 * overwriting the oldest as newer ones come in.
 *
 * (C) 2012-2013, Katerina Barone-Adesi <kat.obsc@gmail.com>
 * All Rights Reserved
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */

/*! \file strrb.c
 *  \brief Lossy string ringbuffer for logging; keeps newest messages.
 */

#include <stdio.h>
#include <string.h>
#include <strings.h>

#include <osmocom/core/strrb.h>

/* Ringbuffer assumptions, invarients, and notes:
 * - start is the index of the first used index slot in the ring buffer.
 * - end is the index of the next index slot in the ring buffer.
 * - start == end => buffer is empty
 * - Consequence: the buffer can hold at most size - 1 messages
 * (if this were not the case, full and empty buffers would be indistinguishable
 * given the conventions in this implementation).
 * - Whenever the ringbuffer is full, start is advanced. The second oldest
 * message becomes unreachable by valid indexes (end is not a valid index)
 * and the oldest message is overwritten (if there was a message there, which
 * is the case unless this is the first time the ringbuffer becomes full).
*/

/*! \brief Create an empty, initialized osmo_strrb.
 *  \param[in] ctx The talloc memory context which should own this.
 *  \param[in] rb_size The number of message slots the osmo_strrb can hold.
 *  \returns A struct osmo_strrb* on success, NULL in case of error.
 *
 * This function creates and initializes a ringbuffer.
 * Note that the ringbuffer stores at most rb_size - 1 messages.
 */

struct osmo_strrb *osmo_strrb_create(TALLOC_CTX * ctx, size_t rb_size)
{
	struct osmo_strrb *rb = NULL;
	unsigned int i;

	rb = talloc_zero(ctx, struct osmo_strrb);
	if (!rb)
		goto alloc_error;

	/* start and end are zero already, which is correct */
	rb->size = rb_size;

	rb->buffer = talloc_array(rb, char *, rb->size);
	if (!rb->buffer)
		goto alloc_error;
	for (i = 0; i < rb->size; i++) {
		rb->buffer[i] =
		    talloc_zero_size(rb->buffer, RB_MAX_MESSAGE_SIZE);
		if (!rb->buffer[i])
			goto alloc_error;
	}

	return rb;

alloc_error:			/* talloc_free(NULL) is safe */
	talloc_free(rb);
	return NULL;
}

/*! \brief Check if an osmo_strrb is empty.
 *  \param[in] rb The osmo_strrb to check.
 *  \returns True if the osmo_strrb is empty, false otherwise.
 */
bool osmo_strrb_is_empty(const struct osmo_strrb *rb)
{
	return rb->end == rb->start;
}

/*! \brief Return a pointer to the Nth string in the osmo_strrb.
 * \param[in] rb The osmo_strrb to search.
 * \param[in] string_index The index sought (N), zero-indexed.
 *
 * Return a pointer to the Nth string in the osmo_strrb.
 * Return NULL if there is no Nth string.
 * Note that N is zero-indexed.
 * \returns A pointer to the target string on success, NULL in case of error.
 */
const char *osmo_strrb_get_nth(const struct osmo_strrb *rb,
			       unsigned int string_index)
{
	unsigned int offset = string_index + rb->start;

	if ((offset >= rb->size) && (rb->start > rb->end))
		offset -= rb->size;
	if (_osmo_strrb_is_bufindex_valid(rb, offset))
		return rb->buffer[offset];

	return NULL;
}

bool _osmo_strrb_is_bufindex_valid(const struct osmo_strrb *rb,
				   unsigned int bufi)
{
	if (osmo_strrb_is_empty(rb))
		return 0;
	if ((bufi >= rb->size) || (bufi < 0))
		return 0;
	if (rb->start < rb->end)
		return (bufi >= rb->start) && (bufi < rb->end);
	return (bufi < rb->end) || (bufi >= rb->start);
}

/*! \brief Count the number of log messages in an osmo_strrb.
 *  \param[in] rb The osmo_strrb to count the elements of.
 *
 *  \returns The number of log messages in the osmo_strrb.
 */
size_t osmo_strrb_elements(const struct osmo_strrb *rb)
{
	if (rb->end < rb->start)
		return rb->end + (rb->size - rb->start);

	return rb->end - rb->start;
}

/*! \brief Add a string to the osmo_strrb.
 * \param[in] rb The osmo_strrb to add to.
 * \param[in] data The string to add.
 *
 * Add a message to the osmo_strrb.
 * Older messages will be overwritten as necessary.
 * \returns 0 normally, 1 as a warning (ie, if data was truncated).
 */
int osmo_strrb_add(struct osmo_strrb *rb, const char *data)
{
	size_t len = strlen(data);
	int ret = 0;

	if (len >= RB_MAX_MESSAGE_SIZE) {
		len = RB_MAX_MESSAGE_SIZE - 1;
		ret = 1;
	}

	memcpy(rb->buffer[rb->end], data, len);
	rb->buffer[rb->end][len] = '\0';

	rb->end += 1;
	rb->end %= rb->size;

	/* The buffer is full; oldest message is forgotten - see notes above */
	if (rb->end == rb->start) {
		rb->start += 1;
		rb->start %= rb->size;
	}
	return ret;
}
