/*
 * Buffering of output and input.
 * Copyright (C) 1998 Kunihiro Ishiguro
 *
 * This file is part of GNU Zebra.
 *
 * GNU Zebra 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 2, or (at your
 * option) any later version.
 *
 * GNU Zebra 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 GNU Zebra; see the file COPYING.  If not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stddef.h>
#include <sys/uio.h>

#include <osmocore/talloc.h>
#include <osmocom/vty/buffer.h>
#include <osmocom/vty/vty.h>

/* Buffer master. */
struct buffer {
	/* Data list. */
	struct buffer_data *head;
	struct buffer_data *tail;

	/* Size of each buffer_data chunk. */
	size_t size;
};

/* Data container. */
struct buffer_data {
	struct buffer_data *next;

	/* Location to add new data. */
	size_t cp;

	/* Pointer to data not yet flushed. */
	size_t sp;

	/* Actual data stream (variable length). */
	unsigned char data[0];	/* real dimension is buffer->size */
};

/* It should always be true that: 0 <= sp <= cp <= size */

/* Default buffer size (used if none specified).  It is rounded up to the
   next page boundery. */
#define BUFFER_SIZE_DEFAULT		4096

#define BUFFER_DATA_FREE(D) talloc_free((D))

/* Make new buffer. */
struct buffer *buffer_new(void *ctx, size_t size)
{
	struct buffer *b;

	b = talloc_zero(ctx, struct buffer);

	if (size)
		b->size = size;
	else {
		static size_t default_size;
		if (!default_size) {
			long pgsz = sysconf(_SC_PAGESIZE);
			default_size =
			    ((((BUFFER_SIZE_DEFAULT - 1) / pgsz) + 1) * pgsz);
		}
		b->size = default_size;
	}

	return b;
}

/* Free buffer. */
void buffer_free(struct buffer *b)
{
	buffer_reset(b);
	talloc_free(b);
}

/* Make string clone. */
char *buffer_getstr(struct buffer *b)
{
	size_t totlen = 0;
	struct buffer_data *data;
	char *s;
	char *p;

	for (data = b->head; data; data = data->next)
		totlen += data->cp - data->sp;
	if (!(s = _talloc_zero(tall_vty_ctx, (totlen + 1), "buffer_getstr")))
		return NULL;
	p = s;
	for (data = b->head; data; data = data->next) {
		memcpy(p, data->data + data->sp, data->cp - data->sp);
		p += data->cp - data->sp;
	}
	*p = '\0';
	return s;
}

/* Return 1 if buffer is empty. */
int buffer_empty(struct buffer *b)
{
	return (b->head == NULL);
}

/* Clear and free all allocated data. */
void buffer_reset(struct buffer *b)
{
	struct buffer_data *data;
	struct buffer_data *next;

	for (data = b->head; data; data = next) {
		next = data->next;
		BUFFER_DATA_FREE(data);
	}
	b->head = b->tail = NULL;
}

/* Add buffer_data to the end of buffer. */
static struct buffer_data *buffer_add(struct buffer *b)
{
	struct buffer_data *d;

	d = _talloc_zero(b,
			 offsetof(struct buffer_data, data[b->size]),
			 "buffer_add");
	if (!d)
		return NULL;
	d->cp = d->sp = 0;
	d->next = NULL;

	if (b->tail)
		b->tail->next = d;
	else
		b->head = d;
	b->tail = d;

	return d;
}

/* Write data to buffer. */
void buffer_put(struct buffer *b, const void *p, size_t size)
{
	struct buffer_data *data = b->tail;
	const char *ptr = p;

	/* We use even last one byte of data buffer. */
	while (size) {
		size_t chunk;

		/* If there is no data buffer add it. */
		if (data == NULL || data->cp == b->size)
			data = buffer_add(b);

		chunk =
		    ((size <=
		      (b->size - data->cp)) ? size : (b->size - data->cp));
		memcpy((data->data + data->cp), ptr, chunk);
		size -= chunk;
		ptr += chunk;
		data->cp += chunk;
	}
}

/* Insert character into the buffer. */
void buffer_putc(struct buffer *b, u_char c)
{
	buffer_put(b, &c, 1);
}

/* Put string to the buffer. */
void buffer_putstr(struct buffer *b, const char *c)
{
	buffer_put(b, c, strlen(c));
}

