/*
 * Copyright © 2015 Samsung Electronics Co., Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice (including the
 * next paragraph) shall be included in all copies or substantial
 * portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include "config.h"

#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>

#include "zunitc/zunitc_impl.h"
#include "zunitc/zunitc.h"

#include "zuc_base_logger.h"
#include "zuc_collector.h"
#include "zuc_context.h"
#include "zuc_event_listener.h"
#include "zuc_junit_reporter.h"

#include "shared/config-parser.h"
#include "shared/helpers.h"
#include "shared/zalloc.h"

/*
 * If CLOCK_MONOTONIC is present on the system it will give us reliable
 * results under certain edge conditions that normally require manual
 * admin actions to trigger. If not, CLOCK_REALTIME is a reasonable
 * fallback.
 */
#if _POSIX_MONOTONIC_CLOCK
static const clockid_t TARGET_TIMER = CLOCK_MONOTONIC;
#else
static const clockid_t TARGET_TIMER = CLOCK_REALTIME;
#endif

static char const DISABLED_PREFIX[] = "DISABLED_";

#define MS_PER_SEC 1000L
#define NANO_PER_MS 1000000L

/**
 * Simple single-linked list structure.
 */
struct zuc_slinked {
	void *data;
	struct zuc_slinked *next;
};

static struct zuc_context g_ctx = {
	.case_count = 0,
	.cases = NULL,

	.fatal = false,
	.repeat = 0,
	.random = 0,
	.spawn = true,
	.break_on_failure = false,
	.fds = {-1, -1},

	.listeners = NULL,

	.curr_case = NULL,
	.curr_test = NULL,
};

static char *g_progname = NULL;
static char *g_progbasename = NULL;

typedef int (*comp_pred2)(intptr_t lhs, intptr_t rhs);

static bool
test_has_skip(struct zuc_test *test)
{
	return test->skipped;
}

static bool
test_has_failure(struct zuc_test *test)
{
	return test->fatal || test->failed;
}

bool
zuc_has_skip(void)
{
	return g_ctx.curr_test ?
		test_has_skip(g_ctx.curr_test) : false;
}

bool
zuc_has_failure(void)
{
	return g_ctx.curr_test ?
		test_has_failure(g_ctx.curr_test) : false;
}

void
zuc_set_filter(const char *filter)
{
	g_ctx.filter = strdup(filter);
}

void
zuc_set_repeat(int repeat)
{
	g_ctx.repeat = repeat;
}

void
zuc_set_random(int random)
{
	g_ctx.random = random;
}

void
zuc_set_spawn(bool spawn)
{
	g_ctx.spawn = spawn;
}

void
zuc_set_break_on_failure(bool break_on_failure)
{
	g_ctx.break_on_failure = break_on_failure;
}

void
zuc_set_output_junit(bool enable)
{
	g_ctx.output_junit = enable;
}

const char *
zuc_get_program_name(void)
{
	return g_progname;
}

const char *
zuc_get_program_basename(void)
{
	return g_progbasename;
}

static struct zuc_test *
create_test(int order, zucimpl_test_fn fn, zucimpl_test_fn_f fn_f,
	    char const *case_name, char const *test_name,
	    struct zuc_case *parent)
{
	struct zuc_test *test = zalloc(sizeof(struct zuc_test));
	ZUC_ASSERTG_NOT_NULL(test, out);
	test->order = order;
	test->fn = fn;
	test->fn_f = fn_f;
	test->name = strdup(test_name);
	if ((!fn && !fn_f) ||
	    (strncmp(DISABLED_PREFIX,
		     test_name, sizeof(DISABLED_PREFIX) - 1) == 0))
		test->disabled = 1;

	test->test_case = parent;

out:
	return test;
}

static int
compare_regs(const void *lhs, const void *rhs)
{
	int rc = strcmp((*(struct zuc_registration **)lhs)->tcase,
		      (*(struct zuc_registration **)rhs)->tcase);
	if (rc == 0)
		rc = strcmp((*(struct zuc_registration **)lhs)->test,
		      (*(struct zuc_registration **)rhs)->test);

	return rc;
}

/* gcc-specific markers for auto test case registration: */
extern const struct zuc_registration __start_zuc_tsect;
extern const struct zuc_registration __stop_zuc_tsect;

