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

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

const char *kunit_stream_get_level(struct kunit_stream *this)
{
	unsigned long flags;
	const char *level;

	spin_lock_irqsave(&this->lock, flags);
	level = this->level;
	spin_unlock_irqrestore(&this->lock, flags);

	return level;
}

void kunit_stream_set_level(struct kunit_stream *this, const char *level)
{
	unsigned long flags;

	spin_lock_irqsave(&this->lock, flags);
	this->level = level;
	spin_unlock_irqrestore(&this->lock, flags);
}

void kunit_stream_add(struct kunit_stream *this, const char *fmt, ...)
{
	va_list args;
	struct string_stream *stream = this->internal_stream;

	va_start(args, fmt);

	if (string_stream_vadd(stream, fmt, args) < 0)
		kunit_err(this->test, "Failed to allocate fragment: %s\n", fmt);

	va_end(args);
}

void kunit_stream_append(struct kunit_stream *this,
				struct kunit_stream *other)
{
	struct string_stream *other_stream = other->internal_stream;
	const char *other_content;

	other_content = string_stream_get_string(other_stream);

	if (!other_content) {
		kunit_err(this->test,
			  "Failed to get string from second argument for appending.\n");
		return;
	}

	kunit_stream_add(this, other_content);
}

void kunit_stream_clear(struct kunit_stream *this)
{
	string_stream_clear(this->internal_stream);
}

void kunit_stream_commit(struct kunit_stream *this)
{
	struct string_stream *stream = this->internal_stream;
	struct string_stream_fragment *fragment;
	const char *level;
	char *buf;

	level = kunit_stream_get_level(this);
	if (!level) {
		kunit_err(this->test,
			  "Stream was committed without a specified log level.\n");
		level = KERN_ERR;
		kunit_stream_set_level(this, level);
	}

	buf = string_stream_get_string(stream);
	if (!buf) {
		kunit_err(this->test,
			 "Could not allocate buffer, dumping stream:\n");
		list_for_each_entry(fragment, &stream->fragments, node) {
			kunit_err(this->test, fragment->fragment);
		}
		kunit_err(this->test, "\n");
		goto cleanup;
	}

	kunit_printk(level, this->test, buf);
	kfree(buf);

cleanup:
	kunit_stream_clear(this);
}

static int kunit_stream_init(struct kunit_resource *res, void *context)
{
	struct kunit *test = context;
	struct kunit_stream *stream;

	stream = kzalloc(sizeof(*stream), GFP_KERNEL);
	if (!stream)
		return -ENOMEM;
	res->allocation = stream;
	stream->test = test;
	spin_lock_init(&stream->lock);
	stream->internal_stream = new_string_stream();

	if (!stream->internal_stream)
		return -ENOMEM;

	return 0;
}

static void kunit_stream_free(struct kunit_resource *res)
{
	struct kunit_stream *stream = res->allocation;

	if (!string_stream_is_empty(stream->internal_stream)) {
		kunit_err(stream->test,
			 "End of test case reached with uncommitted stream entries.\n");
		kunit_stream_commit(stream);
	}

	destroy_string_stream(stream->internal_stream);
	kfree(stream);
}

struct kunit_stream *kunit_new_stream(struct kunit *test)
{
	struct kunit_resource *res;

	res = kunit_alloc_resource(test,
				   kunit_stream_init,
				   kunit_stream_free,
				   test);

	if (res)
		return res->allocation;
	else
		return NULL;
}
