/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2017  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 <stdarg.h>
#include <stdbool.h>
#include <signal.h>
#include <sys/signalfd.h>
#include <wordexp.h>
#include <getopt.h>

#include <readline/readline.h>
#include <readline/history.h>

#include "src/shared/mainloop.h"
#include "src/shared/timeout.h"
#include "src/shared/io.h"
#include "src/shared/util.h"
#include "src/shared/queue.h"
#include "src/shared/shell.h"

#define CMD_LENGTH	48
#define print_text(color, fmt, args...) \
		printf(color fmt COLOR_OFF "\n", ## args)
#define print_menu(cmd, args, desc) \
		printf(COLOR_HIGHLIGHT "%s %-*s " COLOR_OFF "%s\n", \
			cmd, (int)(CMD_LENGTH - strlen(cmd)), args, desc)
#define print_submenu(cmd, desc) \
		printf(COLOR_BLUE "%s %-*s " COLOR_OFF "%s\n", \
			cmd, (int)(CMD_LENGTH - strlen(cmd)), "", desc)

struct bt_shell_env {
	char *name;
	void *value;
};

static struct {
	bool init;
	char *name;
	char history[256];
	int argc;
	char **argv;
	bool mode;
	int timeout;
	struct io *input;

	bool saved_prompt;
	bt_shell_prompt_input_func saved_func;
	void *saved_user_data;

	const struct bt_shell_menu *menu;
	const struct bt_shell_menu *main;
	struct queue *submenus;
	const struct bt_shell_menu_entry *exec;

	struct queue *envs;
} data;

static void shell_print_menu(void);

static void cmd_version(int argc, char *argv[])
{
	bt_shell_printf("Version %s\n", VERSION);

	return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}

static void cmd_quit(int argc, char *argv[])
{
	mainloop_quit();
}

static void cmd_help(int argc, char *argv[])
{
	shell_print_menu();

	return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}

static const struct bt_shell_menu *find_menu(const char *name, size_t len)
{
	const struct queue_entry *entry;

	for (entry = queue_get_entries(data.submenus); entry;
						entry = entry->next) {
		struct bt_shell_menu *menu = entry->data;

		if (!strncmp(menu->name, name, len))
			return menu;
	}

	return NULL;
}

static char *menu_generator(const char *text, int state)
{
	static unsigned int index, len;
	static struct queue_entry *entry;

	if (!state) {
		index = 0;
		len = strlen(text);
		entry = (void *) queue_get_entries(data.submenus);
	}

	for (; entry; entry = entry->next) {
		struct bt_shell_menu *menu = entry->data;

		index++;

		if (!strncmp(menu->name, text, len)) {
			entry = entry->next;
			return strdup(menu->name);
		}
	}

	return NULL;
}

static void cmd_menu(int argc, char *argv[])
{
	const struct bt_shell_menu *menu;

	if (argc < 2 || !strlen(argv[1])) {
		bt_shell_printf("Missing name argument\n");
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	menu = find_menu(argv[1], strlen(argv[1]));
	if (!menu) {
		bt_shell_printf("Unable find menu with name: %s\n", argv[1]);
		return bt_shell_noninteractive_quit(EXIT_FAILURE);
	}

	bt_shell_set_menu(menu);

	shell_print_menu();

	return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}

static bool cmd_menu_exists(const struct bt_shell_menu *menu)
{
	/* Skip menu command if not on main menu or if there are no
	 * submenus.
	 */
	if (menu != data.main || queue_isempty(data.submenus))
		return false;

	return true;
}

static void cmd_back(int argc, char *argv[])
{
	if (data.menu == data.main) {
		bt_shell_printf("Already on main menu\n");
		return;
	}

	bt_shell_set_menu(data.main);

	shell_print_menu();
}

static bool cmd_back_exists(const struct bt_shell_menu *menu)
{
	/* Skip back command if on main menu */
	if (menu == data.main)
		return false;

	return true;
}

static void cmd_export(int argc, char *argv[])
{
	const struct queue_entry *entry;

	for (entry = queue_get_entries(data.envs); entry; entry = entry->next) {
		struct bt_shell_env *env = entry->data;

		print_text(COLOR_HIGHLIGHT, "%s=%p", env->name, env->value);
	}
}

static const struct bt_shell_menu_entry default_menu[] = {
	{ "back",         NULL,       cmd_back, "Return to main menu", NULL,
							NULL, cmd_back_exists },
	{ "menu",         "<name>",   cmd_menu, "Select submenu",
							menu_generator, NULL,
							cmd_menu_exists},
	{ "version",      NULL,       cmd_version, "Display version" },
	{ "quit",         NULL,       cmd_quit, "Quit program" },
	{ "exit",         NULL,       cmd_quit, "Quit program" },
	{ "help",         NULL,       cmd_help,
					"Display help about this program" },
	{ "export",       NULL,       cmd_export,
						"Print evironment variables" },
	{ }
};

static void shell_print_help(void)
{
	print_text(COLOR_HIGHLIGHT,
		"\n"
		"Use \"help\" for a list of available commands in a menu.\n"
		"Use \"menu <submenu>\" if you want to enter any submenu.\n"
		"Use \"back\" if you want to return to menu main.");
}

static void shell_print_menu(void)
{
	const struct bt_shell_menu_entry *entry;
	const struct queue_entry *submenu;

	if (!data.menu)
		return;

	print_text(COLOR_HIGHLIGHT, "Menu %s:", data.menu->name);
	print_text(COLOR_HIGHLIGHT, "Available commands:");
	print_text(COLOR_HIGHLIGHT, "-------------------");

	if (data.menu == data.main) {
		for (submenu = queue_get_entries(data.submenus); submenu;
						submenu = submenu->next) {
			struct bt_shell_menu *menu = submenu->data;

			print_submenu(menu->name, menu->desc ? menu->desc :
								"Submenu");
		}
	}

	for (entry = data.menu->entries; entry->cmd; entry++) {
		print_menu(entry->cmd, entry->arg ? : "", entry->desc ? : "");
	}

	for (entry = default_menu; entry->cmd; entry++) {
		if (entry->exists && !entry->exists(data.menu))
			continue;

		print_menu(entry->cmd, entry->arg ? : "", entry->desc ? : "");
	}
}

static int parse_args(char *arg, wordexp_t *w, char *del, int flags)
{
	char *str;

	str = strdelimit(arg, del, '"');

	if (wordexp(str, w, flags)) {
		free(str);
		return -EINVAL;
	}

	/* If argument ends with ... set we_offs bypass strict checks */
	if (w->we_wordc && !strsuffix(w->we_wordv[w->we_wordc -1], "..."))
		w->we_offs = 1;

	free(str);

	return 0;
}

static int cmd_exec(const struct bt_shell_menu_entry *entry,
					int argc, char *argv[])
{
	wordexp_t w;
	size_t len;
	char *man, *opt;
	int flags = WRDE_NOCMD;
	bool optargs = false;

	if (!entry->arg || entry->arg[0] == '\0') {
		if (argc > 1) {
			print_text(COLOR_HIGHLIGHT, "Too many arguments");
			return -EINVAL;
		}
		goto exec;
	}

	/* Find last mandatory arguments */
	man = strrchr(entry->arg, '>');
	if (!man) {
		opt = strdup(entry->arg);
		goto optional;
	}

	len = man - entry->arg;
	if (entry->arg[0] == '<')
		man = strndup(entry->arg, len + 1);
	else {
		/* Find where mandatory arguments start */
		opt = strrchr(entry->arg, '<');
		/* Skip if mandatory arguments are not in the right format */
		if (!opt || opt > man) {
			opt = strdup(entry->arg);
			goto optional;
		}
		man = strndup(opt, man - opt + 1);
		optargs = true;
	}

	if (parse_args(man, &w, "<>", flags) < 0) {
		print_text(COLOR_HIGHLIGHT,
			"Unable to parse mandatory command arguments: %s", man );
		free(man);
		return -EINVAL;
	}

	free(man);

	/* Check if there are enough arguments */
	if ((unsigned) argc - 1 < w.we_wordc) {
		print_text(COLOR_HIGHLIGHT, "Missing %s argument",
						w.we_wordv[argc - 1]);
		goto fail;
	}

	flags |= WRDE_APPEND;
	opt = strdup(entry->arg + len + 1);

optional:
	if (parse_args(opt, &w, "[]", flags) < 0) {
		print_text(COLOR_HIGHLIGHT,
			"Unable to parse optional command arguments: %s", opt);
		free(opt);
		return -EINVAL;
	}

	free(opt);

	/* Check if there are too many arguments */
	if (!optargs && ((unsigned int) argc - 1 > w.we_wordc && !w.we_offs)) {
		print_text(COLOR_HIGHLIGHT, "Too many arguments: %d > %zu",
					argc - 1, w.we_wordc);
		goto fail;
	}

	w.we_offs = 0;
	wordfree(&w);

exec:
	data.exec = entry;

	if (entry->func)
		entry->func(argc, argv);

	data.exec = NULL;

	return 0;

fail:
	w.we_offs = 0;
	wordfree(&w);
	return -EINVAL;
}

static int menu_exec(const struct bt_shell_menu_entry *entry,
					int argc, char *argv[])
{
	for (; entry->cmd; entry++) {
		if (strcmp(argv[0], entry->cmd))
			continue;

		/* Skip menu command if not on main menu */
		if (data.menu != data.main && !strcmp(entry->cmd, "menu"))
			continue;

		/* Skip back command if on main menu */
		if (data.menu == data.main && !strcmp(entry->cmd, "back"))
			continue;

		return cmd_exec(entry, argc, argv);
	}

	return -ENOENT;
}

static int submenu_exec(int argc, char *argv[])
{
	char *name;
	int len, tlen;
	const struct bt_shell_menu *submenu;

	if (data.menu != data.main)
		return -ENOENT;

	name = strchr(argv[0], '.');
	if (!name)
		return -ENOENT;

	tlen = strlen(argv[0]);
	len = name - argv[0];
	name[0] = '\0';

	submenu = find_menu(argv[0], strlen(argv[0]));
	if (!submenu)
		return -ENOENT;

	/* Replace submenu.command with command */
	memmove(argv[0], argv[0] + len + 1, tlen - len - 1);
	memset(argv[0] + tlen - len - 1, 0, len + 1);

	return menu_exec(submenu->entries, argc, argv);
}

static int shell_exec(int argc, char *argv[])
{
	int err;

	if (!data.menu || !argv[0])
		return -EINVAL;

	err  = menu_exec(default_menu, argc, argv);
	if (err == -ENOENT) {
		err  = menu_exec(data.menu->entries, argc, argv);
		if (err == -ENOENT) {
			err = submenu_exec(argc, argv);
			if (err == -ENOENT) {
				print_text(COLOR_HIGHLIGHT,
					"Invalid command in menu %s: %s",
					data.menu->name , argv[0]);
				shell_print_help();
			}
		}
	}

	return err;
}

void bt_shell_printf(const char *fmt, ...)
{
	va_list args;
	bool save_input;
	char *saved_line;
	int saved_point;

	if (!data.input)
		return;

	if (data.mode) {
		va_start(args, fmt);
		vprintf(fmt, args);
		va_end(args);
		return;
	}

	save_input = !RL_ISSTATE(RL_STATE_DONE);

	if (save_input) {
		saved_point = rl_point;
		saved_line = rl_copy_text(0, rl_end);
		if (!data.saved_prompt)
			rl_save_prompt();
		rl_replace_line("", 0);
		rl_redisplay();
	}

	va_start(args, fmt);
	vprintf(fmt, args);
	va_end(args);

	if (save_input) {
		if (!data.saved_prompt)
			rl_restore_prompt();
		rl_replace_line(saved_line, 0);
		rl_point = saved_point;
		rl_forced_update_display();
		free(saved_line);
	}
}

static void print_string(const char *str, void *user_data)
{
	bt_shell_printf("%s\n", str);
}

void bt_shell_hexdump(const unsigned char *buf, size_t len)
{
	util_hexdump(' ', buf, len, print_string, NULL);
}

void bt_shell_usage()
{
	if (!data.exec)
		return;

	bt_shell_printf("Usage: %s %s\n", data.exec->cmd,
					data.exec->arg ? data.exec->arg : "");
}

void bt_shell_prompt_input(const char *label, const char *msg,
			bt_shell_prompt_input_func func, void *user_data)
{
	if (!data.init || data.mode)
		return;

	/* Normal use should not prompt for user input to the value a second
	 * time before it releases the prompt, but we take a safe action. */
	if (data.saved_prompt)
		return;

	data.saved_prompt = true;
	data.saved_func = func;
	data.saved_user_data = user_data;

	rl_save_prompt();
	bt_shell_printf(COLOR_RED "[%s]" COLOR_OFF " %s ", label, msg);
}

int bt_shell_release_prompt(const char *input)
{
	bt_shell_prompt_input_func func;
	void *user_data;

	if (!data.saved_prompt)
		return -1;

	data.saved_prompt = false;

	rl_restore_prompt();

	func = data.saved_func;
	user_data = data.saved_user_data;

	data.saved_func = NULL;
	data.saved_user_data = NULL;

	func(input, user_data);

	return 0;
}

static void rl_handler(char *input)
{
	wordexp_t w;

	if (!input) {
		rl_insert_text("quit");
		rl_redisplay();
		rl_crlf();
		mainloop_quit();
		return;
	}

	if (!strlen(input))
		goto done;

	if (!bt_shell_release_prompt(input))
		goto done;

	if (history_search(input, -1))
		add_history(input);

	if (wordexp(input, &w, WRDE_NOCMD))
		goto done;

	if (w.we_wordc == 0) {
		wordfree(&w);
		goto done;
	}

	shell_exec(w.we_wordc, w.we_wordv);
	wordfree(&w);
done:
	free(input);
}

static char *find_cmd(const char *text,
			const struct bt_shell_menu_entry *entry, int *index)
{
	const struct bt_shell_menu_entry *tmp;
	int len;

	len = strlen(text);

	while ((tmp = &entry[*index])) {
		(*index)++;

		if (!tmp->cmd)
			break;

		if (tmp->exists && !tmp->exists(data.menu))
			continue;

		if (!strncmp(tmp->cmd, text, len))
			return strdup(tmp->cmd);
	}

	return NULL;
}

static char *cmd_generator(const char *text, int state)
{
	static int index;
	static bool default_menu_enabled, submenu_enabled;
	static const struct bt_shell_menu *menu;
	char *cmd;

	if (!state) {
		index = 0;
		menu = NULL;
		default_menu_enabled = true;
		submenu_enabled = false;
	}

	if (default_menu_enabled) {
		cmd = find_cmd(text, default_menu, &index);
		if (cmd) {
			return cmd;
		} else {
			index = 0;
			menu = data.menu;
			default_menu_enabled = false;
		}
	}

	if (!submenu_enabled) {
		cmd = find_cmd(text, menu->entries, &index);
		if (cmd || menu != data.main)
			return cmd;

		cmd = strrchr(text, '.');
		if (!cmd)
			return NULL;

		menu = find_menu(text, cmd - text);
		if (!menu)
			return NULL;

		index = 0;
		submenu_enabled = true;
	}

	cmd = find_cmd(text + strlen(menu->name) + 1, menu->entries, &index);
	if (cmd) {
		int err;
		char *tmp;

		err = asprintf(&tmp, "%s.%s", menu->name, cmd);

		free(cmd);

		if (err < 0)
			return NULL;

		cmd = tmp;
	}

	return cmd;
}

static wordexp_t args;

static char *arg_generator(const char *text, int state)
{
	static unsigned int index, len;
	const char *arg;

	if (!state) {
		index = 0;
		len = strlen(text);
	}

	while (index < args.we_wordc) {
		arg = args.we_wordv[index];
		index++;

		if (!strncmp(arg, text, len))
			return strdup(arg);
	}

	return NULL;
}

static char **args_completion(const struct bt_shell_menu_entry *entry, int argc,
							const char *text)
{
	char **matches = NULL;
	char *str;
	int index;

	index = text[0] == '\0' ? argc - 1 : argc - 2;
	if (index < 0)
		return NULL;

	if (!entry->arg)
		goto end;

	str = strdup(entry->arg);

	if (parse_args(str, &args, "<>[]", WRDE_NOCMD))
		goto done;

	/* Check if argument is valid */
	if ((unsigned) index > args.we_wordc - 1)
		goto done;

	/* Check if there are multiple values */
	if (!strrchr(entry->arg, '/'))
		goto done;

	free(str);

	/* Split values separated by / */
	str = strdelimit(args.we_wordv[index], "/", ' ');

	args.we_offs = 0;
	wordfree(&args);

	if (wordexp(str, &args, WRDE_NOCMD))
		goto done;

	rl_completion_display_matches_hook = NULL;
	matches = rl_completion_matches(text, arg_generator);

done:
	free(str);
end:
	if (!matches && text[0] == '\0')
		bt_shell_printf("Usage: %s %s\n", entry->cmd,
					entry->arg ? entry->arg : "");

	args.we_offs = 0;
	wordfree(&args);
	return matches;
}

static char **menu_completion(const struct bt_shell_menu_entry *entry,
				const char *text, int argc, char *input_cmd)
{
	char **matches = NULL;

	for (; entry->cmd; entry++) {
		if (strcmp(entry->cmd, input_cmd))
			continue;

		if (!entry->gen) {
			matches = args_completion(entry, argc, text);
			break;
		}

		rl_completion_display_matches_hook = entry->disp;
		matches = rl_completion_matches(text, entry->gen);
		break;
	}

	return matches;
}

static char **shell_completion(const char *text, int start, int end)
{
	char **matches = NULL;

	if (!data.menu)
		return NULL;

	if (start > 0) {
		wordexp_t w;

		if (wordexp(rl_line_buffer, &w, WRDE_NOCMD))
			return NULL;

		matches = menu_completion(default_menu, text, w.we_wordc,
							w.we_wordv[0]);
		if (!matches)
			matches = menu_completion(data.menu->entries, text,
							w.we_wordc,
							w.we_wordv[0]);

		wordfree(&w);
	} else {
		rl_completion_display_matches_hook = NULL;
		matches = rl_completion_matches(text, cmd_generator);
	}

	if (!matches)
		rl_attempted_completion_over = 1;

	return matches;
}

static bool io_hup(struct io *io, void *user_data)
{
	mainloop_quit();

	return false;
}

static bool signal_read(struct io *io, void *user_data)
{
	static bool terminated = false;
	struct signalfd_siginfo si;
	ssize_t result;
	int fd;

	fd = io_get_fd(io);

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

	switch (si.ssi_signo) {
	case SIGINT:
		if (data.input && !data.mode) {
			rl_replace_line("", 0);
			rl_crlf();
			rl_on_new_line();
			rl_redisplay();
			return true;
		}

		/*
		 * If input was not yet setup up that means signal was received
		 * while daemon was not yet running. Since user is not able
		 * to terminate client by CTRL-D or typing exit treat this as
		 * exit and fall through.
		 */

		/* fall through */
	case SIGTERM:
		if (!terminated) {
			if (!data.mode) {
				rl_replace_line("", 0);
				rl_crlf();
			}
			mainloop_quit();
		}

		terminated = true;
		break;
	}

	return false;
}

static struct io *setup_signalfd(void)
{
	struct io *io;
	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;
	}

	io = io_new(fd);

	io_set_close_on_destroy(io, true);
	io_set_read_handler(io, signal_read, NULL, NULL);
	io_set_disconnect_handler(io, io_hup, NULL, NULL);

	return io;
}

static void rl_init_history(void)
{
	const char *name;
	char *dir;

	memset(data.history, 0, sizeof(data.history));

	name = strrchr(data.name, '/');
	if (!name)
		name = data.name;
	else
		name++;

	dir = getenv("XDG_CACHE_HOME");
	if (dir) {
		snprintf(data.history, sizeof(data.history), "%s/.%s_history",
							dir, name);
		goto done;
	}

	dir = getenv("HOME");
	if (dir) {
		snprintf(data.history, sizeof(data.history),
				"%s/.cache/.%s_history", dir, name);
		goto done;
	}

	dir = getenv("PWD");
	if (dir) {
		snprintf(data.history, sizeof(data.history), "%s/.%s_history",
							dir, name);
		goto done;
	}

	return;

done:
	read_history(data.history);
	using_history();
	bt_shell_set_env("HISTORY", data.history);
}

static void rl_init(void)
{
	if (data.mode)
		return;

	setlinebuf(stdout);
	rl_attempted_completion_function = shell_completion;

	rl_erase_empty_line = 1;
	rl_callback_handler_install(NULL, rl_handler);

	rl_init_history();
}

static const struct option main_options[] = {
	{ "version",	no_argument, 0, 'v' },
	{ "help",	no_argument, 0, 'h' },
	{ "timeout",	required_argument, 0, 't' },
};

static void usage(int argc, char **argv, const struct bt_shell_opt *opt)
{
	unsigned int i;

	printf("%s ver %s\n", argv[0], VERSION);
	printf("Usage:\n"
		"\t%s [options]\n", argv[0]);

	printf("Options:\n");

	for (i = 0; opt && opt->options[i].name; i++)
		printf("\t--%s \t%s\n", opt->options[i].name, opt->help[i]);

	printf("\t--timeout \tTimeout in seconds for non-interactive mode\n"
		"\t--version \tDisplay version\n"
		"\t--help \t\tDisplay help\n");
}

void bt_shell_init(int argc, char **argv, const struct bt_shell_opt *opt)
{
	int c, index = -1;
	struct option options[256];
	char optstr[256];
	size_t offset;

	offset = sizeof(main_options) / sizeof(struct option);

	memcpy(options, main_options, sizeof(struct option) * offset);

	if (opt) {
		memcpy(options + offset, opt->options,
				sizeof(struct option) * opt->optno);
		snprintf(optstr, sizeof(optstr), "+hvt:%s", opt->optstr);
	} else
		snprintf(optstr, sizeof(optstr), "+hvt:");

	while ((c = getopt_long(argc, argv, optstr, options, &index)) != -1) {
		switch (c) {
		case 'v':
			printf("%s: %s\n", argv[0], VERSION);
			exit(EXIT_SUCCESS);
			return;
		case 'h':
			usage(argc, argv, opt);
			exit(EXIT_SUCCESS);
			return;
		case 't':
			data.timeout = atoi(optarg);
			break;
		default:
			if (index < 0) {
				for (index = 0; options[index].val; index++) {
					if (c == options[index].val)
						break;
				}
			}

			if (c != opt->options[index - offset].val) {
				usage(argc, argv, opt);
				exit(EXIT_SUCCESS);
				return;
			}

			*opt->optarg[index - offset] = optarg;
		}

		index = -1;
	}

	data.name = strdup(argv[0]);
	bt_shell_set_env("SHELL", data.name);

	data.argc = argc - optind;
	data.argv = argv + optind;
	optind = 0;
	data.mode = (data.argc > 0);

	if (data.mode)
		bt_shell_set_env("NON_INTERACTIVE", &data.mode);

	mainloop_init();

	rl_init();

	data.init = true;
}

static void rl_cleanup(void)
{
	if (data.mode)
		return;

	if (data.history[0] != '\0')
		write_history(data.history);

	rl_message("");
	rl_callback_handler_remove();
}

static void env_destroy(void *data)
{
	struct bt_shell_env *env = data;

	free(env->name);
	free(env);
}

int bt_shell_run(void)
{
	struct io *signal;
	int status;

	signal = setup_signalfd();

	status = mainloop_run();

	io_destroy(signal);

	bt_shell_cleanup();

	return status;
}

void bt_shell_cleanup(void)
{
	bt_shell_release_prompt("");
	bt_shell_detach();

	if (data.envs) {
		queue_destroy(data.envs, env_destroy);
		data.envs = NULL;
	}

	rl_cleanup();

	data.init = false;
	free(data.name);
}

void bt_shell_quit(int status)
{
	if (status == EXIT_SUCCESS)
		mainloop_exit_success();
	else
		mainloop_exit_failure();
}

void bt_shell_noninteractive_quit(int status)
{
	if (!data.mode || data.timeout)
		return;

	bt_shell_quit(status);
}

bool bt_shell_set_menu(const struct bt_shell_menu *menu)
{
	if (!menu)
		return false;

	data.menu = menu;

	if (!data.main)
		data.main = menu;

	return true;
}

bool bt_shell_add_submenu(const struct bt_shell_menu *menu)
{
	if (!menu)
		return false;

	if (!data.submenus)
		data.submenus = queue_new();

	queue_push_tail(data.submenus, (void *) menu);

	return true;
}

void bt_shell_set_prompt(const char *string)
{
	if (!data.init || data.mode)
		return;

	rl_set_prompt(string);
	bt_shell_printf("\r");
}

static bool input_read(struct io *io, void *user_data)
{
	rl_callback_read_char();
	return true;
}

static bool shell_quit(void *data)
{
	mainloop_quit();

	return false;
}

bool bt_shell_attach(int fd)
{
	struct io *io;

	/* TODO: Allow more than one input? */
	if (data.input)
		return false;

	io = io_new(fd);

	if (!data.mode)
		io_set_read_handler(io, input_read, NULL, NULL);

	io_set_disconnect_handler(io, io_hup, NULL, NULL);

	data.input = io;

	if (data.mode) {
		if (shell_exec(data.argc, data.argv) < 0) {
			bt_shell_noninteractive_quit(EXIT_FAILURE);
			return true;
		}

		if (data.timeout)
			timeout_add(data.timeout * 1000, shell_quit, NULL,
								NULL);
	}

	return true;
}

bool bt_shell_detach(void)
{
	if (!data.input)
		return false;

	io_destroy(data.input);
	data.input = NULL;

	return true;
}

static bool match_env(const void *data, const void *user_data)
{
	const struct bt_shell_env *env = data;
	const char *name = user_data;

	return !strcmp(env->name, name);
}

void bt_shell_set_env(const char *name, void *value)
{
	struct bt_shell_env *env;

	if (!data.envs) {
		if (!value)
			return;
		data.envs = queue_new();
		goto done;
	}

	env = queue_remove_if(data.envs, match_env, (void *) name);
	if (env)
		env_destroy(env);

	/* Don't create an env if value is not set */
	if (!value)
		return;

done:
	env = new0(struct bt_shell_env, 1);
	env->name = strdup(name);
	env->value = value;

	queue_push_tail(data.envs, env);
}

void *bt_shell_get_env(const char *name)
{
	const struct bt_shell_env *env;

	if (!data.envs)
		return NULL;

	env = queue_find(data.envs, match_env, name);
	if (!env)
		return NULL;

	return env->value;
}