static void
register_tests(void)
{
	size_t case_count = 0;
	size_t count = &__stop_zuc_tsect - &__start_zuc_tsect;
	size_t i;
	int idx = 0;
	const char *last_name = NULL;
	void **array = zalloc(sizeof(void *) * count);
	ZUC_ASSERT_NOT_NULL(array);
	for (i = 0; i < count; ++i)
		array[i] = (void *)(&__start_zuc_tsect + i);

	qsort(array, count, sizeof(array[0]), compare_regs);

	/* Count transitions to get number of test cases. */
	last_name = NULL;
	for (i = 0; i < count; ++i) {
		const struct zuc_registration *reg =
			(const struct zuc_registration *)array[i];
		if (!last_name || (strcmp(last_name, reg->tcase))) {
			last_name = reg->tcase;
			case_count++;
		}
	}

	/* Create test case data items. */
	struct zuc_case **case_array =
		zalloc(sizeof(struct zuc_case *) * case_count);
	ZUC_ASSERT_NOT_NULL(case_array);
	struct zuc_case *last_case = NULL;
	size_t case_num = 0;
	for (i = 0; i < count; ++i) {
		const struct zuc_registration *reg =
			(const struct zuc_registration *)array[i];
		if (!last_case || (strcmp(last_case->name, reg->tcase))) {
			last_case = zalloc(sizeof(struct zuc_case));
			ZUC_ASSERT_NOT_NULL(last_case);
			last_case->order = count;
			last_case->name = strdup(reg->tcase);
			last_case->fxt = reg->fxt;
			last_case->test_count = i;
			if (case_num > 0) {
				int tcount = i
					- case_array[case_num - 1]->test_count;
				case_array[case_num - 1]->test_count = tcount;
			}
			case_array[case_num++] = last_case;
		}
	}
	case_array[case_count - 1]->test_count = count
		- case_array[case_count - 1]->test_count;

	/* Reserve space for tests per test case. */
	for (case_num = 0; case_num < case_count; ++case_num) {
		case_array[case_num]->tests =
			zalloc(case_array[case_num]->test_count
			       * sizeof(struct zuc_test *));
		ZUC_ASSERT_NOT_NULL(case_array[case_num]->tests);
	}

	last_name = NULL;
	case_num = -1;
	for (i = 0; i < count; ++i) {
		const struct zuc_registration *reg =
			(const struct zuc_registration *)array[i];
		int order = count - (1 + (reg - &__start_zuc_tsect));

		if (!last_name || (strcmp(last_name, reg->tcase))) {
			last_name = reg->tcase;
			case_num++;
			idx = 0;
		}
		if (order < case_array[case_num]->order)
			case_array[case_num]->order = order;
		case_array[case_num]->tests[idx] =
			create_test(order, reg->fn, reg->fn_f,
				    reg->tcase, reg->test,
				    case_array[case_num]);

		if (case_array[case_num]->fxt != reg->fxt)
			printf("%s:%d: error: Mismatched fixtures for '%s'\n",
			       __FILE__, __LINE__, case_array[case_num]->name);

		idx++;
	}
	free(array);

	g_ctx.case_count = case_count;
	g_ctx.cases = case_array;
}

static int
compare_case_order(const void *lhs, const void *rhs)
{
	return (*(struct zuc_case **)lhs)->order
		- (*(struct zuc_case **)rhs)->order;
}

static int
compare_test_order(const void *lhs, const void *rhs)
{
	return (*(struct zuc_test **)lhs)->order
		- (*(struct zuc_test **)rhs)->order;
}

static void
order_cases(int count, struct zuc_case **cases)
{
	int i;
	qsort(cases, count, sizeof(*cases), compare_case_order);
	for (i = 0; i < count; ++i) {
		qsort(cases[i]->tests, cases[i]->test_count,
		      sizeof(*cases[i]->tests), compare_test_order);
	}
}

static void
free_events(struct zuc_event **events)
{
	struct zuc_event *evt = *events;
	*events = NULL;
	while (evt) {
		struct zuc_event *old = evt;
		evt = evt->next;
		free(old->file);
		if (old->valtype == ZUC_VAL_CSTR) {
			free((void *)old->val1);
			free((void *)old->val2);
		}
		free(old->expr1);
		free(old->expr2);
		free(old);
	}
}

static void
free_test(struct zuc_test *test)
{
	free(test->name);
	free_events(&test->events);
	free_events(&test->deferred);
	free(test);
}

static void
free_test_case(struct zuc_case *test_case)
{
	int i;
	free(test_case->name);
	for (i = test_case->test_count - 1; i >= 0; --i) {
		free_test(test_case->tests[i]);
		test_case->tests[i] = NULL;
	}
	free(test_case->tests);
	free(test_case);
}

/**
 * A very simple matching that is compatible with the algorithm used in
 * Google Test.
 *
 * @param wildcard sequence of '?', '*' or normal characters to match.
 * @param str string to check for matching.
 * @return true if the wildcard matches the entire string, false otherwise.
 */
static bool
wildcard_matches(char const *wildcard, char const *str)
{
	switch (*wildcard) {
	case '\0':
		return !*str;
	case '?':
		return *str && wildcard_matches(wildcard + 1, str + 1);
	case '*':
		return (*str && wildcard_matches(wildcard, str + 1))
			|| wildcard_matches(wildcard + 1, str);
	default:
		return (*wildcard == *str)
			&& wildcard_matches(wildcard + 1, str + 1);
	};
}

static char**
segment_str(char *str)
{
	int count = 1;
	char **parts = NULL;
	char *saved = NULL;
	char *tok = NULL;
	int i = 0;
	for (i = 0; str[i]; ++i)
		if (str[i] == ':')
			count++;
	parts = zalloc(sizeof(char*) * (count + 1));
	ZUC_ASSERTG_NOT_NULL(parts, out);
	tok = strtok_r(str, ":", &saved);
	i = 0;
	parts[i++] = tok;
	while (tok) {
		tok = strtok_r(NULL, ":", &saved);
		parts[i++] = tok;
	}
out:
	return parts;
}

