/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2012  Intel Corporation. All rights reserved.
 *
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/signalfd.h>

#include <glib.h>

#include "src/shared/tester.h"

#define COLOR_OFF	"\x1B[0m"
#define COLOR_BLACK	"\x1B[0;30m"
#define COLOR_RED	"\x1B[0;31m"
#define COLOR_GREEN	"\x1B[0;32m"
#define COLOR_YELLOW	"\x1B[0;33m"
#define COLOR_BLUE	"\x1B[0;34m"
#define COLOR_MAGENTA	"\x1B[0;35m"
#define COLOR_CYAN	"\x1B[0;36m"
#define COLOR_WHITE	"\x1B[0;37m"
#define COLOR_HIGHLIGHT	"\x1B[1;39m"

#define print_text(color, fmt, args...) \
		printf(color fmt COLOR_OFF "\n", ## args)

#define print_summary(label, color, value, fmt, args...) \
			printf("%-45s " color "%-10s" COLOR_OFF fmt "\n", \
							label, value, ## args)
 
#define print_progress(name, color, fmt, args...) \
		printf(COLOR_HIGHLIGHT "%s" COLOR_OFF " - " \
				color fmt COLOR_OFF "\n", name, ## args)

enum test_result {
	TEST_RESULT_NOT_RUN,
	TEST_RESULT_PASSED,
	TEST_RESULT_FAILED,
};

enum test_stage {
	TEST_STAGE_INVALID,
	TEST_STAGE_PRE_SETUP,
	TEST_STAGE_SETUP,
	TEST_STAGE_RUN,
	TEST_STAGE_TEARDOWN,
	TEST_STAGE_POST_TEARDOWN,
};

struct test_case {
	char *name;
	enum test_result result;
	enum test_stage stage;
	const void *test_data;
	tester_data_func_t pre_setup_func;
	tester_data_func_t setup_func;
	tester_data_func_t test_func;
	tester_data_func_t teardown_func;
	tester_data_func_t post_teardown_func;
	gdouble start_time;
	gdouble end_time;
	tester_destroy_func_t destroy;
	void *user_data;
};

static GMainLoop *main_loop;

static GList *test_list;
static GList *test_current;
static GTimer *test_timer;

static void test_destroy(gpointer data)
{
	struct test_case *test = data;

	if (test->destroy)
		test->destroy(test->user_data);

	g_free(test->name);
	g_free(test);
}

void tester_print(const char *format, ...)
{
	va_list ap;

	if (tester_use_quiet())
		return;

	printf("  %s", COLOR_WHITE);
	va_start(ap, format);
	vprintf(format, ap);
	va_end(ap);
	printf("%s\n", COLOR_OFF);
}

void tester_warn(const char *format, ...)
{
	va_list ap;

	printf("  %s", COLOR_WHITE);
	va_start(ap, format);
	vprintf(format, ap);
	va_end(ap);
	printf("%s\n", COLOR_OFF);
}

static void default_pre_setup(const void *test_data)
{
	tester_pre_setup_complete();
}

static void default_setup(const void *test_data)
{
	tester_setup_complete();
}

static void default_teardown(const void *test_data)
{
	tester_teardown_complete();
}

static void default_post_teardown(const void *test_data)
{
	tester_post_teardown_complete();
}

void tester_add_full(const char *name, const void *test_data,
				tester_data_func_t pre_setup_func,
				tester_data_func_t setup_func,
				tester_data_func_t test_func,
				tester_data_func_t teardown_func,
				tester_data_func_t post_teardown_func,
				void *user_data, tester_destroy_func_t destroy)
{
	struct test_case *test;

	if (!test_func)
		return;

	test = g_new0(struct test_case, 1);

	test->name = g_strdup(name);
	test->result = TEST_RESULT_NOT_RUN;
	test->stage = TEST_STAGE_INVALID;

	test->test_data = test_data;

	if (pre_setup_func)
		test->pre_setup_func = pre_setup_func;
	else
		test->pre_setup_func = default_pre_setup;

	if (setup_func)
		test->setup_func = setup_func;
	else
		test->setup_func = default_setup;

	test->test_func = test_func;

	if (teardown_func)
		test->teardown_func = teardown_func;
	else
		test->teardown_func = default_teardown;

	if (post_teardown_func)
		test->post_teardown_func = post_teardown_func;
	else
		test->post_teardown_func = default_post_teardown;

	test->destroy = destroy;
	test->user_data = user_data;

	test_list = g_list_append(test_list, test);
}

void tester_add(const char *name, const void *test_data,
					tester_data_func_t setup_func,
					tester_data_func_t test_func,
					tester_data_func_t teardown_func)
{
	tester_add_full(name, test_data, NULL, setup_func, test_func,
					teardown_func, NULL, NULL, NULL);
}

void *tester_get_data(void)
{
	struct test_case *test;

	if (!test_current)
		return NULL;

	test = test_current->data;

	return test->user_data;
}

static void tester_summarize(void)
{
	unsigned int not_run = 0, passed = 0, failed = 0;
	gdouble execution_time;
	GList *list;

	printf("\n");
	print_text(COLOR_HIGHLIGHT, "");
	print_text(COLOR_HIGHLIGHT, "Test Summary");
	print_text(COLOR_HIGHLIGHT, "------------");

	for (list = g_list_first(test_list); list; list = g_list_next(list)) {
		struct test_case *test = list->data;
		gdouble exec_time;

		exec_time = test->end_time - test->start_time;

		switch (test->result) {
		case TEST_RESULT_NOT_RUN:
			print_summary(test->name, COLOR_YELLOW, "Not Run", "");
			not_run++;
			break;
		case TEST_RESULT_PASSED:
			print_summary(test->name, COLOR_GREEN, "Passed",
						"%8.3f seconds", exec_time);
			passed++;
			break;
		case TEST_RESULT_FAILED:
			print_summary(test->name, COLOR_RED, "Failed",
						"%8.3f seconds", exec_time);
			failed++;
			break;
		}
        }

	printf("\nTotal: %d, "
		COLOR_GREEN "Passed: %d (%.1f%%)" COLOR_OFF ", "
		COLOR_RED "Failed: %d" COLOR_OFF ", "
		COLOR_YELLOW "Not Run: %d" COLOR_OFF "\n",
			not_run + passed + failed, passed,
			(float) passed * 100 / (not_run + passed + failed),
			failed, not_run);

	execution_time = g_timer_elapsed(test_timer, NULL);
	printf("Overall execution time: %.3g seconds\n", execution_time);

}

static void next_test_case(void)
{
	struct test_case *test;

	if (test_current)
		test_current = g_list_next(test_current);
	else
		test_current = test_list;

	if (!test_current) {
		g_timer_stop(test_timer);

		g_main_loop_quit(main_loop);
		return;
	}

	test = test_current->data;

	printf("\n");
	print_progress(test->name, COLOR_BLACK, "init");

	test->start_time = g_timer_elapsed(test_timer, NULL);

	test->stage = TEST_STAGE_PRE_SETUP;

	test->pre_setup_func(test->test_data);
}

static gboolean setup_callback(gpointer user_data)
{
	struct test_case *test = user_data;

	test->stage = TEST_STAGE_SETUP;

	print_progress(test->name, COLOR_BLUE, "setup");
	test->setup_func(test->test_data);

	return FALSE;
}

static gboolean run_callback(gpointer user_data)
{
	struct test_case *test = user_data;

	test->stage = TEST_STAGE_RUN;

	print_progress(test->name, COLOR_BLACK, "run");
	test->test_func(test->test_data);

	return FALSE;
}

static gboolean teardown_callback(gpointer user_data)
{
	struct test_case *test = user_data;

	test->stage = TEST_STAGE_TEARDOWN;

	print_progress(test->name, COLOR_MAGENTA, "teardown");
	test->teardown_func(test->test_data);

	return FALSE;
}

static gboolean done_callback(gpointer user_data)
{
	struct test_case *test = user_data;

	test->end_time = g_timer_elapsed(test_timer, NULL);

	print_progress(test->name, COLOR_BLACK, "done");
	next_test_case();

	return FALSE;
}

void tester_pre_setup_complete(void)
{
	struct test_case *test;

	if (!test_current)
		return;

	test = test_current->data;

	if (test->stage != TEST_STAGE_PRE_SETUP)
		return;

	g_idle_add(setup_callback, test);
}

void tester_pre_setup_failed(void)
{
	struct test_case *test;

	if (!test_current)
		return;

	test = test_current->data;

	if (test->stage != TEST_STAGE_PRE_SETUP)
		return;

	test->stage = TEST_STAGE_SETUP;

	tester_setup_failed();
}

void tester_setup_complete(void)
{
	struct test_case *test;

	if (!test_current)
		return;

	test = test_current->data;

	if (test->stage != TEST_STAGE_SETUP)
		return;

	print_progress(test->name, COLOR_BLUE, "setup complete");

	g_idle_add(run_callback, test);
}

void tester_setup_failed(void)
{
	struct test_case *test;

	if (!test_current)
		return;

	test = test_current->data;

	if (test->stage != TEST_STAGE_SETUP)
		return;

	print_progress(test->name, COLOR_RED, "setup failed");

	g_idle_add(done_callback, test);
}

void tester_test_passed(void)
{
	struct test_case *test;

	if (!test_current)
		return;

	test = test_current->data;

	if (test->stage != TEST_STAGE_RUN)
		return;

	test->result = TEST_RESULT_PASSED;
	print_progress(test->name, COLOR_GREEN, "test passed");

	g_idle_add(teardown_callback, test);
}

void tester_test_failed(void)
{
	struct test_case *test;

	if (!test_current)
		return;

	test = test_current->data;

	if (test->stage != TEST_STAGE_RUN)
		return;

	test->result = TEST_RESULT_FAILED;
	print_progress(test->name, COLOR_RED, "test failed");

	g_idle_add(teardown_callback, test);
}

void tester_teardown_complete(void)
{
	struct test_case *test;

	if (!test_current)
		return;

	test = test_current->data;

	if (test->stage != TEST_STAGE_TEARDOWN)
		return;

	test->stage = TEST_STAGE_POST_TEARDOWN;

	test->post_teardown_func(test->test_data);
}

void tester_teardown_failed(void)
{
	struct test_case *test;

	if (!test_current)
		return;

	test = test_current->data;

	if (test->stage != TEST_STAGE_TEARDOWN)
		return;

	test->stage = TEST_STAGE_POST_TEARDOWN;

	tester_post_teardown_failed();
}

void tester_post_teardown_complete(void)
{
	struct test_case *test;

	if (!test_current)
		return;

	test = test_current->data;

	if (test->stage != TEST_STAGE_POST_TEARDOWN)
		return;

	print_progress(test->name, COLOR_MAGENTA, "teardown complete");

	g_idle_add(done_callback, test);
}

void tester_post_teardown_failed(void)
{
	struct test_case *test;

	if (!test_current)
		return;

	test = test_current->data;

	if (test->stage != TEST_STAGE_POST_TEARDOWN)
		return;

	print_progress(test->name, COLOR_RED, "teardown failed");

	g_idle_add(done_callback, test);
}

static gboolean start_tester(gpointer user_data)
{
	test_timer = g_timer_new();

	next_test_case();

	return FALSE;
}

struct wait_data {
	unsigned int seconds;
	struct test_case *test;
	tester_wait_func_t func;
	void *user_data;
};

static gboolean wait_callback(gpointer user_data)
{
	struct wait_data *wait = user_data;
	struct test_case *test = wait->test;

	wait->seconds--;

	if (wait->seconds > 0) {
		print_progress(test->name, COLOR_BLACK, "%u seconds left",
								wait->seconds);
		return TRUE;
	}

	print_progress(test->name, COLOR_BLACK, "waiting done");

	wait->func(wait->user_data);

	g_free(wait);

	return FALSE;
}

void tester_wait(unsigned int seconds, tester_wait_func_t func,
							void *user_data)
{
	struct test_case *test;
	struct wait_data *wait;

	if (!func || seconds < 1)
		return;

	if (!test_current)
		return;

	test = test_current->data;

	print_progress(test->name, COLOR_BLACK, "waiting %u seconds", seconds);

	wait = g_new0(struct wait_data, 1);

	wait->seconds = seconds;
	wait->test = test;
	wait->func = func;
	wait->user_data = user_data;

	g_timeout_add(1000, wait_callback, wait);
}

static gboolean signal_handler(GIOChannel *channel, GIOCondition condition,
							gpointer user_data)
{
	static unsigned int __terminated = 0;
	struct signalfd_siginfo si;
	ssize_t result;
	int fd;

	if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
		g_main_loop_quit(main_loop);
		return FALSE;
	}

	fd = g_io_channel_unix_get_fd(channel);

	result = read(fd, &si, sizeof(si));
	if (result != sizeof(si))
		return FALSE;

	switch (si.ssi_signo) {
	case SIGINT:
	case SIGTERM:
		if (__terminated == 0)
			g_main_loop_quit(main_loop);

		__terminated = 1;
		break;
	}

	return TRUE;
}

static guint setup_signalfd(void)
{
	GIOChannel *channel;
	guint source;
	sigset_t mask;
	int fd;

	sigemptyset(&mask);
	sigaddset(&mask, SIGINT);
	sigaddset(&mask, SIGTERM);

	if (sigprocmask(SIG_BLOCK, &mask, NULL) < 0) {
		perror("Failed to set signal mask");
		return 0;
	}

	fd = signalfd(-1, &mask, 0);
	if (fd < 0) {
		perror("Failed to create signal descriptor");
		return 0;
	}

	channel = g_io_channel_unix_new(fd);

	g_io_channel_set_close_on_unref(channel, TRUE);
	g_io_channel_set_encoding(channel, NULL, NULL);
	g_io_channel_set_buffered(channel, FALSE);

	source = g_io_add_watch(channel,
				G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
				signal_handler, NULL);

	g_io_channel_unref(channel);

	return source;
}

static gboolean option_version = FALSE;
static gboolean option_quiet = FALSE;
static gboolean option_debug = FALSE;

bool tester_use_quiet(void)
{
	return option_quiet == TRUE ? true : false;
}

bool tester_use_debug(void)
{
	return option_debug == TRUE ? true : false;
}

static GOptionEntry options[] = {
	{ "version", 'v', 0, G_OPTION_ARG_NONE, &option_version,
				"Show version information and exit" },
	{ "quiet", 'q', 0, G_OPTION_ARG_NONE, &option_quiet,
				"Run tests without logging" },
	{ "debug", 'd', 0, G_OPTION_ARG_NONE, &option_debug,
				"Run tests with debug output" },
	{ NULL },
};

void tester_init(int *argc, char ***argv)
{
	GOptionContext *context;
	GError *error = NULL;

	context = g_option_context_new(NULL);
	g_option_context_add_main_entries(context, options, NULL);

	if (g_option_context_parse(context, argc, argv, &error) == FALSE) {
		if (error != NULL) {
			g_printerr("%s\n", error->message);
			g_error_free(error);
		} else
			g_printerr("An unknown error occurred\n");
		exit(1);
	}

	g_option_context_free(context);

	if (option_version == TRUE) {
		g_print("%s\n", VERSION);
		exit(EXIT_SUCCESS);
	}

	main_loop = g_main_loop_new(NULL, FALSE);

	test_list = NULL;
	test_current = NULL;
}

int tester_run(void)
{
	guint signal;

	if (!main_loop)
		return EXIT_FAILURE;

	signal = setup_signalfd();

	g_idle_add(start_tester, NULL);
	g_main_loop_run(main_loop);

	g_source_remove(signal);

	g_main_loop_unref(main_loop);

	tester_summarize();

	g_list_free_full(test_list, test_destroy);

	return EXIT_SUCCESS;
}
