// SPDX-License-Identifier: GPL-2.0+
/*
 * Simple unit test library
 *
 * Copyright (c) 2013 Google, Inc
 */

#include <console.h>
#include <malloc.h>
#ifdef CONFIG_SANDBOX
#include <asm/state.h>
#endif
#include <asm/global_data.h>
#include <test/test.h>
#include <test/ut.h>

DECLARE_GLOBAL_DATA_PTR;

void ut_fail(struct unit_test_state *uts, const char *fname, int line,
	     const char *func, const char *cond)
{
	gd->flags &= ~(GD_FLG_SILENT | GD_FLG_RECORD);
	printf("%s:%d, %s(): %s\n", fname, line, func, cond);
	uts->cur.fail_count++;
}

void ut_failf(struct unit_test_state *uts, const char *fname, int line,
	      const char *func, const char *cond, const char *fmt, ...)
{
	va_list args;

	gd->flags &= ~(GD_FLG_SILENT | GD_FLG_RECORD);
	printf("%s:%d, %s(): %s: ", fname, line, func, cond);
	va_start(args, fmt);
	vprintf(fmt, args);
	va_end(args);
	putc('\n');
	uts->cur.fail_count++;
}

ulong ut_check_free(void)
{
	struct mallinfo info = mallinfo();

	return info.uordblks;
}

long ut_check_delta(ulong last)
{
	return ut_check_free() - last;
}

static int readline_check(struct unit_test_state *uts)
{
	int ret;

	ret = console_record_readline(uts->actual_str, sizeof(uts->actual_str));
	if (ret == -ENOSPC) {
		ut_fail(uts, __FILE__, __LINE__, __func__,
			"Console record buffer too small - increase CONFIG_CONSOLE_RECORD_OUT_SIZE");
		return ret;
	} else if (ret == -ENOENT) {
		strcpy(uts->actual_str, "<no-more-output>");
	}

	return ret;
}

int ut_check_console_line(struct unit_test_state *uts, const char *fmt, ...)
{
	va_list args;
	int len;
	int ret;

	va_start(args, fmt);
	len = vsnprintf(uts->expect_str, sizeof(uts->expect_str), fmt, args);
	va_end(args);
	if (len >= sizeof(uts->expect_str)) {
		ut_fail(uts, __FILE__, __LINE__, __func__,
			"unit_test_state->expect_str too small");
		return -EOVERFLOW;
	}
	ret = readline_check(uts);
	if (ret == -ENOENT)
		return 1;

	return strcmp(uts->expect_str, uts->actual_str);
}

int ut_check_console_linen(struct unit_test_state *uts, const char *fmt, ...)
{
	va_list args;
	int len;
	int ret;

	va_start(args, fmt);
	len = vsnprintf(uts->expect_str, sizeof(uts->expect_str), fmt, args);
	va_end(args);
	if (len >= sizeof(uts->expect_str)) {
		ut_fail(uts, __FILE__, __LINE__, __func__,
			"unit_test_state->expect_str too small");
		return -EOVERFLOW;
	}
	ret = readline_check(uts);
	if (ret < 0)
		return ret;

	return strncmp(uts->expect_str, uts->actual_str,
		       strlen(uts->expect_str));
}

int ut_check_skipline(struct unit_test_state *uts)
{
	int ret;

	if (!console_record_avail())
		return -ENFILE;
	ret = readline_check(uts);
	if (ret < 0)
		return ret;

	return 0;
}

int ut_check_skip_to_linen(struct unit_test_state *uts, const char *fmt, ...)
{
	va_list args;
	int len;
	int ret;

	va_start(args, fmt);
	len = vsnprintf(uts->expect_str, sizeof(uts->expect_str), fmt, args);
	va_end(args);
	if (len >= sizeof(uts->expect_str)) {
		ut_fail(uts, __FILE__, __LINE__, __func__,
			"unit_test_state->expect_str too small");
		return -EOVERFLOW;
	}
	while (1) {
		if (!console_record_avail())
			return -ENOENT;
		ret = readline_check(uts);
		if (ret < 0)
			return ret;

		if (!strncmp(uts->expect_str, uts->actual_str,
			     strlen(uts->expect_str)))
			return 0;
	}
}

int ut_check_skip_to_line(struct unit_test_state *uts, const char *fmt, ...)
{
	va_list args;
	int len;
	int ret;

	va_start(args, fmt);
	len = vsnprintf(uts->expect_str, sizeof(uts->expect_str), fmt, args);
	va_end(args);
	if (len >= sizeof(uts->expect_str)) {
		ut_fail(uts, __FILE__, __LINE__, __func__,
			"unit_test_state->expect_str too small");
		return -EOVERFLOW;
	}
	while (1) {
		if (!console_record_avail())
			return -ENOENT;
		ret = readline_check(uts);
		if (ret < 0)
			return ret;

		if (!strcmp(uts->expect_str, uts->actual_str))
			return 0;
	}
}

int ut_check_console_end(struct unit_test_state *uts)
{
	int ret;

	if (!console_record_avail())
		return 0;
	ret = readline_check(uts);
	if (ret < 0)
		return ret;

	return 1;
}

int ut_check_console_dump(struct unit_test_state *uts, int total_bytes)
{
	char *str = uts->actual_str;
	int upto;

	/* Handle empty dump */
	if (!total_bytes)
		return 0;

	for (upto = 0; upto < total_bytes;) {
		int len;
		int bytes;

		len = console_record_readline(str, sizeof(uts->actual_str));
		if (str[8] != ':' || str[9] != ' ')
			return 1;

		bytes = len - 8 - 2 - 3 * 16 - 2;
		upto += bytes;
	}

	return upto == total_bytes ? 0 : 1;
}

void ut_silence_console(struct unit_test_state *uts)
{
#ifdef CONFIG_SANDBOX
	struct sandbox_state *state = state_get_current();

	if (!state->show_test_output)
		gd->flags |= GD_FLG_SILENT;
#endif
}

void ut_unsilence_console(struct unit_test_state *uts)
{
	gd->flags &= ~(GD_FLG_SILENT | GD_FLG_RECORD);
}

void ut_set_skip_delays(struct unit_test_state *uts, bool skip_delays)
{
#ifdef CONFIG_SANDBOX
	state_set_skip_delays(skip_delays);
#endif
}
