/*
 * Test result reporting
 *
 * Copyright (c) Siemens AG, 2014
 *
 * Authors:
 *  Jan Kiszka <jan.kiszka@siemens.com>
 *  Andrew Jones <drjones@redhat.com>
 *
 * This work is licensed under the terms of the GNU LGPL, version 2.
 */

#include "libcflat.h"
#include "asm/spinlock.h"

static unsigned int tests, failures, xfailures, skipped;
static char prefixes[256];
static struct spinlock lock;

#define PREFIX_DELIMITER ": "

void report_passed(void)
{
	spin_lock(&lock);
	tests++;
	spin_unlock(&lock);
}

void report_prefix_pushf(const char *prefix_fmt, ...)
{
	va_list va;
	unsigned int len;
	int start;

	spin_lock(&lock);

	len = strlen(prefixes);
	assert_msg(len < sizeof(prefixes), "%d >= %zu", len, sizeof(prefixes));
	start = len;

	va_start(va, prefix_fmt);
	len += vsnprintf(&prefixes[len], sizeof(prefixes) - len, prefix_fmt,
			 va);
	va_end(va);
	assert_msg(len < sizeof(prefixes), "%d >= %zu", len, sizeof(prefixes));

	assert_msg(!strstr(&prefixes[start], PREFIX_DELIMITER),
		   "Prefix \"%s\" contains delimiter \"" PREFIX_DELIMITER "\"",
		   &prefixes[start]);

	len += snprintf(&prefixes[len], sizeof(prefixes) - len,
			PREFIX_DELIMITER);
	assert_msg(len < sizeof(prefixes), "%d >= %zu", len, sizeof(prefixes));

	spin_unlock(&lock);
}

void report_prefix_push(const char *prefix)
{
	report_prefix_pushf("%s", prefix);
}

void report_prefix_pop(void)
{
	char *p, *q;

	spin_lock(&lock);

	if (!*prefixes) {
		spin_unlock(&lock);
		return;
	}

	for (p = prefixes, q = strstr(p, PREFIX_DELIMITER) + 2;
			*q;
			p = q, q = strstr(p, PREFIX_DELIMITER) + 2)
		;
	*p = '\0';

	spin_unlock(&lock);
}

static void va_report(const char *msg_fmt,
		bool pass, bool xfail, bool skip, va_list va)
{
	const char *prefix = skip ? "SKIP"
				  : xfail ? (pass ? "XPASS" : "XFAIL")
					  : (pass ? "PASS"  : "FAIL");

	spin_lock(&lock);

	tests++;
	printf("%s: ", prefix);
	puts(prefixes);
	vprintf(msg_fmt, va);
	puts("\n");
	if (skip)
		skipped++;
	else if (xfail && !pass)
		xfailures++;
	else if (xfail || !pass)
		failures++;

	spin_unlock(&lock);
}

void report(bool pass, const char *msg_fmt, ...)
{
	va_list va;
	va_start(va, msg_fmt);
	va_report(msg_fmt, pass, false, false, va);
	va_end(va);
}

void report_pass(const char *msg_fmt, ...)
{
	va_list va;

	va_start(va, msg_fmt);
	va_report(msg_fmt, true, false, false, va);
	va_end(va);
}

void report_fail(const char *msg_fmt, ...)
{
	va_list va;

	va_start(va, msg_fmt);
	va_report(msg_fmt, false, false, false, va);
	va_end(va);
}

void report_xfail(bool xfail, bool pass, const char *msg_fmt, ...)
{
	va_list va;
	va_start(va, msg_fmt);
	va_report(msg_fmt, pass, xfail, false, va);
	va_end(va);
}

void report_skip(const char *msg_fmt, ...)
{
	va_list va;
	va_start(va, msg_fmt);
	va_report(msg_fmt, false, false, true, va);
	va_end(va);
}

void report_info(const char *msg_fmt, ...)
{
	va_list va;

	spin_lock(&lock);
	puts("INFO: ");
	puts(prefixes);
	va_start(va, msg_fmt);
	vprintf(msg_fmt, va);
	va_end(va);
	puts("\n");
	spin_unlock(&lock);
}

int report_summary(void)
{
	int ret;
	spin_lock(&lock);

	printf("SUMMARY: %d tests", tests);
	if (failures)
		printf(", %d unexpected failures", failures);
	if (xfailures)
		printf(", %d expected failures", xfailures);
	if (skipped)
		printf(", %d skipped", skipped);
	printf("\n");

	if (tests == skipped) {
		spin_unlock(&lock);
		/* Blame AUTOTOOLS for using 77 for skipped test and QEMU for
		 * mangling error codes in a way that gets 77 if we ... */
		return 77 >> 1;
	}

	ret = failures > 0 ? 1 : 0;
	spin_unlock(&lock);
	return ret;
}

void report_abort(const char *msg_fmt, ...)
{
	va_list va;

	spin_lock(&lock);
	puts("ABORT: ");
	puts(prefixes);
	va_start(va, msg_fmt);
	vprintf(msg_fmt, va);
	va_end(va);
	puts("\n");
	spin_unlock(&lock);
	report_summary();
	abort();
}