static void
filter_cases(int *count, struct zuc_case **cases, char const *filter)
{
	int i = 0;
	int j = 0;
	int num_pos = 0;
	int negative = -1;
	char *buf = strdup(filter);
	char **parts = segment_str(buf);

	for (i = 0; parts[i]; ++i) {
		if (parts[i][0] == '-') {
			parts[i]++;
			negative = i;
			break;
		}
		num_pos++;
	}

	for (i = 0; i < *count; ++i) {
		/* Walk backwards for easier pruning. */
		for (j = cases[i]->test_count - 1; j >= 0; --j) {
			int x;
			bool keep = num_pos == 0;
			char *name = NULL;
			struct zuc_test *test = cases[i]->tests[j];
			if (asprintf(&name, "%s.%s", cases[i]->name,
				     test->name) < 0) {
				printf("%s:%d: error: %d\n", __FILE__, __LINE__,
				       errno);
				exit(EXIT_FAILURE);
			}
			for (x = 0; (x < num_pos) && !keep; ++x)
				keep = wildcard_matches(parts[x], name);
			if (keep && (negative >= 0))
				for (x = negative; parts[x] && keep; ++x)
					keep &= !wildcard_matches(parts[x],
								  name);
			if (!keep) {
				int w;
				free_test(test);
				for (w = j + 1; w < cases[i]->test_count; w++)
					cases[i]->tests[w - 1] =
						cases[i]->tests[w];
				cases[i]->test_count--;
			}

			free(name);
		}
	}
	free(parts);
	parts = NULL;
	free(buf);
	buf = NULL;

	/* Prune any cases with no more tests. */
	for (i = *count - 1; i >= 0; --i) {
		if (cases[i]->test_count < 1) {
			free_test_case(cases[i]);
			for (j = i + 1; j < *count; ++j)
				cases[j - 1] = cases[j];
			cases[*count - 1] = NULL;
			(*count)--;
		}
	}
}

static unsigned int
get_seed_from_time(void)
{
	time_t sec = time(NULL);
	unsigned int seed = (unsigned int) sec % 100000;
	if (seed < 2)
		seed = 2;

	return seed;
}

static void
initialize(void)
{
	static bool init = false;
	if (init)
		return;

	init = true;
	register_tests();
	if (g_ctx.fatal)
		return;

	if (g_ctx.random > 1) {
		g_ctx.seed = g_ctx.random;
	} else if (g_ctx.random == 1) {
		g_ctx.seed = get_seed_from_time();
	}

	if (g_ctx.case_count) {
		order_cases(g_ctx.case_count, g_ctx.cases);
		if (g_ctx.filter && g_ctx.filter[0])
			filter_cases(&g_ctx.case_count, g_ctx.cases,
				     g_ctx.filter);
	}
}

int
zuc_initialize(int *argc, char *argv[], bool *help_flagged)
{
	int rc = EXIT_FAILURE;
	int opt_help = 0;
	int opt_nofork = 0;
	int opt_list = 0;
	int opt_repeat = 0;
	int opt_random = 0;
	int opt_break_on_failure = 0;
	int opt_junit = 0;
	char *opt_filter = NULL;

	char *help_param = NULL;
	int argc_in = *argc;

	const struct weston_option options[] = {
		{ WESTON_OPTION_BOOLEAN, "zuc-nofork", 0, &opt_nofork },
		{ WESTON_OPTION_BOOLEAN, "zuc-list-tests", 0, &opt_list },
		{ WESTON_OPTION_INTEGER, "zuc-repeat", 0, &opt_repeat },
		{ WESTON_OPTION_INTEGER, "zuc-random", 0, &opt_random },
		{ WESTON_OPTION_BOOLEAN, "zuc-break-on-failure", 0,
		  &opt_break_on_failure },
#if ENABLE_JUNIT_XML
		{ WESTON_OPTION_BOOLEAN, "zuc-output-xml", 0, &opt_junit },
#endif
		{ WESTON_OPTION_STRING, "zuc-filter", 0, &opt_filter },
	};

	/*
	 *If a test binary is linked to our libzunitcmain it might want
	 * to access the program 'name' from argv[0]
	 */
	free(g_progname);
	g_progname = NULL;
	free(g_progbasename);
	g_progbasename = NULL;
	if ((*argc > 0) && argv) {
		char *path = NULL;
		char *base = NULL;

		g_progname = strdup(argv[0]);

		/* basename() might modify the input, so needs a writeable
		 * string.
		 * It also may return a statically allocated buffer subject to
		 * being overwritten so needs to be dup'd.
		 */
		path = strdup(g_progname);
		base = basename(path);
		g_progbasename = strdup(base);
		free(path);
	} else {
		g_progname = strdup("");
		printf("%s:%d: warning: No valid argv[0] for initialization\n",
		       __FILE__, __LINE__);
	}


	initialize();
	if (g_ctx.fatal)
		return EXIT_FAILURE;

	if (help_flagged)
		*help_flagged = false;

	{
		/* Help param will be a special case and need restoring. */
		int i = 0;
		char **argv_in = NULL;
		const struct weston_option help_options[] = {
			{ WESTON_OPTION_BOOLEAN, "help", 'h', &opt_help },
		};
		argv_in = zalloc(sizeof(char *) * argc_in);
		if (!argv_in) {
			printf("%s:%d: error: alloc failed.\n",
			       __FILE__, __LINE__);
			return EXIT_FAILURE;
		}
		for (i = 0; i < argc_in; ++i)
			argv_in[i] = argv[i];

		parse_options(help_options, ARRAY_LENGTH(help_options),
			      argc, argv);
		if (*argc < argc_in) {
			for (i = 1; (i < argc_in) && !help_param; ++i) {
				bool found = false;
				int j = 0;
				for (j = 0; (j < *argc) && !found; ++j)
					found = (argv[j] == argv_in[i]);

				if (!found)
					help_param = argv_in[i];
			}
		}
		free(argv_in);
	}

	parse_options(options, ARRAY_LENGTH(options), argc, argv);

	if (help_param && (*argc < argc_in))
		argv[(*argc)++] = help_param;

	if (opt_filter) {
		zuc_set_filter(opt_filter);
		free(opt_filter);
	}

	if (opt_help) {
		printf("Usage: %s [OPTIONS]\n"
		       "  --zuc-break-on-failure\n"
		       "  --zuc-filter=FILTER\n"
		       "  --zuc-list-tests\n"
		       "  --zuc-nofork\n"
#if ENABLE_JUNIT_XML
		       "  --zuc-output-xml\n"
#endif
		       "  --zuc-random=N            [0|1|<seed number>]\n"
		       "  --zuc-repeat=N\n"
		       "  --help\n",
		       argv[0]);
		if (help_flagged)
			*help_flagged = true;
		rc = EXIT_SUCCESS;
	} else if (opt_list) {
		zuc_list_tests();
		rc = EXIT_FAILURE;
	} else {
		zuc_set_repeat(opt_repeat);
		zuc_set_random(opt_random);
		zuc_set_spawn(!opt_nofork);
		zuc_set_break_on_failure(opt_break_on_failure);
		zuc_set_output_junit(opt_junit);
		rc = EXIT_SUCCESS;
	}

	return rc;
}

