/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>

#include "dumper.h"

void dumpf(struct dumper *dumper, const char *format, ...)
{
	va_list ap;
	va_start(ap, format);
	dumper->vprintf(dumper, format, ap);
	va_end(ap);
}

/* dumper which outputs to syslog */

struct syslog_data {
	int priority;
	struct dumper *mem_dumper;
};

static void syslog_vprintf(struct dumper *dumper, const char *fmt, va_list ap)
{
	char *buf;
	int size, i;
	struct syslog_data *data = (struct syslog_data *)dumper->data;
	struct dumper *mem_dumper = data->mem_dumper;

	/* We cannot use syslog() directly each time we are called,
	 * because syslog() will always append a newline to the
	 * output, so the user will not be able to construct a line
	 * incrementally using multiple calls. What we do here is to
	 * collect the output in a buffer until a newline is given by
	 * the user. */

	mem_dumper->vprintf(mem_dumper, fmt, ap);
again:
	mem_dumper_get(mem_dumper, &buf, &size);
	for (i = 0; i < size; i++) {
		if (buf[i] == '\n') {
			syslog(data->priority, "%.*s", i + 1, buf);
			mem_dumper_consume(mem_dumper, i + 1);
			goto again;
		}
	}
}

struct dumper *syslog_dumper_create(int priority)
{
	struct dumper *dumper = calloc(1, sizeof(struct dumper));
	struct syslog_data *data = calloc(1, sizeof(struct syslog_data));
	data->priority = priority;
	data->mem_dumper = mem_dumper_create();
	dumper->data = data;
	dumper->vprintf = &syslog_vprintf;
	return dumper;
}

void syslog_dumper_free(struct dumper *dumper)
{
	mem_dumper_free(((struct syslog_data *)dumper->data)->mem_dumper);
	free(dumper->data);
	free(dumper);
}

/* dumper which outputs to a memory buffer */

struct mem_data {
	char *buf;
	int size;
	int capacity;
};

static void mem_vprintf(struct dumper *dumper, const char *format, va_list ap)
{
	int n;
	char *tmp;
	struct mem_data *data = (struct mem_data *)dumper->data;

	while (1) {
		/* try to use the remaining space */
		int remaining = data->capacity - data->size;
		n = vsnprintf(data->buf + data->size, remaining, format, ap);

		/* enough space? */
		if (n > -1 && n < remaining) {
			data->size += n;
			return;
		}

		/* allocate more space and try again */
		tmp = realloc(data->buf, data->capacity * 2);
		if (tmp == NULL)
			return;
		data->buf = tmp;
		data->capacity *= 2;
	}
}

struct dumper *mem_dumper_create()
{
	struct dumper *dumper = calloc(1, sizeof(struct dumper));
	struct mem_data *data = calloc(1, sizeof(struct mem_data));
	if (!dumper || !data)
		goto error;
	data->size = 0;
	data->capacity = 80;
	data->buf = malloc(data->capacity);
	if (!data->buf)
		goto error;
	data->buf[0] = '\0';
	dumper->data = data;
	dumper->vprintf = &mem_vprintf;
	return dumper;

error:
	if (dumper)
		free(dumper);
	if (data)
		free(data);
	return NULL;
}

void mem_dumper_free(struct dumper *dumper)
{
	struct mem_data *data = (struct mem_data *)dumper->data;
	free(data->buf);
	free(data);
	free(dumper);
}

void mem_dumper_clear(struct dumper *dumper)
{
	struct mem_data *data = (struct mem_data *)dumper->data;
	data->buf[0] = '\0';
	data->size = 0;
}

void mem_dumper_consume(struct dumper *dumper, int n)
{
	struct mem_data *data = (struct mem_data *)dumper->data;
	if (n > data->size)
		n = data->size;
	memmove(data->buf, data->buf + n, data->size - n + 1);
	data->size -= n;
}

void mem_dumper_get(struct dumper *dumper, char **buf, int *size)
{
	struct mem_data *data = (struct mem_data *)dumper->data;
	*buf = data->buf;
	*size = data->size;
}
