/*
 * test-run-command.c: test run command API.
 *
 * (C) 2009 Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
 *
 * This code is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#define DISABLE_SIGN_COMPARE_WARNINGS

#include "test-tool.h"
#include "run-command.h"
#include "strvec.h"
#include "strbuf.h"
#include "parse-options.h"
#include "string-list.h"
#include "thread-utils.h"
#include "wildmatch.h"

static int number_callbacks;
static int parallel_next(struct child_process *cp,
			 struct strbuf *err,
			 void *cb,
			 void **task_cb)
{
	struct child_process *d = cb;
	if (number_callbacks >= 4)
		return 0;

	strvec_pushv(&cp->args, d->args.v);
	cp->in = d->in;
	cp->no_stdin = d->no_stdin;
	if (err)
		strbuf_addstr(err, "preloaded output of a child\n");
	else
		fprintf(stderr, "preloaded output of a child\n");

	number_callbacks++;

	/* test_stdin callback will use this to count remaining lines */
	*task_cb = xmalloc(sizeof(int));
	*(int*)(*task_cb) = 2;

	return 1;
}

static int no_job(struct child_process *cp UNUSED,
		  struct strbuf *err,
		  void *cb UNUSED,
		  void **task_cb UNUSED)
{
	if (err)
		strbuf_addstr(err, "no further jobs available\n");
	else
		fprintf(stderr, "no further jobs available\n");
	return 0;
}

static int task_finished(int result UNUSED,
			 struct strbuf *err,
			 void *pp_cb UNUSED,
			 void *pp_task_cb)
{
	if (err)
		strbuf_addstr(err, "asking for a quick stop\n");
	else
		fprintf(stderr, "asking for a quick stop\n");

	FREE_AND_NULL(pp_task_cb);

	return 1;
}

static int task_finished_quiet(int result UNUSED,
			       struct strbuf *err UNUSED,
			       void *pp_cb UNUSED,
			       void *pp_task_cb)
{
	FREE_AND_NULL(pp_task_cb);
	return 0;
}

static int test_stdin_pipe_feed(int hook_stdin_fd, void *cb UNUSED, void *task_cb)
{
	int *lines_remaining = task_cb;

	if (*lines_remaining) {
		struct strbuf buf = STRBUF_INIT;
		strbuf_addf(&buf, "sample stdin %d\n", --(*lines_remaining));
		if (write_in_full(hook_stdin_fd, buf.buf, buf.len) < 0) {
			if (errno == EPIPE) {
				/* child closed stdin, nothing more to do */
				strbuf_release(&buf);
				return 1;
			}
			die_errno("write");
		}
		strbuf_release(&buf);
	}

	return !(*lines_remaining);
}

struct testsuite {
	struct string_list tests, failed;
	int next;
	int quiet, immediate, verbose, verbose_log, trace, write_junit_xml;
	const char *shell_path;
};
#define TESTSUITE_INIT { \
	.tests = STRING_LIST_INIT_DUP, \
	.failed = STRING_LIST_INIT_DUP, \
}

static int next_test(struct child_process *cp, struct strbuf *err, void *cb,
		     void **task_cb)
{
	struct testsuite *suite = cb;
	const char *test;
	if (suite->next >= suite->tests.nr)
		return 0;

	test = suite->tests.items[suite->next++].string;
	if (suite->shell_path)
		strvec_push(&cp->args, suite->shell_path);
	strvec_push(&cp->args, test);
	if (suite->quiet)
		strvec_push(&cp->args, "--quiet");
	if (suite->immediate)
		strvec_push(&cp->args, "-i");
	if (suite->verbose)
		strvec_push(&cp->args, "-v");
	if (suite->verbose_log)
		strvec_push(&cp->args, "-V");
	if (suite->trace)
		strvec_push(&cp->args, "-x");
	if (suite->write_junit_xml)
		strvec_push(&cp->args, "--write-junit-xml");

	strbuf_addf(err, "Output of '%s':\n", test);
	*task_cb = (void *)test;

	return 1;
}