/* Keep flushing data to the fd until the buffer is empty or an error is
   encountered or the operation would block. */
buffer_status_t buffer_flush_all(struct buffer *b, int fd)
{
	buffer_status_t ret;
	struct buffer_data *head;
	size_t head_sp;

	if (!b->head)
		return BUFFER_EMPTY;
	head_sp = (head = b->head)->sp;
	/* Flush all data. */
	while ((ret = buffer_flush_available(b, fd)) == BUFFER_PENDING) {
		if ((b->head == head) && (head_sp == head->sp)
		    && (errno != EINTR))
			/* No data was flushed, so kernel buffer must be full. */
			return ret;
		head_sp = (head = b->head)->sp;
	}

	return ret;
}

#if 0
/* Flush enough data to fill a terminal window of the given scene (used only
   by vty telnet interface). */
buffer_status_t
buffer_flush_window(struct buffer * b, int fd, int width, int height,
		    int erase_flag, int no_more_flag)
{
	int nbytes;
	int iov_alloc;
	int iov_index;
	struct iovec *iov;
	struct iovec small_iov[3];
	char more[] = " --More-- ";
	char erase[] =
	    { 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
		' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
		0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08
	};
	struct buffer_data *data;
	int column;

	if (!b->head)
		return BUFFER_EMPTY;

	if (height < 1) {
		zlog_warn
		    ("%s called with non-positive window height %d, forcing to 1",
		     __func__, height);
		height = 1;
	} else if (height >= 2)
		height--;
	if (width < 1) {
		zlog_warn
		    ("%s called with non-positive window width %d, forcing to 1",
		     __func__, width);
		width = 1;
	}

	/* For erase and more data add two to b's buffer_data count. */
	if (b->head->next == NULL) {
		iov_alloc = sizeof(small_iov) / sizeof(small_iov[0]);
		iov = small_iov;
	} else {
		iov_alloc = ((height * (width + 2)) / b->size) + 10;
		iov = XMALLOC(MTYPE_TMP, iov_alloc * sizeof(*iov));
	}
	iov_index = 0;

	/* Previously print out is performed. */
	if (erase_flag) {
		iov[iov_index].iov_base = erase;
		iov[iov_index].iov_len = sizeof erase;
		iov_index++;
	}

	/* Output data. */
	column = 1;		/* Column position of next character displayed. */
	for (data = b->head; data && (height > 0); data = data->next) {
		size_t cp;

		cp = data->sp;
		while ((cp < data->cp) && (height > 0)) {
			/* Calculate lines remaining and column position after displaying
			   this character. */
			if (data->data[cp] == '\r')
				column = 1;
			else if ((data->data[cp] == '\n') || (column == width)) {
				column = 1;
				height--;
			} else
				column++;
			cp++;
		}
		iov[iov_index].iov_base = (char *)(data->data + data->sp);
		iov[iov_index++].iov_len = cp - data->sp;
		data->sp = cp;

		if (iov_index == iov_alloc)
			/* This should not ordinarily happen. */
		{
			iov_alloc *= 2;
			if (iov != small_iov) {
				zlog_warn("%s: growing iov array to %d; "
					  "width %d, height %d, size %lu",
					  __func__, iov_alloc, width, height,
					  (u_long) b->size);
				iov =
				    XREALLOC(MTYPE_TMP, iov,
					     iov_alloc * sizeof(*iov));
			} else {
				/* This should absolutely never occur. */
				zlog_err
				    ("%s: corruption detected: iov_small overflowed; "
				     "head %p, tail %p, head->next %p",
				     __func__, b->head, b->tail, b->head->next);
				iov =
				    XMALLOC(MTYPE_TMP,
					    iov_alloc * sizeof(*iov));
				memcpy(iov, small_iov, sizeof(small_iov));
			}
		}
	}

	/* In case of `more' display need. */
	if (b->tail && (b->tail->sp < b->tail->cp) && !no_more_flag) {
		iov[iov_index].iov_base = more;
		iov[iov_index].iov_len = sizeof more;
		iov_index++;
	}
#ifdef IOV_MAX
	/* IOV_MAX are normally defined in <sys/uio.h> , Posix.1g.
	   example: Solaris2.6 are defined IOV_MAX size at 16.     */
	{
		struct iovec *c_iov = iov;
		nbytes = 0;	/* Make sure it's initialized. */

		while (iov_index > 0) {
			int iov_size;

			iov_size =
			    ((iov_index > IOV_MAX) ? IOV_MAX : iov_index);
			if ((nbytes = writev(fd, c_iov, iov_size)) < 0) {
				zlog_warn("%s: writev to fd %d failed: %s",
					  __func__, fd, safe_strerror(errno));
				break;
			}

			/* move pointer io-vector */
			c_iov += iov_size;
			iov_index -= iov_size;
		}
	}
#else				/* IOV_MAX */
	if ((nbytes = writev(fd, iov, iov_index)) < 0)
		zlog_warn("%s: writev to fd %d failed: %s",
			  __func__, fd, safe_strerror(errno));
#endif				/* IOV_MAX */

	/* Free printed buffer data. */
	while (b->head && (b->head->sp == b->head->cp)) {
		struct buffer_data *del;
		if (!(b->head = (del = b->head)->next))
			b->tail = NULL;
		BUFFER_DATA_FREE(del);
	}

	if (iov != small_iov)
		XFREE(MTYPE_TMP, iov);

	return (nbytes < 0) ? BUFFER_ERROR :
	    (b->head ? BUFFER_PENDING : BUFFER_EMPTY);
}
#endif

