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

int string_stream_vadd(struct string_stream *this,
		       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(&this->lock, flags);
	this->length += len;
	list_add_tail(&frag_container->node, &this->fragments);
	spin_unlock_irqrestore(&this->lock, flags);
	return 0;
}

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

	va_start(args, fmt);
	result = string_stream_vadd(this, fmt, args);
	va_end(args);
	return result;
}

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

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

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

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

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

	return buf;
}

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

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

	return is_empty;
}

void destroy_string_stream(struct string_stream *stream)
{
	string_stream_clear(stream);
	kfree(stream);
}

static void string_stream_destroy(struct kref *kref)
{
	struct string_stream *stream = container_of(kref,
						    struct string_stream,
						    refcount);
	destroy_string_stream(stream);
}

struct string_stream *new_string_stream(void)
{
	struct string_stream *stream = kzalloc(sizeof(*stream), GFP_KERNEL);

	if (!stream)
		return NULL;

	INIT_LIST_HEAD(&stream->fragments);
	spin_lock_init(&stream->lock);
	kref_init(&stream->refcount);
	return stream;
}

void string_stream_get(struct string_stream *stream)
{
	kref_get(&stream->refcount);
}

int string_stream_put(struct string_stream *stream)
{
	return kref_put(&stream->refcount, &string_stream_destroy);
}