static void
dispatch_pre_run(struct zuc_context *ctx, int pass_count, int pass_num,
		 int seed, const char *filter)
{
	struct zuc_slinked *curr;
	for (curr = ctx->listeners; curr; curr = curr->next) {
		struct zuc_event_listener *listener = curr->data;
		if (listener->pre_run)
			listener->pre_run(listener->data,
					  pass_count,
					  pass_num,
					  seed,
					  filter);
	}
}

static void
dispatch_run_started(struct zuc_context *ctx, int live_case_count,
		     int live_test_count, int disabled_count)
{
	struct zuc_slinked *curr;
	for (curr = ctx->listeners; curr; curr = curr->next) {
		struct zuc_event_listener *listener = curr->data;
		if (listener->run_started)
			listener->run_started(listener->data,
					      live_case_count,
					      live_test_count,
					      disabled_count);
	}
}

static void
dispatch_run_ended(struct zuc_context *ctx,
		   int live_case_count, int live_test_count, int total_passed,
		   int total_failed, int total_disabled, long total_elapsed)
{
	struct zuc_slinked *curr;
	for (curr = ctx->listeners; curr; curr = curr->next) {
		struct zuc_event_listener *listener = curr->data;
		if (listener->run_ended)
			listener->run_ended(listener->data,
					    ctx->case_count,
					    ctx->cases,
					    live_case_count,
					    live_test_count,
					    total_passed,
					    total_failed,
					    total_disabled,
					    total_elapsed);
	}
}

static void
dispatch_case_started(struct zuc_context *ctx,struct zuc_case *test_case,
		      int live_test_count, int disabled_count)
{
	struct zuc_slinked *curr;
	for (curr = ctx->listeners; curr; curr = curr->next) {
		struct zuc_event_listener *listener = curr->data;
		if (listener->case_started)
			listener->case_started(listener->data,
					       test_case,
					       live_test_count,
					       disabled_count);
	}
}

static void
dispatch_case_ended(struct zuc_context *ctx, struct zuc_case *test_case)
{
	struct zuc_slinked *curr;
	for (curr = ctx->listeners; curr; curr = curr->next) {
		struct zuc_event_listener *listener = curr->data;
		if (listener->case_ended)
			listener->case_ended(listener->data, test_case);
	}
}

static void
dispatch_test_started(struct zuc_context *ctx, struct zuc_test *test)
{
	struct zuc_slinked *curr;
	for (curr = ctx->listeners; curr; curr = curr->next) {
		struct zuc_event_listener *listener = curr->data;
		if (listener->test_started)
			listener->test_started(listener->data, test);
	}
}

static void
dispatch_test_ended(struct zuc_context *ctx, struct zuc_test *test)
{
	struct zuc_slinked *curr;
	for (curr = ctx->listeners; curr; curr = curr->next) {
		struct zuc_event_listener *listener = curr->data;
		if (listener->test_ended)
			listener->test_ended(listener->data, test);
	}
}

static void
dispatch_test_disabled(struct zuc_context *ctx, struct zuc_test *test)
{
	struct zuc_slinked *curr;
	for (curr = ctx->listeners; curr; curr = curr->next) {
		struct zuc_event_listener *listener = curr->data;
		if (listener->test_disabled)
			listener->test_disabled(listener->data, test);
	}
}

static void
dispatch_check_triggered(struct zuc_context *ctx, char const *file, int line,
			 enum zuc_fail_state state, enum zuc_check_op op,
			 enum zuc_check_valtype valtype,
			 intptr_t val1, intptr_t val2,
			 const char *expr1, const char *expr2)
{
	struct zuc_slinked *curr;
	for (curr = ctx->listeners; curr; curr = curr->next) {
		struct zuc_event_listener *listener = curr->data;
		if (listener->check_triggered)
			listener->check_triggered(listener->data,
						  file, line,
						  state, op, valtype,
						  val1, val2,
						  expr1, expr2);
	}
}

static void
dispatch_collect_event(struct zuc_context *ctx, char const *file, int line,
		       const char *expr1)
{
	struct zuc_slinked *curr;
	for (curr = ctx->listeners; curr; curr = curr->next) {
		struct zuc_event_listener *listener = curr->data;
		if (listener->collect_event)
			listener->collect_event(listener->data,
						file, line, expr1);
	}
}

