// 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;

	/* 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 = kunit_kmalloc(stream->test, sizeof(*frag_container),
				       stream->gfp);
	if (!frag_container)
		return -ENOMEM;

	frag_container->fragment = kunit_kmalloc(stream->test, len,
						 stream->gfp);
	if (!frag_container->fragment)
		return -ENOMEM;

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

	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;

	spin_lock(&stream->lock);
	list_for_each_entry_safe(frag_container,
				 frag_container_safe,
				 &stream->fragments,
				 node) {
		list_del(&frag_container->node);
	}
	stream->length = 0;
	spin_unlock(&stream->lock);
}

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;

	buf = kunit_kzalloc(stream->test, buf_len, stream->gfp);
	if (!buf)
		return NULL;

	spin_lock(&stream->lock);
	list_for_each_entry(frag_container, &stream->fragments, node)
		strlcat(buf, frag_container->fragment, buf_len);
	spin_unlock(&stream->lock);

	return buf;
}

int string_stream_append(struct string_stream *stream,
			 struct string_stream *other)
{
	const char *other_content;

	other_content = string_stream_get_string(other);

	if (!other_content)
		return -ENOMEM;

	return string_stream_add(stream, other_content);
}

bool string_stream_is_empty(struct string_stream *stream)
{
	return list_empty(&stream->fragments);
}

struct string_stream_alloc_context {
	struct kunit *test;
	gfp_t gfp;
};

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

	stream = kunit_kzalloc(ctx->test, sizeof(*stream), ctx->gfp);
	if (!stream)
		return -ENOMEM;

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

	return 0;
}

static void string_stream_free(struct kunit_resource *res)
{
	/* Nothing to do since everything is already a KUnit managed resource */
}

struct string_stream *alloc_string_stream(struct kunit *test, gfp_t gfp)
{
	struct string_stream_alloc_context context = {
		.test = test,
		.gfp = gfp
	};

	return kunit_alloc_resource(test,
				    string_stream_init,
				    string_stream_free,
				    gfp,
				    &context);
}
