/* SPDX-License-Identifier: GPL-2.0 */
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <linux/ctype.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/zalloc.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <subcmd/exec-cmd.h>
#include <subcmd/parse-options.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <api/io.h>
#include "builtin.h"
#include "tests-scripts.h"
#include "color.h"
#include "debug.h"
#include "hist.h"
#include "intlist.h"
#include "string2.h"
#include "symbol.h"
#include "tests.h"
#include "util/rlimit.h"
#include "util/util.h"

static int shell_tests__dir_fd(void)
{
	struct stat st;
	char path[PATH_MAX], path2[PATH_MAX], *exec_path;
	ssize_t len;
	static const char * const devel_dirs[] = {
		"./tools/perf/tests/shell",
		"./tests/shell",
		"./source/tests/shell"
	};
	int fd;
	char *p;

	for (size_t i = 0; i < ARRAY_SIZE(devel_dirs); ++i) {
		fd = open(devel_dirs[i], O_PATH);

		if (fd >= 0)
			return fd;
	}

	/* Use directory of executable */
	len = readlink("/proc/self/exe", path2, sizeof(path2) - 1);
	if (len < 0)
		return -1;
	path2[len] = '\0';
	/* Follow another level of symlink if there */
	if (lstat(path2, &st) == 0 && (st.st_mode & S_IFMT) == S_IFLNK) {
		scnprintf(path, sizeof(path), "%s", path2);
		len = readlink(path, path2, sizeof(path2) - 1);
		if (len < 0)
			return -1;
		path2[len] = '\0';
	}
	/* Get directory */
	p = strrchr(path2, '/');
	if (p)
		*p = 0;
	scnprintf(path, sizeof(path), "%s/tests/shell", path2);
	fd = open(path, O_PATH);
	if (fd >= 0)
		return fd;
	scnprintf(path, sizeof(path), "%s/source/tests/shell", path2);
	fd = open(path, O_PATH);
	if (fd >= 0)
		return fd;

	/* Then installed path. */
	exec_path = get_argv_exec_path();
	scnprintf(path, sizeof(path), "%s/tests/shell", exec_path);
	free(exec_path);
	return open(path, O_PATH);
}

static char *shell_test__description(int dir_fd, const char *name)
{
	struct io io;
	char buf[128], *line = NULL;
	size_t line_len = 0;
	ssize_t len;
	char *desc = NULL;
	const char *spdx = "SPDX-License";

	io__init(&io, openat(dir_fd, name, O_RDONLY), buf, sizeof(buf));
	if (io.fd < 0)
		return NULL;

	while ((len = io__getline(&io, &line, &line_len)) > 0) {
		char *p = line;

		/* Skip leading whitespace */
		while (*p && isspace(*p))
			p++;

		/* Must be a comment */
		if (*p != '#')
			continue;
		p++;

		/* Skip shebang or SPDX lines */
		if (*p == '!' || (strstr(p, spdx) && strstr(p, "-Identifier:")))
			continue;

		/* Skip whitespace after # */
		while (*p && isspace(*p))
			p++;

		/* If we found non-empty text, this is the description! */
		if (*p && *p != '\n') {
			char *end = p + strlen(p);

			while (end > p && isspace(end[-1]))
				end--;
			*end = '\0';
			desc = strdup(p);
			break;
		}
	}
	free(line);
	close(io.fd);
	return desc;
}

/* Is this full file path a shell script */
static bool is_shell_script(int dir_fd, const char *path)
{
	const char *ext;

	ext = strrchr(path, '.');
	if (!ext)
		return false;
	if (!strcmp(ext, ".sh")) { /* Has .sh extension */
		if (faccessat(dir_fd, path, R_OK | X_OK, 0) == 0) /* Is executable */
			return true;
	}
	return false;
}

/* Is this file in this dir a shell script (for test purposes) */
static bool is_test_script(int dir_fd, const char *name)
{
	return is_shell_script(dir_fd, name);
}

/* Duplicate a string and fall over and die if we run out of memory */
static char *strdup_check(const char *str)
{
	char *newstr;

	newstr = strdup(str);
	if (!newstr) {
		pr_err("Out of memory while duplicating test script string\n");
		abort();
	}
	return newstr;
}

static int shell_test__run(struct test_suite *test, int subtest __maybe_unused)
{
	const char *file = test->priv;
	int err;
	char *cmd = NULL;

	if (asprintf(&cmd, "%s%s", file, verbose ? " -v" : "") < 0)
		return TEST_FAIL;
	err = system(cmd);
	free(cmd);
	if (!err)
		return TEST_OK;

	return WEXITSTATUS(err) == 2 ? TEST_SKIP : TEST_FAIL;
}