static void
migrate_deferred_events(struct zuc_test *test, bool transferred)
{
	struct zuc_event *evt = test->deferred;
	if (!evt)
		return;

	test->deferred = NULL;
	if (test->events) {
		struct zuc_event *old = test->events;
		while (old->next)
			old = old->next;
		old->next = evt;
	} else {
		test->events = evt;
	}
	while (evt && !transferred) {
		dispatch_check_triggered(&g_ctx,
					 evt->file, evt->line,
					 evt->state, evt->op,
					 evt->valtype,
					 evt->val1, evt->val2,
					 evt->expr1, evt->expr2);
		evt = evt->next;
	}
}

static void
mark_single_failed(struct zuc_test *test, enum zuc_fail_state state)
{
	switch (state) {
	case ZUC_CHECK_OK:
		/* no internal state to change */
		break;
	case ZUC_CHECK_SKIP:
		if (test)
			test->skipped = 1;
		break;
	case ZUC_CHECK_FAIL:
		if (test)
			test->failed = 1;
		break;
	case ZUC_CHECK_ERROR:
	case ZUC_CHECK_FATAL:
		if (test)
			test->fatal = 1;
		break;
	}

	if (g_ctx.break_on_failure)
		raise(SIGABRT);

}

static void
mark_failed(struct zuc_test *test, enum zuc_fail_state state)
{
	if (!test && g_ctx.curr_test)
		test = g_ctx.curr_test;

	if (test) {
		mark_single_failed(test, state);
	} else if (g_ctx.curr_case) {
		/* In setup or tear-down of test suite */
		int i;
		for (i = 0; i < g_ctx.curr_case->test_count; ++i)
			mark_single_failed(g_ctx.curr_case->tests[i], state);
	}
	if ((state == ZUC_CHECK_FATAL) || (state == ZUC_CHECK_ERROR))
		g_ctx.fatal = true;
}

void
zuc_attach_event(struct zuc_test *test, struct zuc_event *event,
		 enum zuc_event_type event_type, bool transferred)
{
	if (!test) {
		/*
		 * consider adding events directly to the case.
		 * would be for use during per-suite setup and teardown.
		 */
		printf("%s:%d: error: No current test.\n", __FILE__, __LINE__);
	} else if (event_type == ZUC_EVENT_DEFERRED) {
		if (test->deferred) {
			struct zuc_event *curr = test->deferred;
			while (curr->next)
				curr = curr->next;
			curr->next = event;
		} else {
			test->deferred = event;
		}
	} else {
		if (test)
			migrate_deferred_events(test, transferred);

		if (test->events) {
			struct zuc_event *curr = test->events;
			while (curr->next)
				curr = curr->next;
			curr->next = event;
		} else {
			test->events = event;
		}
		mark_failed(test, event->state);
	}
}

void
zuc_add_event_listener(struct zuc_event_listener *event_listener)
{
	if (!event_listener) /* ensure null entries are not added */
		return;

	if (!g_ctx.listeners) {
		g_ctx.listeners = zalloc(sizeof(struct zuc_slinked));
		ZUC_ASSERT_NOT_NULL(g_ctx.listeners);
		g_ctx.listeners->data = event_listener;
	} else {
		struct zuc_slinked *curr = g_ctx.listeners;
		while (curr->next)
			curr = curr->next;
		curr->next = zalloc(sizeof(struct zuc_slinked));
		ZUC_ASSERT_NOT_NULL(curr->next);
		curr->next->data = event_listener;
	}
}


void
zuc_cleanup(void)
{
	int i;

	free(g_ctx.filter);
	g_ctx.filter = 0;
	for (i = 0; i < 2; ++i)
		if (g_ctx.fds[i] != -1) {
			close(g_ctx.fds[i]);
			g_ctx.fds[i] = -1;
		}

	if (g_ctx.listeners) {
		struct zuc_slinked *curr = g_ctx.listeners;
		while (curr) {
			struct zuc_slinked *old = curr;
			struct zuc_event_listener *listener = curr->data;
			if (listener->destroy)
				listener->destroy(listener->data);
			free(listener);
			curr = curr->next;
			free(old);
		}
		g_ctx.listeners = NULL;
	}

	for (i = g_ctx.case_count - 1; i >= 0; --i) {
		free_test_case(g_ctx.cases[i]);
		g_ctx.cases[i] = NULL;
	}
	free(g_ctx.cases);
	g_ctx.cases = NULL;

	free(g_progname);
	g_progname = NULL;
	free(g_progbasename);
	g_progbasename = NULL;
}

static void
shuffle_cases(int count, struct zuc_case **cases,
		   unsigned int seed)
{
	int i;
	unsigned int rseed = seed;
	for (i = 0; i < count; ++i) {
		int j;
		for (j = cases[i]->test_count - 1; j > 0 ; --j) {
			int val = rand_r(&rseed);
			int b = ((val / (double)RAND_MAX) * j + 0.5);
			if (j != b) {
				struct zuc_test *tmp = cases[i]->tests[j];
				cases[i]->tests[j] = cases[i]->tests[b];
				cases[i]->tests[b] = tmp;
			}
		}
	}

	for (i = count - 1; i > 0; --i) {
		int val = rand_r(&rseed);
		int j = ((val / (double)RAND_MAX) * i + 0.5);

		if (i != j) {
			struct zuc_case *tmp = cases[i];
			cases[i] = cases[j];
			cases[j] = tmp;
		}
	}
}

