/**
 * Copyright © 2017 IBM Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#include "console-server.h"

static inline size_t min(size_t a, size_t b)
{
	return a < b ? a : b;
}

struct ringbuffer *ringbuffer_init(size_t size)
{
	struct ringbuffer *rb;

	rb = malloc(sizeof(*rb) + size);
	if (!rb) {
		return NULL;
	}

	memset(rb, 0, sizeof(*rb));
	rb->size = size;
	rb->buf = (void *)(rb + 1);

	return rb;
}

void ringbuffer_fini(struct ringbuffer *rb)
{
	while (rb->n_consumers) {
		ringbuffer_consumer_unregister(rb->consumers[0]);
	}
	free(rb);
}

struct ringbuffer_consumer *
ringbuffer_consumer_register(struct ringbuffer *rb, ringbuffer_poll_fn_t fn,
			     void *data)
{
	struct ringbuffer_consumer *rbc;
	int n;

	rbc = malloc(sizeof(*rbc));
	rbc->rb = rb;
	rbc->poll_fn = fn;
	rbc->poll_data = data;
	rbc->pos = rb->tail;

	n = rb->n_consumers++;
	/*
	 * We're managing an array of pointers to aggregates, so don't warn about sizeof() on a
	 * pointer type.
	 */
	/* NOLINTBEGIN(bugprone-sizeof-expression) */
	rb->consumers = reallocarray(rb->consumers, rb->n_consumers,
				     sizeof(*rb->consumers));
	/* NOLINTEND(bugprone-sizeof-expression) */
	rb->consumers[n] = rbc;

	return rbc;
}

void ringbuffer_consumer_unregister(struct ringbuffer_consumer *rbc)
{
	struct ringbuffer *rb = rbc->rb;
	int i;

	for (i = 0; i < rb->n_consumers; i++) {
		if (rb->consumers[i] == rbc) {
			break;
		}
	}

	assert(i < rb->n_consumers);

	rb->n_consumers--;

	/*
	 * We're managing an array of pointers to aggregates, so don't warn about sizeof() on a
	 * pointer type.
	 */
	memmove(&rb->consumers[i], &rb->consumers[i + 1],
		/* NOLINTNEXTLINE(bugprone-sizeof-expression) */
		sizeof(*rb->consumers) * (rb->n_consumers - i));

	if (rb->n_consumers == 0) {
		free(rb->consumers);
		rb->consumers = NULL;
	} else {
		rb->consumers = reallocarray(
			rb->consumers, rb->n_consumers,
			/* NOLINTNEXTLINE(bugprone-sizeof-expression) */
			sizeof(*rb->consumers));
	}

	free(rbc);
}

size_t ringbuffer_len(struct ringbuffer_consumer *rbc)
{
	if (rbc->pos <= rbc->rb->tail) {
		return rbc->rb->tail - rbc->pos;
	}
	return rbc->rb->tail + rbc->rb->size - rbc->pos;
}

static size_t ringbuffer_space(struct ringbuffer_consumer *rbc)
{
	return rbc->rb->size - ringbuffer_len(rbc) - 1;
}

static int ringbuffer_consumer_ensure_space(struct ringbuffer_consumer *rbc,
					    size_t len)
{
	enum ringbuffer_poll_ret prc;
	size_t force_len;

	if (ringbuffer_space(rbc) >= len) {
		return 0;
	}

	force_len = len - ringbuffer_space(rbc);

	prc = rbc->poll_fn(rbc->poll_data, force_len);
	if (prc != RINGBUFFER_POLL_OK) {
		return -1;
	}

	return 0;
}

int ringbuffer_queue(struct ringbuffer *rb, uint8_t *data, size_t len)
{
	struct ringbuffer_consumer *rbc;
	size_t wlen;
	int i;
	int rc;

	if (len >= rb->size) {
		return -1;
	}

	if (len == 0) {
		return 0;
	}

	/* Ensure there is at least len bytes of space available.
	 *
	 * If a client doesn't have sufficient space, perform a blocking write
	 * (by calling ->poll_fn with force_len) to create it.
	 */
	for (i = 0; i < rb->n_consumers; i++) {
		rbc = rb->consumers[i];

		rc = ringbuffer_consumer_ensure_space(rbc, len);
		if (rc) {
			ringbuffer_consumer_unregister(rbc);
			i--;
			continue;
		}

		assert(ringbuffer_space(rbc) >= len);
	}

	/* Now that we know we have enough space, add new data to tail */
	wlen = min(len, rb->size - rb->tail);
	memcpy(rb->buf + rb->tail, data, wlen);
	rb->tail = (rb->tail + wlen) % rb->size;
	len -= wlen;
	data += wlen;

	memcpy(rb->buf, data, len);
	rb->tail += len;

	/* Inform consumers of new data in non-blocking mode, by calling
	 * ->poll_fn with 0 force_len */
	for (i = 0; i < rb->n_consumers; i++) {
		enum ringbuffer_poll_ret prc;

		rbc = rb->consumers[i];
		prc = rbc->poll_fn(rbc->poll_data, 0);
		if (prc == RINGBUFFER_POLL_REMOVE) {
			ringbuffer_consumer_unregister(rbc);
			i--;
		}
	}

	return 0;
}

size_t ringbuffer_dequeue_peek(struct ringbuffer_consumer *rbc, size_t offset,
			       uint8_t **data)
{
	struct ringbuffer *rb = rbc->rb;
	size_t pos;
	size_t len;

	if (offset >= ringbuffer_len(rbc)) {
		return 0;
	}

	pos = (rbc->pos + offset) % rb->size;
	if (pos <= rb->tail) {
		len = rb->tail - pos;
	} else {
		len = rb->size - pos;
	}

	*data = rb->buf + pos;
	return len;
}

int ringbuffer_dequeue_commit(struct ringbuffer_consumer *rbc, size_t len)
{
	assert(len <= ringbuffer_len(rbc));
	rbc->pos = (rbc->pos + len) % rbc->rb->size;
	return 0;
}