static int test_finished(int result, struct strbuf *err, void *cb,
			 void *task_cb)
{
	struct testsuite *suite = cb;
	const char *name = (const char *)task_cb;

	if (result)
		string_list_append(&suite->failed, name);

	strbuf_addf(err, "%s: '%s'\n", result ? "FAIL" : "SUCCESS", name);

	return 0;
}

static int test_failed(struct strbuf *out, void *cb, void *task_cb)
{
	struct testsuite *suite = cb;
	const char *name = (const char *)task_cb;

	string_list_append(&suite->failed, name);
	strbuf_addf(out, "FAILED TO START: '%s'\n", name);

	return 0;
}

static const char * const testsuite_usage[] = {
	"test-run-command testsuite [<options>] [<pattern>...]",
	NULL
};

static int testsuite(int argc, const char **argv)
{
	struct testsuite suite = TESTSUITE_INIT;
	int max_jobs = 1, i, ret = 0;
	DIR *dir;
	struct dirent *d;
	struct option options[] = {
		OPT_BOOL('i', "immediate", &suite.immediate,
			 "stop at first failed test case(s)"),
		OPT_INTEGER('j', "jobs", &max_jobs, "run <N> jobs in parallel"),
		OPT_BOOL('q', "quiet", &suite.quiet, "be terse"),
		OPT_BOOL('v', "verbose", &suite.verbose, "be verbose"),
		OPT_BOOL('V', "verbose-log", &suite.verbose_log,
			 "be verbose, redirected to a file"),
		OPT_BOOL('x', "trace", &suite.trace, "trace shell commands"),
		OPT_BOOL(0, "write-junit-xml", &suite.write_junit_xml,
			 "write JUnit-style XML files"),
		OPT_END()
	};
	struct run_process_parallel_opts opts = {
		.get_next_task = next_test,
		.start_failure = test_failed,
		.feed_pipe = test_stdin_pipe_feed,
		.task_finished = test_finished,
		.data = &suite,
	};
	struct strbuf progpath = STRBUF_INIT;
	size_t path_prefix_len;

	argc = parse_options(argc, argv, NULL, options,
			testsuite_usage, PARSE_OPT_STOP_AT_NON_OPTION);

	if (max_jobs <= 0)
		max_jobs = online_cpus();

	/*
	 * If we run without a shell, execute the programs directly from CWD.
	 */
	suite.shell_path = getenv("TEST_SHELL_PATH");
	if (!suite.shell_path)
		strbuf_addstr(&progpath, "./");
	path_prefix_len = progpath.len;

	dir = opendir(".");
	if (!dir)
		die("Could not open the current directory");
	while ((d = readdir(dir))) {
		const char *p = d->d_name;

		if (!strcmp(p, ".") || !strcmp(p, ".."))
			continue;

		/* No pattern: match all */
		if (!argc) {
			strbuf_setlen(&progpath, path_prefix_len);
			strbuf_addstr(&progpath, p);
			string_list_append(&suite.tests, progpath.buf);
			continue;
		}

		for (i = 0; i < argc; i++)
			if (!wildmatch(argv[i], p, 0)) {
				strbuf_setlen(&progpath, path_prefix_len);
				strbuf_addstr(&progpath, p);
				string_list_append(&suite.tests, progpath.buf);
				break;
			}
	}
	closedir(dir);

	if (!suite.tests.nr)
		die("No tests match!");
	if (max_jobs > suite.tests.nr)
		max_jobs = suite.tests.nr;

	fprintf(stderr, "Running %"PRIuMAX" tests (%d at a time)\n",
		(uintmax_t)suite.tests.nr, max_jobs);

	opts.processes = max_jobs;
	run_processes_parallel(&opts);

	if (suite.failed.nr > 0) {
		ret = 1;
		fprintf(stderr, "%"PRIuMAX" tests failed:\n\n",
			(uintmax_t)suite.failed.nr);
		for (i = 0; i < suite.failed.nr; i++)
			fprintf(stderr, "\t%s\n", suite.failed.items[i].string);
	}

	string_list_clear(&suite.tests, 0);
	string_list_clear(&suite.failed, 0);
	strbuf_release(&progpath);

	return ret;
}