/* This function (unlike other buffer_flush* functions above) is designed
to work with non-blocking sockets.  It does not attempt to write out
all of the queued data, just a "big" chunk.  It returns 0 if it was
able to empty out the buffers completely, 1 if more flushing is
required later, or -1 on a fatal write error. */
buffer_status_t buffer_flush_available(struct buffer * b, int fd)
{

/* These are just reasonable values to make sure a significant amount of
data is written.  There's no need to go crazy and try to write it all
in one shot. */
#ifdef IOV_MAX
#define MAX_CHUNKS ((IOV_MAX >= 16) ? 16 : IOV_MAX)
#else
#define MAX_CHUNKS 16
#endif
#define MAX_FLUSH 131072

	struct buffer_data *d;
	size_t written;
	struct iovec iov[MAX_CHUNKS];
	size_t iovcnt = 0;
	size_t nbyte = 0;

	for (d = b->head; d && (iovcnt < MAX_CHUNKS) && (nbyte < MAX_FLUSH);
	     d = d->next, iovcnt++) {
		iov[iovcnt].iov_base = d->data + d->sp;
		nbyte += (iov[iovcnt].iov_len = d->cp - d->sp);
	}

	if (!nbyte)
		/* No data to flush: should we issue a warning message? */
		return BUFFER_EMPTY;

	/* only place where written should be sign compared */
	if ((ssize_t) (written = writev(fd, iov, iovcnt)) < 0) {
		if (ERRNO_IO_RETRY(errno))
			/* Calling code should try again later. */
			return BUFFER_PENDING;
		return BUFFER_ERROR;
	}

	/* Free printed buffer data. */
	while (written > 0) {
		struct buffer_data *d;
		if (!(d = b->head))
			break;
		if (written < d->cp - d->sp) {
			d->sp += written;
			return BUFFER_PENDING;
		}

		written -= (d->cp - d->sp);
		if (!(b->head = d->next))
			b->tail = NULL;
		BUFFER_DATA_FREE(d);
	}

	return b->head ? BUFFER_PENDING : BUFFER_EMPTY;

#undef MAX_CHUNKS
#undef MAX_FLUSH
}

buffer_status_t
buffer_write(struct buffer * b, int fd, const void *p, size_t size)
{
	ssize_t nbytes;

#if 0
	/* Should we attempt to drain any previously buffered data?  This could help reduce latency in pushing out the data if we are stuck in a long-running thread that is preventing the main select loop from calling the flush thread... */

	if (b->head && (buffer_flush_available(b, fd) == BUFFER_ERROR))
		return BUFFER_ERROR;
#endif
	if (b->head)
		/* Buffer is not empty, so do not attempt to write the new data. */
		nbytes = 0;
	else if ((nbytes = write(fd, p, size)) < 0) {
		if (ERRNO_IO_RETRY(errno))
			nbytes = 0;
		else
			return BUFFER_ERROR;
	}
	/* Add any remaining data to the buffer. */
	{
		size_t written = nbytes;
		if (written < size)
			buffer_put(b, ((const char *)p) + written,
				   size - written);
	}
	return b->head ? BUFFER_PENDING : BUFFER_EMPTY;
}