void
zuc_list_tests(void)
{
	int i;
	int j;
	initialize();
	if (g_ctx.fatal)
		return;
	for (i = 0; i < g_ctx.case_count; ++i) {
		printf("%s.\n", g_ctx.cases[i]->name);
		for (j = 0; j < g_ctx.cases[i]->test_count; ++j) {
			printf("  %s\n", g_ctx.cases[i]->tests[j]->name);
		}
	}
}

static void
spawn_test(struct zuc_test *test, void *test_data,
	   void (*cleanup_fn)(void *data), void *cleanup_data)
{
	pid_t pid = -1;

	if (!test || (!test->fn && !test->fn_f))
		return;

	if (pipe2(g_ctx.fds, O_CLOEXEC)) {
		printf("%s:%d: error: Unable to create pipe: %d\n",
		       __FILE__, __LINE__, errno);
		mark_failed(test, ZUC_CHECK_ERROR);
		return;
	}

	fflush(NULL); /* important. avoid duplication of output */
	pid = fork();
	switch (pid) {
	case -1: /* Error forking */
		printf("%s:%d: error: Problem with fork: %d\n",
		       __FILE__, __LINE__, errno);
		mark_failed(test, ZUC_CHECK_ERROR);
		close(g_ctx.fds[0]);
		g_ctx.fds[0] = -1;
		close(g_ctx.fds[1]);
		g_ctx.fds[1] = -1;
		break;
	case 0: { /* child */
		int rc = EXIT_SUCCESS;
		close(g_ctx.fds[0]);
		g_ctx.fds[0] = -1;

		if (test->fn_f)
			test->fn_f(test_data);
		else
			test->fn();

		if (test_has_failure(test))
			rc = EXIT_FAILURE;
		else if (test_has_skip(test))
			rc = ZUC_EXIT_SKIP;

		/* Avoid confusing memory tools like valgrind */
		if (cleanup_fn)
			cleanup_fn(cleanup_data);

		zuc_cleanup();
		exit(rc);
	}
	default: { /* parent */
		ssize_t rc = 0;
		siginfo_t info = {};

		close(g_ctx.fds[1]);
		g_ctx.fds[1] = -1;

		do {
			rc = zuc_process_message(g_ctx.curr_test,
						 g_ctx.fds[0]);
		} while (rc > 0);
		close(g_ctx.fds[0]);
		g_ctx.fds[0] = -1;

		if (waitid(P_ALL, 0, &info, WEXITED)) {
			printf("%s:%d: error: waitid failed. (%d)\n",
			       __FILE__, __LINE__, errno);
			mark_failed(test, ZUC_CHECK_ERROR);
		} else {
			switch (info.si_code) {
			case CLD_EXITED: {
				int exit_code = info.si_status;
				switch(exit_code) {
				case EXIT_SUCCESS:
					break;
				case ZUC_EXIT_SKIP:
					if (!test_has_skip(g_ctx.curr_test) &&
					    !test_has_failure(g_ctx.curr_test))
						ZUC_SKIP("Child exited SKIP");
					break;
				default:
					/* unexpected failure */
					if (!test_has_failure(g_ctx.curr_test))
						ZUC_ASSERT_EQ(0, exit_code);
				}
				break;
			}
			case CLD_KILLED:
			case CLD_DUMPED:
				printf("%s:%d: error: signaled: %d\n",
				       __FILE__, __LINE__, info.si_status);
				mark_failed(test, ZUC_CHECK_ERROR);
				break;
			}
		}
	}
	}
}

static void
run_single_test(struct zuc_test *test,const struct zuc_fixture *fxt,
		void *case_data, bool spawn)
{
	long elapsed = 0;
	struct timespec begin;
	struct timespec end;
	void *test_data = NULL;
	void *cleanup_data = NULL;
	void (*cleanup_fn)(void *data) = NULL;
	memset(&begin, 0, sizeof(begin));
	memset(&end, 0, sizeof(end));

	g_ctx.curr_test = test;
	dispatch_test_started(&g_ctx, test);

	cleanup_fn = fxt ? fxt->tear_down : NULL;
	cleanup_data = NULL;

	if (fxt && fxt->set_up) {
		test_data = fxt->set_up(case_data);
		cleanup_data = test_data;
	} else {
		test_data = case_data;
	}

	clock_gettime(TARGET_TIMER, &begin);

	/* Need to re-check these, as fixtures might have changed test state. */
	if (!test->fatal && !test->skipped) {
		if (spawn) {
			spawn_test(test, test_data,
				   cleanup_fn, cleanup_data);
		} else {
			if (test->fn_f)
				test->fn_f(test_data);
			else
				test->fn();
		}
	}

	clock_gettime(TARGET_TIMER, &end);

	elapsed = (end.tv_sec - begin.tv_sec) * MS_PER_SEC;
	if (end.tv_sec != begin.tv_sec) {
		elapsed -= (begin.tv_nsec) / NANO_PER_MS;
		elapsed += (end.tv_nsec) / NANO_PER_MS;
	} else {
		elapsed += (end.tv_nsec - begin.tv_nsec) / NANO_PER_MS;
	}
	test->elapsed = elapsed;

	if (cleanup_fn)
		cleanup_fn(cleanup_data);

	if (test->deferred) {
		if (test_has_failure(test))
			migrate_deferred_events(test, false);
		else
			free_events(&test->deferred);
	}

	dispatch_test_ended(&g_ctx, test);

	g_ctx.curr_test = NULL;
}

