/*
 * libusbx test library helper functions
 * Copyright © 2012 Toby Gray <toby.gray@realvnc.com>
 *
 * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include "libusbx_testlib.h"

#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#if !defined(_WIN32_WCE)
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#endif

#if defined(_WIN32_WCE)
// No support for selective redirection of STDOUT on WinCE.
#define DISABLE_STDOUT_REDIRECTION
#define STDOUT_FILENO 1
#elif defined(_WIN32)
#include <io.h>
#define dup _dup
#define dup2 _dup2
#define open _open
#define close _close
#define fdopen _fdopen
#define NULL_PATH "nul"
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
#else
#include <unistd.h>
#define NULL_PATH "/dev/null"
#endif
#define INVALID_FD -1
#define IGNORE_RETVAL(expr) do { (void)(expr); } while(0)

/**
 * Converts a test result code into a human readable string.
 */
static const char* test_result_to_str(libusbx_testlib_result result)
{
	switch (result) {
	case TEST_STATUS_SUCCESS:
		return "Success";
	case TEST_STATUS_FAILURE:
		return "Failure";
	case TEST_STATUS_ERROR:
		return "Error";
	case TEST_STATUS_SKIP:
		return "Skip";
	default:
		return "Unknown";
	}
}

static void print_usage(int argc, char ** argv)
{
	printf("Usage: %s [-l] [-v] [<test_name> ...]\n",
		argc > 0 ? argv[0] : "test_*");
	printf("   -l   List available tests\n");
	printf("   -v   Don't redirect STDERR/STDOUT during tests\n");
}

static void cleanup_test_output(libusbx_testlib_ctx * ctx)
{
#ifndef DISABLE_STDOUT_REDIRECTION
	if (!ctx->verbose) {
		if (ctx->old_stdout != INVALID_FD) {
			IGNORE_RETVAL(dup2(ctx->old_stdout, STDOUT_FILENO));
			ctx->old_stdout = INVALID_FD;
		}
		if (ctx->old_stderr != INVALID_FD) {
			IGNORE_RETVAL(dup2(ctx->old_stderr, STDERR_FILENO));
			ctx->old_stderr = INVALID_FD;
		}
		if (ctx->null_fd != INVALID_FD) {
			close(ctx->null_fd);
			ctx->null_fd = INVALID_FD;
		}
		if (ctx->output_file != stdout) {
			fclose(ctx->output_file);
			ctx->output_file = stdout;
		}
	}
#endif
}

/**
 * Setup test output handles
 * \return zero on success, non-zero on failure
 */
static int setup_test_output(libusbx_testlib_ctx * ctx)
{
#ifndef DISABLE_STDOUT_REDIRECTION
	/* Stop output to stdout and stderr from being displayed if using non-verbose output */
	if (!ctx->verbose) {
		/* Keep a copy of STDOUT and STDERR */
		ctx->old_stdout = dup(STDOUT_FILENO);
		if (ctx->old_stdout < 0) {
			ctx->old_stdout = INVALID_FD;
			printf("Failed to duplicate stdout handle: %d\n", errno);
			return 1;
		}
		ctx->old_stderr = dup(STDERR_FILENO);
		if (ctx->old_stderr < 0) {
			ctx->old_stderr = INVALID_FD;
			cleanup_test_output(ctx);
			printf("Failed to duplicate stderr handle: %d\n", errno);
			return 1;
		}
		/* Redirect STDOUT_FILENO and STDERR_FILENO to /dev/null or "nul"*/
		ctx->null_fd = open(NULL_PATH, O_WRONLY);
		if (ctx->null_fd < 0) {
			ctx->null_fd = INVALID_FD;
			cleanup_test_output(ctx);
			printf("Failed to open null handle: %d\n", errno);
			return 1;
		}
		if ((dup2(ctx->null_fd, STDOUT_FILENO) < 0) ||
			(dup2(ctx->null_fd, STDERR_FILENO) < 0)) {
				cleanup_test_output(ctx);
				return 1;
		}
		ctx->output_file = fdopen(ctx->old_stdout, "w");
		if (!ctx->output_file) {
			cleanup_test_output(ctx);
			printf("Failed to open FILE for output handle: %d\n", errno);
			return 1;
		}
	}
#endif
	return 0;
}