static uint64_t my_random_next = 1234;

static uint64_t my_random(void)
{
	uint64_t res = my_random_next;
	my_random_next = my_random_next * 1103515245 + 12345;
	return res;
}

static int quote_stress_test(int argc, const char **argv)
{
	/*
	 * We are running a quote-stress test.
	 * spawn a subprocess that runs quote-stress with a
	 * special option that echoes back the arguments that
	 * were passed in.
	 */
	char special[] = ".?*\\^_\"'`{}()[]<>@~&+:;$%"; // \t\r\n\a";
	int i, j, k, trials = 100, skip = 0, msys2 = 0;
	struct strbuf out = STRBUF_INIT;
	struct strvec args = STRVEC_INIT;
	struct option options[] = {
		OPT_INTEGER('n', "trials", &trials, "number of trials"),
		OPT_INTEGER('s', "skip", &skip, "skip <n> trials"),
		OPT_BOOL('m', "msys2", &msys2, "test quoting for MSYS2's sh"),
		OPT_END()
	};
	const char * const usage[] = {
		"test-tool run-command quote-stress-test <options>",
		NULL
	};

	argc = parse_options(argc, argv, NULL, options, usage, 0);

	setenv("MSYS_NO_PATHCONV", "1", 0);

	for (i = 0; i < trials; i++) {
		struct child_process cp = CHILD_PROCESS_INIT;
		size_t arg_count, arg_offset;
		int ret = 0;

		strvec_clear(&args);
		if (msys2)
			strvec_pushl(&args, "sh", "-c",
				     "printf %s\\\\0 \"$@\"", "skip", NULL);
		else
			strvec_pushl(&args, "test-tool", "run-command",
				     "quote-echo", NULL);
		arg_offset = args.nr;

		if (argc > 0) {
			trials = 1;
			arg_count = argc;
			for (j = 0; j < arg_count; j++)
				strvec_push(&args, argv[j]);
		} else {
			arg_count = 1 + (my_random() % 5);
			for (j = 0; j < arg_count; j++) {
				char buf[20];
				size_t min_len = 1;
				size_t arg_len = min_len +
					(my_random() % (ARRAY_SIZE(buf) - min_len));

				for (k = 0; k < arg_len; k++)
					buf[k] = special[my_random() %
						ARRAY_SIZE(special)];
				buf[arg_len] = '\0';

				strvec_push(&args, buf);
			}
		}

		if (i < skip)
			continue;

		strvec_pushv(&cp.args, args.v);
		strbuf_reset(&out);
		if (pipe_command(&cp, NULL, 0, &out, 0, NULL, 0) < 0)
			return error("Failed to spawn child process");

		for (j = 0, k = 0; j < arg_count; j++) {
			const char *arg = args.v[j + arg_offset];

			if (strcmp(arg, out.buf + k))
				ret = error("incorrectly quoted arg: '%s', "
					    "echoed back as '%s'",
					     arg, out.buf + k);
			k += strlen(out.buf + k) + 1;
		}

		if (k != out.len)
			ret = error("got %d bytes, but consumed only %d",
				     (int)out.len, (int)k);

		if (ret) {
			fprintf(stderr, "Trial #%d failed. Arguments:\n", i);
			for (j = 0; j < arg_count; j++)
				fprintf(stderr, "arg #%d: '%s'\n",
					(int)j, args.v[j + arg_offset]);

			strbuf_release(&out);
			strvec_clear(&args);

			return ret;
		}

		if (i && (i % 100) == 0)
			fprintf(stderr, "Trials completed: %d\n", (int)i);
	}

	strbuf_release(&out);
	strvec_clear(&args);

	return 0;
}

static int quote_echo(int argc, const char **argv)
{
	while (argc > 1) {
		fwrite(argv[1], strlen(argv[1]), 1, stdout);
		fputc('\0', stdout);
		argv++;
		argc--;
	}

	return 0;
}