static void
run_single_case(struct zuc_case *test_case)
{
	int count_live = test_case->test_count - test_case->disabled;
	g_ctx.curr_case = test_case;
	if (count_live) {
		int i = 0;
		const struct zuc_fixture *fxt = test_case->fxt;
		void *case_data = fxt ? (void *)fxt->data : NULL;

		dispatch_case_started(&g_ctx, test_case,
				      count_live, test_case->disabled);

		if (fxt && fxt->set_up_test_case)
			case_data = fxt->set_up_test_case(fxt->data);

		for (i = 0; i < test_case->test_count; ++i) {
			struct zuc_test *curr = test_case->tests[i];
			if (curr->disabled) {
				dispatch_test_disabled(&g_ctx, curr);
			} else {
				run_single_test(curr, fxt, case_data,
						g_ctx.spawn);
				if (curr->skipped)
					test_case->skipped++;
				if (curr->failed)
					test_case->failed++;
				if (curr->fatal)
					test_case->fatal++;
				if (!curr->failed && !curr->fatal)
					test_case->passed++;
				test_case->elapsed += curr->elapsed;
			}
		}

		if (fxt && fxt->tear_down_test_case)
			fxt->tear_down_test_case(case_data);

		dispatch_case_ended(&g_ctx, test_case);
	}
	g_ctx.curr_case = NULL;
}

static void
reset_test_values(struct zuc_case **cases, int case_count)
{
	int i;
	for (i = 0; i < case_count; ++i) {
		int j;
		cases[i]->disabled = 0;
		cases[i]->skipped = 0;
		cases[i]->failed = 0;
		cases[i]->fatal = 0;
		cases[i]->passed = 0;
		cases[i]->elapsed = 0;
		for (j = 0; j < cases[i]->test_count; ++j) {
			struct zuc_test *test = cases[i]->tests[j];
			if (test->disabled)
				cases[i]->disabled++;
			test->skipped = 0;
			test->failed = 0;
			test->fatal = 0;
			test->elapsed = 0;

			free_events(&test->events);
			free_events(&test->deferred);
		}
	}
}

static int
run_single_pass(void)
{
	long total_elapsed = 0;
	int total_passed = 0;
	int total_failed = 0;
	int total_skipped = 0;
	int live_case_count = 0;
	int live_test_count = 0;
	int disabled_test_count = 0;
	int i;

	reset_test_values(g_ctx.cases, g_ctx.case_count);
	for (i = 0; i <  g_ctx.case_count; ++i) {
		int live = g_ctx.cases[i]->test_count
			- g_ctx.cases[i]->disabled;
		if (live) {
			live_test_count += live;
			live_case_count++;
		}
		if (g_ctx.cases[i]->disabled)
			disabled_test_count++;
	}

	dispatch_run_started(&g_ctx, live_case_count, live_test_count,
			     disabled_test_count);

	for (i = 0; i <  g_ctx.case_count; ++i) {
		run_single_case(g_ctx.cases[i]);
		total_failed += g_ctx.cases[i]->test_count
			- (g_ctx.cases[i]->passed + g_ctx.cases[i]->disabled);
		total_passed += g_ctx.cases[i]->passed;
		total_elapsed += g_ctx.cases[i]->elapsed;
		total_skipped += g_ctx.cases[i]->skipped;
	}

	dispatch_run_ended(&g_ctx, live_case_count, live_test_count,
			   total_passed, total_failed, disabled_test_count,
			   total_elapsed);

	if (total_failed)
		return EXIT_FAILURE;
	else if (total_skipped)
		return ZUC_EXIT_SKIP;
	else
		return EXIT_SUCCESS;
}

int
zucimpl_run_tests(void)
{
	int rc = EXIT_SUCCESS;
	int i;
	int limit = g_ctx.repeat > 0 ? g_ctx.repeat : 1;

	initialize();
	if (g_ctx.fatal)
		return EXIT_FAILURE;

	if (g_ctx.listeners == NULL) {
		zuc_add_event_listener(zuc_collector_create(&(g_ctx.fds[1])));
		zuc_add_event_listener(zuc_base_logger_create());
		if (g_ctx.output_junit)
			zuc_add_event_listener(zuc_junit_reporter_create());
	}

	if (g_ctx.case_count < 1) {
		printf("%s:%d: error: Setup error: test tree is empty\n",
		       __FILE__, __LINE__);
		rc = EXIT_FAILURE;
	}

	for (i = 0; (i < limit) && (g_ctx.case_count > 0); ++i) {
		int pass_code = EXIT_SUCCESS;
		dispatch_pre_run(&g_ctx, limit, i + 1,
				 (g_ctx.random > 0) ? g_ctx.seed : 0,
				 g_ctx.filter);

		order_cases(g_ctx.case_count, g_ctx.cases);
		if (g_ctx.random > 0)
			shuffle_cases(g_ctx.case_count, g_ctx.cases,
				      g_ctx.seed);

		pass_code = run_single_pass();
		if (pass_code == EXIT_FAILURE)
			rc = EXIT_FAILURE;
		else if ((pass_code == ZUC_EXIT_SKIP) && (rc == EXIT_SUCCESS))
			rc = ZUC_EXIT_SKIP;

		g_ctx.seed++;
	}

	return rc;
}