static void append_script(int dir_fd, const char *name, char *desc,
			  struct test_suite ***result,
			  size_t *result_sz)
{
	char filename[PATH_MAX], link[128];
	struct test_suite *test_suite, **result_tmp;
	struct test_case *tests;
	ssize_t len;
	char *exclusive;

	snprintf(link, sizeof(link), "/proc/%d/fd/%d", getpid(), dir_fd);
	len = readlink(link, filename, sizeof(filename) - 1);
	if (len < 0 || (size_t)len > sizeof(filename) - strlen(name) - 2) {
		pr_err("Failed to readlink %s or path too long", link);
		return;
	}
	filename[len++] = '/';
	strcpy(&filename[len], name);

	tests = calloc(2, sizeof(*tests));
	if (!tests) {
		pr_err("Out of memory while building script test suite list\n");
		return;
	}
	tests[0].name = strdup_check(name);
	exclusive = strstr(desc, " (exclusive)");
	if (exclusive != NULL) {
		tests[0].exclusive = true;
		exclusive[0] = '\0';
	}
	tests[0].desc = strdup_check(desc);
	tests[0].run_case = shell_test__run;
	test_suite = zalloc(sizeof(*test_suite));
	if (!test_suite) {
		pr_err("Out of memory while building script test suite list\n");
		free(tests);
		return;
	}
	test_suite->desc = desc;
	test_suite->test_cases = tests;
	test_suite->priv = strdup_check(filename);
	/* Realloc is good enough, though we could realloc by chunks, not that
	 * anyone will ever measure performance here */
	result_tmp = realloc(*result, (*result_sz + 1) * sizeof(*result_tmp));
	if (result_tmp == NULL) {
		pr_err("Out of memory while building script test suite list\n");
		free(tests);
		free(test_suite);
		return;
	}
	/* Add file to end and NULL terminate the struct array */
	*result = result_tmp;
	(*result)[*result_sz] = test_suite;
	(*result_sz)++;
}

static void append_scripts_in_dir(int dir_fd,
				  struct test_suite ***result,
				  size_t *result_sz)
{
	struct dirent **entlist;
	struct dirent *ent;
	int n_dirs, i;

	/* List files, sorted by alpha */
	n_dirs = scandirat(dir_fd, ".", &entlist, NULL, alphasort);
	if (n_dirs == -1)
		return;
	for (i = 0; i < n_dirs && (ent = entlist[i]); i++) {
		int fd;

		if (ent->d_name[0] == '.')
			continue; /* Skip hidden files */
		if (is_test_script(dir_fd, ent->d_name)) { /* It's a test */
			char *desc = shell_test__description(dir_fd, ent->d_name);

			if (desc) /* It has a desc line - valid script */
				append_script(dir_fd, ent->d_name, desc, result, result_sz);
			continue;
		}
		if (ent->d_type != DT_DIR) {
			struct stat st;

			if (ent->d_type != DT_UNKNOWN)
				continue;
			fstatat(dir_fd, ent->d_name, &st, 0);
			if (!S_ISDIR(st.st_mode))
				continue;
		}
		if (strncmp(ent->d_name, "base_", 5) == 0)
			continue; /* Skip scripts that have a separate driver. */
		fd = openat(dir_fd, ent->d_name, O_PATH);
		append_scripts_in_dir(fd, result, result_sz);
		close(fd);
	}
	for (i = 0; i < n_dirs; i++) /* Clean up */
		zfree(&entlist[i]);
	free(entlist);
}

struct test_suite **create_script_test_suites(void)
{
	struct test_suite **result = NULL, **result_tmp;
	size_t result_sz = 0;
	int dir_fd = shell_tests__dir_fd(); /* Walk  dir */

	/*
	 * Append scripts if fd is good, otherwise return a NULL terminated zero
	 * length array.
	 */
	if (dir_fd >= 0)
		append_scripts_in_dir(dir_fd, &result, &result_sz);

	result_tmp = realloc(result, (result_sz + 1) * sizeof(*result_tmp));
	if (result_tmp == NULL) {
		pr_err("Out of memory while building script test suite list\n");
		abort();
	}
	/* NULL terminate the test suite array. */
	result = result_tmp;
	result[result_sz] = NULL;
	if (dir_fd >= 0)
		close(dir_fd);
	return result;
}
