/*
 * 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_pass(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_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();
}