void libusbx_testlib_logf(libusbx_testlib_ctx * ctx,
	const char* fmt, ...)
{
	va_list va;
	va_start(va, fmt);
	vfprintf(ctx->output_file, fmt, va);
	va_end(va);
	fprintf(ctx->output_file, "\n");
	fflush(ctx->output_file);
}

int libusbx_testlib_run_tests(int argc,
	char ** argv,
	const libusbx_testlib_test * tests)
{
	int run_count = 0;
	int idx = 0;
	int pass_count = 0;
	int fail_count = 0;
	int error_count = 0;
	int skip_count = 0;
	int r, j;
	size_t arglen;
	libusbx_testlib_result test_result;
	libusbx_testlib_ctx ctx;

	/* Setup default mode of operation */
	ctx.test_names = NULL;
	ctx.test_count = 0;
	ctx.list_tests = false;
	ctx.verbose = false;
	ctx.old_stdout = INVALID_FD;
	ctx.old_stderr = INVALID_FD;
	ctx.output_file = stdout;
	ctx.null_fd = INVALID_FD;

	/* Parse command line options */
	if (argc >= 2) {
		for (j = 1; j < argc; j++) {
			arglen = strlen(argv[j]);
			if ( ((argv[j][0] == '-') || (argv[j][0] == '/')) &&
				arglen >=2 ) {
					switch (argv[j][1]) {
					case 'l':
						ctx.list_tests = true;
						break;
					case 'v':
						ctx.verbose = true;
						break;
					default:
						printf("Unknown option: '%s'\n", argv[j]);
						print_usage(argc, argv);
						return 1;
					}
			} else {
				/* End of command line options, remaining must be list of tests to run */
				ctx.test_names = argv + j;
				ctx.test_count = argc - j;
				break;
			}
		}
	}

	/* Validate command line options */
	if (ctx.test_names && ctx.list_tests) {
		printf("List of tests requested but test list provided\n");
		print_usage(argc, argv);
		return 1;
	}

	/* Setup test log output */
	r = setup_test_output(&ctx);
	if (r != 0)
		return r;  

	/* Act on any options not related to running tests */
	if (ctx.list_tests) {
		while (tests[idx].function != NULL) {
			libusbx_testlib_logf(&ctx, tests[idx].name);
			++idx;
		}
		cleanup_test_output(&ctx);
		return 0;
	}

	/* Run any requested tests */
	while (tests[idx].function != NULL) {
		const libusbx_testlib_test * test = &tests[idx];
		++idx;
		if (ctx.test_count > 0) {
			/* Filtering tests to run, check if this is one of them */
			int i;
			for (i = 0; i < ctx.test_count; ++i) {
				if (strcmp(ctx.test_names[i], test->name) == 0)
					/* Matches a requested test name */
					break;
			}
			if (i >= ctx.test_count) {
				/* Failed to find a test match, so do the next loop iteration */
				continue;
			}
		}
		libusbx_testlib_logf(&ctx,
			"Starting test run: %s...", test->name);
		test_result = test->function(&ctx);
		libusbx_testlib_logf(&ctx,
			"%s (%d)",
			test_result_to_str(test_result), test_result);
		switch (test_result) {
		case TEST_STATUS_SUCCESS: pass_count++; break;
		case TEST_STATUS_FAILURE: fail_count++; break;
		case TEST_STATUS_ERROR: error_count++; break;
		case TEST_STATUS_SKIP: skip_count++; break;
		}
		++run_count;
	}
	libusbx_testlib_logf(&ctx, "---");
	libusbx_testlib_logf(&ctx, "Ran %d tests", run_count);
	libusbx_testlib_logf(&ctx, "Passed %d tests", pass_count);
	libusbx_testlib_logf(&ctx, "Failed %d tests", fail_count);
	libusbx_testlib_logf(&ctx, "Error in %d tests", error_count);
	libusbx_testlib_logf(&ctx, "Skipped %d tests", skip_count);

	cleanup_test_output(&ctx);
	return pass_count != run_count;
}
