// SPDX-License-Identifier: GPL-2.0
/*
 * C++ stream style string builder used in KUnit for building messages.
 *
 * Copyright (C) 2019, Google LLC.
 * Author: Brendan Higgins <brendanhiggins@google.com>
 */

#include <linux/list.h>
#include <linux/slab.h>
#include <kunit/string-stream.h>
#include <kunit/test.h>

int string_stream_vadd(struct string_stream *stream,
		       const char *fmt,
		       va_list args)
{
	struct string_stream_fragment *frag_container;
	int len;
	va_list args_for_counting;
	unsigned long flags;

	/* Make a copy because `vsnprintf` could change it */
	va_copy(args_for_counting, args);

	/* Need space for null byte. */
	len = vsnprintf(NULL, 0, fmt, args_for_counting) + 1;

	va_end(args_for_counting);

	frag_container = kmalloc(sizeof(*frag_container), GFP_KERNEL);
	if (!frag_container)
		return -ENOMEM;

	frag_container->fragment = kmalloc(len, GFP_KERNEL);
	if (!frag_container->fragment) {
		kfree(frag_container);
		return -ENOMEM;
	}

	len = vsnprintf(frag_container->fragment, len, fmt, args);
	spin_lock_irqsave(&stream->lock, flags);
	stream->length += len;
	list_add_tail(&frag_container->node, &stream->fragments);
	spin_unlock_irqrestore(&stream->lock, flags);

	return 0;
}

int string_stream_add(struct string_stream *stream, const char *fmt, ...)
{
	va_list args;
	int result;

	va_start(args, fmt);
	result = string_stream_vadd(stream, fmt, args);
	va_end(args);

	return result;
}

void string_stream_clear(struct string_stream *stream)
{
	struct string_stream_fragment *frag_container, *frag_container_safe;
	unsigned long flags;

	spin_lock_irqsave(&stream->lock, flags);
	list_for_each_entry_safe(frag_container,
				 frag_container_safe,
				 &stream->fragments,
				 node) {
		list_del(&frag_container->node);
		kfree(frag_container->fragment);
		kfree(frag_container);
	}
	stream->length = 0;
	spin_unlock_irqrestore(&stream->lock, flags);
}

char *string_stream_get_string(struct string_stream *stream)
{
	struct string_stream_fragment *frag_container;
	size_t buf_len = stream->length + 1; /* +1 for null byte. */
	char *buf;
	unsigned long flags;

	buf = kzalloc(buf_len, GFP_KERNEL);
	if (!buf)
		return NULL;

	spin_lock_irqsave(&stream->lock, flags);
	list_for_each_entry(frag_container, &stream->fragments, node)
		strlcat(buf, frag_container->fragment, buf_len);
	spin_unlock_irqrestore(&stream->lock, flags);

	return buf;
}

bool string_stream_is_empty(struct string_stream *stream)
{
	bool is_empty;
	unsigned long flags;

	spin_lock_irqsave(&stream->lock, flags);
	is_empty = list_empty(&stream->fragments);
	spin_unlock_irqrestore(&stream->lock, flags);

	return is_empty;
}

static int string_stream_init(struct kunit_resource *res, void *context)
{
	struct string_stream *stream;

	stream = kzalloc(sizeof(*stream), GFP_KERNEL);
	if (!stream)
		return -ENOMEM;

	res->allocation = stream;
	INIT_LIST_HEAD(&stream->fragments);
	spin_lock_init(&stream->lock);

	return 0;
}

static void string_stream_free(struct kunit_resource *res)
{
	struct string_stream *stream = res->allocation;

	string_stream_clear(stream);
	kfree(stream);
}

struct string_stream *alloc_string_stream(struct kunit *test)
{
	struct kunit_resource *res;

	res = kunit_alloc_resource(test,
				   string_stream_init,
				   string_stream_free,
				   NULL);

	if (!res)
		return NULL;

	return res->allocation;
}
