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

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

static const char *test_stream_get_level(struct test_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;
}

static void test_stream_set_level(struct test_stream *this, const char *level)
{
	unsigned long flags;

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

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

	va_start(args, fmt);
	if (stream->vadd(stream, fmt, args) < 0)
		test_err(this->test, "Failed to allocate fragment: %s", fmt);

	va_end(args);
}

static void test_stream_append(struct test_stream *this,
			       struct test_stream *other)
{
	struct string_stream *other_stream = other->internal_stream;
	const char *other_content;

	other_content = other_stream->get_string(other_stream);

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

	this->add(this, other_content);
}

static void test_stream_clear(struct test_stream *this)
{
	this->internal_stream->clear(this->internal_stream);
}

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

	level = test_stream_get_level(this);
	if (!level) {
		test_err(this->test,
			 "Stream was committed without a specified log level.");
		level = KERN_ERR;
		this->set_level(this, level);
	}

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

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

cleanup:
	this->clear(this);
}

static int test_stream_init(struct test_resource *res, void *context)
{
	struct test *test = context;
	struct test_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;

	stream->set_level = test_stream_set_level;
	stream->add = test_stream_add;
	stream->append = test_stream_append;
	stream->commit = test_stream_commit;
	stream->clear = test_stream_clear;

	return 0;
}

static void test_stream_free(struct test_resource *res)
{
	struct test_stream *stream = res->allocation;

	if (!stream->internal_stream->is_empty(stream->internal_stream)) {
		test_err(stream->test,
			 "End of test case reached with uncommitted stream entries.");
		stream->commit(stream);
	}

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

struct test_stream *test_new_stream(struct test *test)
{
	struct test_resource *res;

	res = test_alloc_resource(test,
				  test_stream_init,
				  test_stream_free,
				  test);

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