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

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

	va_start(args, fmt);

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

	va_end(args);
}

void kunit_stream_append(struct kunit_stream *kstream,
				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(kstream->test,
			  "Failed to get string from second argument for appending\n");
		return;
	}

	kunit_stream_add(kstream, other_content);
}

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

void kunit_stream_commit(struct kunit_stream *kstream)
{
	struct string_stream *stream = kstream->internal_stream;
	struct string_stream_fragment *fragment;
	struct kunit *test = kstream->test;
	char *buf;

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

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

cleanup:
	kunit_stream_clear(kstream);
}

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;
	stream->internal_stream = alloc_string_stream(test);

	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);
	}
}

struct kunit_stream *alloc_kunit_stream(struct kunit *test, const char *level)
{
	struct kunit_stream *kstream;
	struct kunit_resource *res;

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

	if (!res)
		return NULL;

	kstream = res->allocation;
	kstream->level = level;

	return kstream;
}