int
zucimpl_tracepoint(char const *file, int line, char const *fmt, ...)
{
	int rc = -1;
	va_list argp;
	char *msg = NULL;


	va_start(argp, fmt);
	rc = vasprintf(&msg, fmt, argp);
	if (rc == -1) {
		msg = NULL;
	}
	va_end(argp);

	dispatch_collect_event(&g_ctx,
			       file, line,
			       msg);

	free(msg);

	return rc;
}

void
zucimpl_terminate(char const *file, int line,
		  bool fail, bool fatal, const char *msg)
{
	enum zuc_fail_state state = ZUC_CHECK_SKIP;
	int level = 2;
	if (fail && fatal) {
		state =  ZUC_CHECK_FATAL;
		level = 0;
	} else if (fail && !fatal) {
		state = ZUC_CHECK_FAIL;
		level = 0;
	}

	mark_failed(g_ctx.curr_test, state);

	if ((state != ZUC_CHECK_OK) && g_ctx.curr_test)
		migrate_deferred_events(g_ctx.curr_test, false);

	dispatch_check_triggered(&g_ctx,
				 file, line,
				 state,
				 ZUC_OP_TERMINATE, ZUC_VAL_INT,
				 level, 0,
				 msg, "");
}

static void
validate_types(enum zuc_check_op op, enum zuc_check_valtype valtype)
{
	bool is_valid = true;

	switch (op) {
	case ZUC_OP_NULL:
	case ZUC_OP_NOT_NULL:
		is_valid = is_valid && (valtype == ZUC_VAL_PTR);
		break;
	default:
		; /* all rest OK */
	}

	switch (valtype) {
	case ZUC_VAL_CSTR:
		is_valid = is_valid && ((op == ZUC_OP_EQ) || (op == ZUC_OP_NE));
		break;
	default:
		; /* all rest OK */
	}

	if (!is_valid)
		printf("%s:%d: warning: Unexpected op+type %d/%d.\n",
		       __FILE__, __LINE__, op, valtype);
}

static int
pred2_unknown(intptr_t lhs, intptr_t rhs)
{
	return 0;
}

static int
pred2_true(intptr_t lhs, intptr_t rhs)
{
	return lhs;
}

static int
pred2_false(intptr_t lhs, intptr_t rhs)
{
	return !lhs;
}

static int
pred2_eq(intptr_t lhs, intptr_t rhs)
{
	return lhs == rhs;
}

static int
pred2_streq(intptr_t lhs, intptr_t rhs)
{
	int status = 0;
	const char *lhptr = (const char *)lhs;
	const char *rhptr = (const char *)rhs;

	if (!lhptr && !rhptr)
		status = 1;
	else if (lhptr && rhptr)
		status = strcmp(lhptr, rhptr) == 0;

	return status;
}

static int
pred2_ne(intptr_t lhs, intptr_t rhs)
{
	return lhs != rhs;
}

static int
pred2_strne(intptr_t lhs, intptr_t rhs)
{
	int status = 0;
	const char *lhptr = (const char *)lhs;
	const char *rhptr = (const char *)rhs;

	if (lhptr != rhptr) {
		if (!lhptr || !rhptr)
			status = 1;
		else
			status = strcmp(lhptr, rhptr) != 0;
	}

	return status;
}

static int
pred2_ge(intptr_t lhs, intptr_t rhs)
{
	return lhs >= rhs;
}

static int
pred2_gt(intptr_t lhs, intptr_t rhs)
{
	return lhs > rhs;
}

static int
pred2_le(intptr_t lhs, intptr_t rhs)
{
	return lhs <= rhs;
}

static int
pred2_lt(intptr_t lhs, intptr_t rhs)
{
	return lhs < rhs;
}

static comp_pred2
get_pred2(enum zuc_check_op op, enum zuc_check_valtype valtype)
{
	switch (op) {
	case ZUC_OP_TRUE:
		return pred2_true;
	case ZUC_OP_FALSE:
		return pred2_false;
	case ZUC_OP_NULL:
		return pred2_false;
	case ZUC_OP_NOT_NULL:
		return pred2_true;
	case ZUC_OP_EQ:
		if (valtype == ZUC_VAL_CSTR)
			return pred2_streq;
		else
			return pred2_eq;
	case ZUC_OP_NE:
		if (valtype == ZUC_VAL_CSTR)
			return pred2_strne;
		else
			return pred2_ne;
	case ZUC_OP_GE:
		return pred2_ge;
	case ZUC_OP_GT:
		return pred2_gt;
	case ZUC_OP_LE:
		return pred2_le;
	case ZUC_OP_LT:
		return pred2_lt;
	default:
		return pred2_unknown;
	}
}

int
zucimpl_expect_pred2(char const *file, int line,
		     enum zuc_check_op op, enum zuc_check_valtype valtype,
		     bool fatal,
		     intptr_t lhs, intptr_t rhs,
		     const char *lhs_str, const char* rhs_str)
{
	enum zuc_fail_state state = fatal ?  ZUC_CHECK_FATAL : ZUC_CHECK_FAIL;
	comp_pred2 pred = get_pred2(op, valtype);
	int failed = !pred(lhs, rhs);

	validate_types(op, valtype);

	if (failed) {
		mark_failed(g_ctx.curr_test, state);

		if (g_ctx.curr_test)
			migrate_deferred_events(g_ctx.curr_test, false);

		dispatch_check_triggered(&g_ctx,
					 file, line,
					 fatal ? ZUC_CHECK_FATAL
					 : ZUC_CHECK_FAIL,
					 op, valtype,
					 lhs, rhs,
					 lhs_str, rhs_str);
	}
	return failed;
}
