/*
 *
 *  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;
	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(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);
}

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.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;

	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;
}

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;
}