static int inherit_handle(const char *argv0)
{
	struct child_process cp = CHILD_PROCESS_INIT;
	char path[PATH_MAX];
	int tmp;

	/* First, open an inheritable handle */
	xsnprintf(path, sizeof(path), "out-XXXXXX");
	tmp = xmkstemp(path);

	strvec_pushl(&cp.args,
		     "test-tool", argv0, "inherited-handle-child", NULL);
	cp.in = -1;
	cp.no_stdout = cp.no_stderr = 1;
	if (start_command(&cp) < 0)
		die("Could not start child process");

	/* Then close it, and try to delete it. */
	close(tmp);
	if (unlink(path))
		die("Could not delete '%s'", path);

	if (close(cp.in) < 0 || finish_command(&cp) < 0)
		die("Child did not finish");

	return 0;
}

static int inherit_handle_child(void)
{
	struct strbuf buf = STRBUF_INIT;

	if (strbuf_read(&buf, 0, 0) < 0)
		die("Could not read stdin");
	printf("Received %s\n", buf.buf);
	strbuf_release(&buf);

	return 0;
}

int cmd__run_command(int argc, const char **argv)
{
	struct child_process proc = CHILD_PROCESS_INIT;
	int jobs;
	int ret;
	struct run_process_parallel_opts opts = {
		.data = &proc,
	};

	if (argc > 1 && !strcmp(argv[1], "testsuite"))
		return testsuite(argc - 1, argv + 1);
	if (!strcmp(argv[1], "inherited-handle"))
		return inherit_handle(argv[0]);
	if (!strcmp(argv[1], "inherited-handle-child"))
		return inherit_handle_child();

	if (argc >= 2 && !strcmp(argv[1], "quote-stress-test"))
		return !!quote_stress_test(argc - 1, argv + 1);

	if (argc >= 2 && !strcmp(argv[1], "quote-echo"))
		return !!quote_echo(argc - 1, argv + 1);

	if (argc < 3)
		return 1;
	while (!strcmp(argv[1], "env")) {
		if (!argv[2])
			die("env specifier without a value");
		strvec_push(&proc.env, argv[2]);
		argv += 2;
		argc -= 2;
	}
	if (argc < 3) {
		ret = 1;
		goto cleanup;
	}
	strvec_pushv(&proc.args, (const char **)argv + 2);

	if (!strcmp(argv[1], "start-command-ENOENT")) {
		if (start_command(&proc) < 0 && errno == ENOENT) {
			ret = 0;
			goto cleanup;
		}
		fprintf(stderr, "FAIL %s\n", argv[1]);
		return 1;
	}
	if (!strcmp(argv[1], "run-command")) {
		ret = run_command(&proc);
		goto cleanup;
	}

	if (!strcmp(argv[1], "--ungroup")) {
		argv += 1;
		argc -= 1;
		opts.ungroup = 1;
	}

	jobs = atoi(argv[2]);
	strvec_clear(&proc.args);
	strvec_pushv(&proc.args, (const char **)argv + 3);

	if (!strcmp(argv[1], "run-command-parallel")) {
		opts.get_next_task = parallel_next;
		opts.task_finished = task_finished_quiet;
	} else if (!strcmp(argv[1], "run-command-abort")) {
		opts.get_next_task = parallel_next;
		opts.task_finished = task_finished;
	} else if (!strcmp(argv[1], "run-command-no-jobs")) {
		opts.get_next_task = no_job;
		opts.task_finished = task_finished;
	} else if (!strcmp(argv[1], "run-command-stdin")) {
		proc.in = -1;
		proc.no_stdin = 0;
		opts.get_next_task = parallel_next;
		opts.task_finished = task_finished_quiet;
		opts.feed_pipe = test_stdin_pipe_feed;
	} else {
		ret = 1;
		fprintf(stderr, "check usage\n");
		goto cleanup;
	}
	opts.processes = jobs;
	run_processes_parallel(&opts);
	ret = 0;
cleanup:
	child_process_clear(&proc);
	return ret;
}
