/*
 * Copyright (c) 2018 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <ctype.h>
#include <stdlib.h>
#include <zephyr/sys/atomic.h>
#include <zephyr/shell/shell.h>
#if defined(CONFIG_SHELL_BACKEND_DUMMY)
#include <zephyr/shell/shell_dummy.h>
#endif
#include "shell_ops.h"
#include "shell_help.h"
#include "shell_utils.h"
#include "shell_vt100.h"
#include "shell_wildcard.h"

/* 2 == 1 char for cmd + 1 char for '\0' */
#if (CONFIG_SHELL_CMD_BUFF_SIZE < 2)
	#error too small CONFIG_SHELL_CMD_BUFF_SIZE
#endif

#if (CONFIG_SHELL_PRINTF_BUFF_SIZE < 1)
	#error too small SHELL_PRINTF_BUFF_SIZE
#endif

#define SHELL_MSG_CMD_NOT_FOUND		": command not found"
#define SHELL_MSG_BACKEND_NOT_ACTIVE	\
	"WARNING: A print request was detected on not active shell backend.\n"
#define SHELL_MSG_TOO_MANY_ARGS		"Too many arguments in the command.\n"
#define SHELL_INIT_OPTION_PRINTER	(NULL)

#define SHELL_THREAD_PRIORITY \
	COND_CODE_1(CONFIG_SHELL_THREAD_PRIORITY_OVERRIDE, \
			(CONFIG_SHELL_THREAD_PRIORITY), (K_LOWEST_APPLICATION_THREAD_PRIO))

BUILD_ASSERT(SHELL_THREAD_PRIORITY >=
		  K_HIGHEST_APPLICATION_THREAD_PRIO
		&& SHELL_THREAD_PRIORITY <= K_LOWEST_APPLICATION_THREAD_PRIO,
		  "Invalid range for thread priority");

static inline void receive_state_change(const struct shell *sh,
					enum shell_receive_state state)
{
	sh->ctx->receive_state = state;
}

static void cmd_buffer_clear(const struct shell *sh)
{
	sh->ctx->cmd_buff[0] = '\0'; /* clear command buffer */
	sh->ctx->cmd_buff_pos = 0;
	sh->ctx->cmd_buff_len = 0;
}

static void shell_internal_help_print(const struct shell *sh)
{
	if (!IS_ENABLED(CONFIG_SHELL_HELP)) {
		return;
	}

	z_shell_help_cmd_print(sh, &sh->ctx->active_cmd);
	z_shell_help_subcmd_print(sh, &sh->ctx->active_cmd,
				  "Subcommands:\n");
}

/**
 * @brief Prints error message on wrong argument count.
 *	  Optionally, printing help on wrong argument count.
 *
 * @param[in] shell	  Pointer to the shell instance.
 * @param[in] arg_cnt_ok  Flag indicating valid number of arguments.
 *
 * @return 0		  if check passed
 * @return -EINVAL	  if wrong argument count
 */
static int cmd_precheck(const struct shell *sh,
			bool arg_cnt_ok)
{
	if (!arg_cnt_ok) {
		z_shell_fprintf(sh, SHELL_ERROR,
				"%s: wrong parameter count\n",
				sh->ctx->active_cmd.syntax);

		if (IS_ENABLED(CONFIG_SHELL_HELP_ON_WRONG_ARGUMENT_COUNT)) {
			shell_internal_help_print(sh);
		}

		return -EINVAL;
	}

	return 0;
}

static inline void state_set(const struct shell *sh, enum shell_state state)
{
	sh->ctx->state = state;

	if (state == SHELL_STATE_ACTIVE && !sh->ctx->bypass) {
		cmd_buffer_clear(sh);
		if (z_flag_print_noinit_get(sh)) {
			z_shell_fprintf(sh, SHELL_WARNING, "%s",
					SHELL_MSG_BACKEND_NOT_ACTIVE);
			z_flag_print_noinit_set(sh, false);
		}
		z_shell_print_prompt_and_cmd(sh);
	}
}

static inline enum shell_state state_get(const struct shell *sh)
{
	return sh->ctx->state;
}

static inline const struct shell_static_entry *
selected_cmd_get(const struct shell *sh)
{
	if (IS_ENABLED(CONFIG_SHELL_CMDS_SELECT)
	    || (CONFIG_SHELL_CMD_ROOT[0] != 0)) {
		return sh->ctx->selected_cmd;
	}

	return NULL;
}

static void tab_item_print(const struct shell *sh, const char *option,
			   uint16_t longest_option)
{
	static const char *tab = "  ";
	uint16_t columns;
	uint16_t diff;

	/* Function initialization has been requested. */
	if (option == NULL) {
		sh->ctx->vt100_ctx.printed_cmd = 0;
		return;
	}

	longest_option += z_shell_strlen(tab);

	columns = (sh->ctx->vt100_ctx.cons.terminal_wid
			- z_shell_strlen(tab)) / longest_option;
	diff = longest_option - z_shell_strlen(option);

	if (sh->ctx->vt100_ctx.printed_cmd++ % columns == 0U) {
		z_shell_fprintf(sh, SHELL_OPTION, "\n%s%s", tab, option);
	} else {
		z_shell_fprintf(sh, SHELL_OPTION, "%s", option);
	}

	z_shell_op_cursor_horiz_move(sh, diff);
}

static void history_init(const struct shell *sh)
{
	if (!IS_ENABLED(CONFIG_SHELL_HISTORY)) {
		return;
	}

	z_shell_history_init(sh->history);
}

static void history_purge(const struct shell *sh)
{
	if (!IS_ENABLED(CONFIG_SHELL_HISTORY)) {
		return;
	}

	z_shell_history_purge(sh->history);
}

static void history_mode_exit(const struct shell *sh)
{
	if (!IS_ENABLED(CONFIG_SHELL_HISTORY)) {
		return;
	}

	z_flag_history_exit_set(sh, false);
	z_shell_history_mode_exit(sh->history);
}

static void history_put(const struct shell *sh, uint8_t *line, size_t length)
{
	if (!IS_ENABLED(CONFIG_SHELL_HISTORY)) {
		return;
	}

	z_shell_history_put(sh->history, line, length);
}

static void history_handle(const struct shell *sh, bool up)
{
	bool history_mode;
	uint16_t len;

	/*optional feature */
	if (!IS_ENABLED(CONFIG_SHELL_HISTORY)) {
		return;
	}

	/* Checking if history process has been stopped */
	if (z_flag_history_exit_get(sh)) {
		z_flag_history_exit_set(sh, false);
		z_shell_history_mode_exit(sh->history);
	}

	/* Backup command if history is entered */
	if (!z_shell_history_active(sh->history)) {
		if (up) {
			uint16_t cmd_len = z_shell_strlen(sh->ctx->cmd_buff);

			if (cmd_len) {
				strcpy(sh->ctx->temp_buff,
				       sh->ctx->cmd_buff);
			} else {
				sh->ctx->temp_buff[0] = '\0';
			}
		} else {
			/* Pressing 'down' not in history mode has no effect. */
			return;
		}
	}

	/* Start by checking if history is not empty. */
	history_mode = z_shell_history_get(sh->history, up,
					   sh->ctx->cmd_buff, &len);

	/* On exiting history mode print backed up command. */
	if (!history_mode) {
		strcpy(sh->ctx->cmd_buff, sh->ctx->temp_buff);
		len = z_shell_strlen(sh->ctx->cmd_buff);
	}

	z_shell_op_cursor_home_move(sh);
	z_clear_eos(sh);
	z_shell_print_cmd(sh);
	sh->ctx->cmd_buff_pos = len;
	sh->ctx->cmd_buff_len = len;
	z_shell_op_cond_next_line(sh);
}

static inline uint16_t completion_space_get(const struct shell *sh)
{
	uint16_t space = (CONFIG_SHELL_CMD_BUFF_SIZE - 1) -
			sh->ctx->cmd_buff_len;
	return space;
}

/* Prepare arguments and return number of space available for completion. */
static bool tab_prepare(const struct shell *sh,
			const struct shell_static_entry **cmd,
			const char ***argv, size_t *argc,
			size_t *complete_arg_idx,
			struct shell_static_entry *d_entry)
{
	uint16_t compl_space = completion_space_get(sh);
	size_t search_argc;

	if (compl_space == 0U) {
		return false;
	}

	/* Copy command from its beginning to cursor position. */
	memcpy(sh->ctx->temp_buff, sh->ctx->cmd_buff,
			sh->ctx->cmd_buff_pos);
	sh->ctx->temp_buff[sh->ctx->cmd_buff_pos] = '\0';

	/* Create argument list. */
	(void)z_shell_make_argv(argc, *argv, sh->ctx->temp_buff,
				CONFIG_SHELL_ARGC_MAX);

	if (*argc > CONFIG_SHELL_ARGC_MAX) {
		return false;
	}

	/* terminate arguments with NULL */
	(*argv)[*argc] = NULL;

	if ((IS_ENABLED(CONFIG_SHELL_CMDS_SELECT) || (CONFIG_SHELL_CMD_ROOT[0] != 0))
	    && (*argc > 0) &&
	    (strcmp("select", (*argv)[0]) == 0) &&
	    !z_shell_in_select_mode(sh)) {
		*argv = *argv + 1;
		*argc = *argc - 1;
	}

	/* If last command is not completed (followed by space) it is treated
	 * as uncompleted one.
	 */
	int space = (sh->ctx->cmd_buff_pos > 0) ?
		     isspace((int)sh->ctx->cmd_buff[sh->ctx->cmd_buff_pos - 1]) : 0;

	/* root command completion */
	if ((*argc == 0) || ((space == 0) && (*argc == 1))) {
		*complete_arg_idx = Z_SHELL_CMD_ROOT_LVL;
		*cmd = selected_cmd_get(sh);
		return true;
	}

	search_argc = space ? *argc : *argc - 1;

	*cmd = z_shell_get_last_command(selected_cmd_get(sh), search_argc,
					*argv, complete_arg_idx,	d_entry,
					false);

	/* if search_argc == 0 (empty command line) shell_get_last_command will
	 * return NULL tab is allowed, otherwise not.
	 */
	if ((*cmd == NULL) && (search_argc != 0)) {
		return false;
	}

	return true;
}

static inline bool is_completion_candidate(const char *candidate,
					   const char *str, size_t len)
{
	return (strncmp(candidate, str, len) == 0) ? true : false;
}

static void find_completion_candidates(const struct shell *sh,
				       const struct shell_static_entry *cmd,
				       const char *incompl_cmd,
				       size_t *first_idx, size_t *cnt,
				       uint16_t *longest)
{
	const struct shell_static_entry *candidate;
	struct shell_static_entry dloc;
	size_t incompl_cmd_len;
	size_t idx = 0;

	incompl_cmd_len = z_shell_strlen(incompl_cmd);
	*longest = 0U;
	*cnt = 0;

	while ((candidate = z_shell_cmd_get(cmd, idx, &dloc)) != NULL) {
		bool is_candidate;
		is_candidate = is_completion_candidate(candidate->syntax,
						incompl_cmd, incompl_cmd_len);
		if (is_candidate) {
			*longest = Z_MAX(strlen(candidate->syntax), *longest);
			if (*cnt == 0) {
				*first_idx = idx;
			}
			(*cnt)++;
		}

		idx++;
	}
}

static void autocomplete(const struct shell *sh,
			 const struct shell_static_entry *cmd,
			 const char *arg,
			 size_t subcmd_idx)
{
	const struct shell_static_entry *match;
	uint16_t cmd_len;
	uint16_t arg_len = z_shell_strlen(arg);

	/* sh->ctx->active_cmd can be safely used outside of command context
	 * to save stack
	 */
	match = z_shell_cmd_get(cmd, subcmd_idx, &sh->ctx->active_cmd);
	__ASSERT_NO_MSG(match != NULL);
	cmd_len = z_shell_strlen(match->syntax);

	if (!IS_ENABLED(CONFIG_SHELL_TAB_AUTOCOMPLETION)) {
		/* Add a space if the Tab button is pressed when command is
		 * complete.
		 */
		if (cmd_len == arg_len) {
			z_shell_op_char_insert(sh, ' ');
		}
		return;
	}

	/* no exact match found */
	if (cmd_len != arg_len) {
		z_shell_op_completion_insert(sh,
					     match->syntax + arg_len,
					     cmd_len - arg_len);
	}

	/* Next character in the buffer is not 'space'. */
	if (isspace((int) sh->ctx->cmd_buff[
					sh->ctx->cmd_buff_pos]) == 0) {
		if (z_flag_insert_mode_get(sh)) {
			z_flag_insert_mode_set(sh, false);
			z_shell_op_char_insert(sh, ' ');
			z_flag_insert_mode_set(sh, true);
		} else {
			z_shell_op_char_insert(sh, ' ');
		}
	} else {
		/*  case:
		 * | | -> cursor
		 * cons_name $: valid_cmd valid_sub_cmd| |argument  <tab>
		 */
		z_shell_op_cursor_move(sh, 1);
		/* result:
		 * cons_name $: valid_cmd valid_sub_cmd |a|rgument
		 */
	}
}

static size_t str_common(const char *s1, const char *s2, size_t n)
{
	size_t common = 0;

	while ((n > 0) && (*s1 == *s2) && (*s1 != '\0')) {
		s1++;
		s2++;
		n--;
		common++;
	}

	return common;
}

static void tab_options_print(const struct shell *sh,
			      const struct shell_static_entry *cmd,
			      const char *str, size_t first, size_t cnt,
			      uint16_t longest)
{
	const struct shell_static_entry *match;
	size_t str_len = z_shell_strlen(str);
	size_t idx = first;

	/* Printing all matching commands (options). */
	tab_item_print(sh, SHELL_INIT_OPTION_PRINTER, longest);

	while (cnt) {
		/* sh->ctx->active_cmd can be safely used outside of command
		 * context to save stack
		 */
		match = z_shell_cmd_get(cmd, idx, &sh->ctx->active_cmd);
		__ASSERT_NO_MSG(match != NULL);
		idx++;
		if (str && match->syntax &&
		    !is_completion_candidate(match->syntax, str, str_len)) {
			continue;
		}

		tab_item_print(sh, match->syntax, longest);
		cnt--;
	}

	z_cursor_next_line_move(sh);
	z_shell_print_prompt_and_cmd(sh);
}

static uint16_t common_beginning_find(const struct shell *sh,
				   const struct shell_static_entry *cmd,
				   const char **str,
				   size_t first, size_t cnt, uint16_t arg_len)
{
	struct shell_static_entry dynamic_entry;
	const struct shell_static_entry *match;
	uint16_t common = UINT16_MAX;
	size_t idx = first + 1;

	__ASSERT_NO_MSG(cnt > 1);

	match = z_shell_cmd_get(cmd, first, &dynamic_entry);
	__ASSERT_NO_MSG(match);
	strncpy(sh->ctx->temp_buff, match->syntax,
			sizeof(sh->ctx->temp_buff) - 1);

	*str = match->syntax;

	while (cnt > 1) {
		struct shell_static_entry dynamic_entry2;
		const struct shell_static_entry *match2;
		int curr_common;

		match2 = z_shell_cmd_get(cmd, idx++, &dynamic_entry2);
		if (match2 == NULL) {
			break;
		}

		curr_common = str_common(sh->ctx->temp_buff, match2->syntax,
					 UINT16_MAX);
		if ((arg_len == 0U) || (curr_common >= arg_len)) {
			--cnt;
			common = (curr_common < common) ? curr_common : common;
		}
	}

	return common;
}

static void partial_autocomplete(const struct shell *sh,
				 const struct shell_static_entry *cmd,
				 const char *arg,
				 size_t first, size_t cnt)
{
	const char *completion;
	uint16_t arg_len = z_shell_strlen(arg);
	uint16_t common = common_beginning_find(sh, cmd, &completion, first,
					     cnt, arg_len);

	if (!IS_ENABLED(CONFIG_SHELL_TAB_AUTOCOMPLETION)) {
		return;
	}

	if (common) {
		z_shell_op_completion_insert(sh, &completion[arg_len],
					     common - arg_len);
	}
}

static int exec_cmd(const struct shell *sh, size_t argc, const char **argv,
		    const struct shell_static_entry *help_entry)
{
	int ret_val = 0;

	if (sh->ctx->active_cmd.handler == NULL) {
		if ((help_entry != NULL) && IS_ENABLED(CONFIG_SHELL_HELP)) {
			if (help_entry->help == NULL) {
				return -ENOEXEC;
			}
			if (help_entry->help != sh->ctx->active_cmd.help) {
				sh->ctx->active_cmd = *help_entry;
			}
			shell_internal_help_print(sh);
			return SHELL_CMD_HELP_PRINTED;
		} else {
			if (IS_ENABLED(CONFIG_SHELL_MSG_SPECIFY_SUBCOMMAND)) {
				z_shell_fprintf(sh, SHELL_ERROR,
						SHELL_MSG_SPECIFY_SUBCOMMAND);
			}
			return -ENOEXEC;
		}
	}

	if (sh->ctx->active_cmd.args.mandatory) {
		uint32_t mand = sh->ctx->active_cmd.args.mandatory;
		uint8_t opt8 = sh->ctx->active_cmd.args.optional;
		uint32_t opt = (opt8 == SHELL_OPT_ARG_CHECK_SKIP) ?
				UINT16_MAX : opt8;
		const bool in_range = IN_RANGE(argc, mand, mand + opt);

		/* Check if argc is within allowed range */
		ret_val = cmd_precheck(sh, in_range);
	}

	if (!ret_val) {
#if CONFIG_SHELL_GETOPT
		getopt_init();
#endif

		z_flag_cmd_ctx_set(sh, true);
		/* Unlock thread mutex in case command would like to borrow
		 * shell context to other thread to avoid mutex deadlock.
		 */
		k_mutex_unlock(&sh->ctx->wr_mtx);
		ret_val = sh->ctx->active_cmd.handler(sh, argc,
							 (char **)argv);
		/* Bring back mutex to shell thread. */
		k_mutex_lock(&sh->ctx->wr_mtx, K_FOREVER);
		z_flag_cmd_ctx_set(sh, false);
	}

	return ret_val;
}

static void active_cmd_prepare(const struct shell_static_entry *entry,
				struct shell_static_entry *active_cmd,
				struct shell_static_entry *help_entry,
				size_t *lvl, size_t *handler_lvl,
				size_t *args_left)
{
	if (entry->handler) {
		*handler_lvl = *lvl;
		*active_cmd = *entry;
		/* If command is final handler and it has a raw optional argument,
		 * then set remaining arguments to mandatory - 1 so after processing mandatory
		 * args, handler is passed remaining raw string
		 */
		if ((entry->subcmd == NULL)
		    && entry->args.optional == SHELL_OPT_ARG_RAW) {
			*args_left = entry->args.mandatory - 1;
		}
	}
	if (entry->help) {
		*help_entry = *entry;
	}
}

static bool wildcard_check_report(const struct shell *sh, bool found,
				  const struct shell_static_entry *entry)
{
	/* An error occurred, fnmatch  argument cannot be followed by argument
	 * with a handler to avoid multiple function calls.
	 */
	if (IS_ENABLED(CONFIG_SHELL_WILDCARD) && found && entry->handler) {
		z_shell_op_cursor_end_move(sh);
		z_shell_op_cond_next_line(sh);

		z_shell_fprintf(sh, SHELL_ERROR,
			"Error: requested multiple function executions\n");
		return false;
	}

	return true;
}

/* Function is analyzing the command buffer to find matching commands. Next, it
 * invokes the  last recognized command which has a handler and passes the rest
 * of command buffer as arguments.
 *
 * By default command buffer is parsed and spaces are treated by arguments
 * separators. Complex arguments are provided in quotation marks with quotation
 * marks escaped within the argument. Argument parser is removing quotation
 * marks at argument boundary as well as escape characters within the argument.
 * However, it is possible to indicate that command shall treat remaining part
 * of command buffer as the last argument without parsing. This can be used for
 * commands which expects whole command buffer to be passed directly to
 * the command handler without any preprocessing.
 * Because of that feature, command buffer is processed argument by argument and
 * decision on further processing is based on currently processed command.
 */
static int execute(const struct shell *sh)
{
	struct shell_static_entry dloc; /* Memory for dynamic commands. */
	const char *argv[CONFIG_SHELL_ARGC_MAX + 1] = {0}; /* +1 reserved for NULL */
	const struct shell_static_entry *parent = selected_cmd_get(sh);
	const struct shell_static_entry *entry = NULL;
	struct shell_static_entry help_entry;
	size_t cmd_lvl = 0;
	size_t cmd_with_handler_lvl = 0;
	bool wildcard_found = false;
	size_t argc = 0, args_left = SIZE_MAX;
	char quote;
	const char **argvp;
	char *cmd_buf = sh->ctx->cmd_buff;
	bool has_last_handler = false;

	z_shell_op_cursor_end_move(sh);
	if (!z_shell_cursor_in_empty_line(sh)) {
		z_cursor_next_line_move(sh);
	}

	memset(&sh->ctx->active_cmd, 0, sizeof(sh->ctx->active_cmd));

	if (IS_ENABLED(CONFIG_SHELL_HISTORY)) {
		z_shell_cmd_trim(sh);
		history_put(sh, sh->ctx->cmd_buff,
			    sh->ctx->cmd_buff_len);
	}

	if (IS_ENABLED(CONFIG_SHELL_WILDCARD)) {
		z_shell_wildcard_prepare(sh);
	}

	/* Parent present means we are in select mode. */
	if (parent != NULL) {
		argv[0] = parent->syntax;
		argv[1] = cmd_buf;
		argvp = &argv[1];
		active_cmd_prepare(parent, &sh->ctx->active_cmd, &help_entry,
				   &cmd_lvl, &cmd_with_handler_lvl, &args_left);
		cmd_lvl++;
	} else {
		help_entry.help = NULL;
		argvp = &argv[0];
	}

	/* Below loop is analyzing subcommands of found root command. */
	while ((argc != 1) && (cmd_lvl < CONFIG_SHELL_ARGC_MAX)
		&& args_left > 0) {
		quote = z_shell_make_argv(&argc, argvp, cmd_buf, 2);
		cmd_buf = (char *)argvp[1];

		if (argc == 0) {
			return -ENOEXEC;
		} else if ((argc == 1) && (quote != 0)) {
			z_shell_fprintf(sh, SHELL_ERROR,
					"not terminated: %c\n", quote);
			return -ENOEXEC;
		}

		if (IS_ENABLED(CONFIG_SHELL_HELP) && (cmd_lvl > 0) &&
		    z_shell_help_request(argvp[0])) {
			/* Command called with help option so it makes no sense
			 * to search deeper commands.
			 */
			if (help_entry.help) {
				sh->ctx->active_cmd = help_entry;
				shell_internal_help_print(sh);
				return SHELL_CMD_HELP_PRINTED;
			}

			if (IS_ENABLED(CONFIG_SHELL_MSG_SPECIFY_SUBCOMMAND)) {
				z_shell_fprintf(sh, SHELL_ERROR,
						SHELL_MSG_SPECIFY_SUBCOMMAND);
			}
			return -ENOEXEC;
		}

		if (IS_ENABLED(CONFIG_SHELL_WILDCARD) && (cmd_lvl > 0)) {
			enum shell_wildcard_status status;

			status = z_shell_wildcard_process(sh, entry,
							  argvp[0]);
			/* Wildcard character found but there is no matching
			 * command.
			 */
			if (status == SHELL_WILDCARD_CMD_NO_MATCH_FOUND) {
				break;
			}

			/* Wildcard character was not found function can process
			 * argument.
			 */
			if (status != SHELL_WILDCARD_NOT_FOUND) {
				++cmd_lvl;
				wildcard_found = true;
				continue;
			}
		}

		if (has_last_handler == false) {
			entry = z_shell_find_cmd(parent, argvp[0], &dloc);
		}

		argvp++;
		args_left--;
		if (entry) {
			if (wildcard_check_report(sh, wildcard_found, entry)
				== false) {
				return -ENOEXEC;
			}

			active_cmd_prepare(entry, &sh->ctx->active_cmd,
					  &help_entry, &cmd_lvl,
					  &cmd_with_handler_lvl, &args_left);
			parent = entry;
		} else {
			if (IS_ENABLED(CONFIG_SHELL_MSG_CMD_NOT_FOUND) &&
				cmd_lvl == 0 &&
				(!z_shell_in_select_mode(sh) ||
				 sh->ctx->selected_cmd->handler == NULL)) {
				z_shell_fprintf(sh, SHELL_ERROR,
						"%s%s\n", argv[0],
						SHELL_MSG_CMD_NOT_FOUND);
			}

			/* last handler found - no need to search commands in
			 * the next iteration.
			 */
			has_last_handler = true;
		}

		if (args_left || (argc == 2)) {
			cmd_lvl++;
		}

	}

	if ((cmd_lvl >= CONFIG_SHELL_ARGC_MAX) && (argc == 2)) {
		/* argc == 2 indicates that when command string was parsed
		 * there was more characters remaining. It means that number of
		 * arguments exceeds the limit.
		 */
		z_shell_fprintf(sh, SHELL_ERROR, "%s\n",
				SHELL_MSG_TOO_MANY_ARGS);
		return -ENOEXEC;
	}

	if (IS_ENABLED(CONFIG_SHELL_WILDCARD) && wildcard_found) {
		z_shell_wildcard_finalize(sh);
		/* cmd_buffer has been overwritten by function finalize function
		 * with all expanded commands. Hence shell_make_argv needs to
		 * be called again.
		 */
		(void)z_shell_make_argv(&cmd_lvl,
					&argv[selected_cmd_get(sh) ? 1 : 0],
					sh->ctx->cmd_buff,
					CONFIG_SHELL_ARGC_MAX);

		if (selected_cmd_get(sh)) {
			/* Apart from what is in the command buffer, there is
			 * a selected command.
			 */
			cmd_lvl++;
		}
	}

	/* If a command was found */
	if (parent != NULL) {
		/* If the found command uses a raw optional argument and
		 * we have a remaining unprocessed non-null string,
		 * then increment command level so handler receives raw string
		 */
		if (parent->args.optional == SHELL_OPT_ARG_RAW && argv[cmd_lvl] != NULL) {
			cmd_lvl++;
		}
	}

	/* Executing the deepest found handler. */
	return exec_cmd(sh, cmd_lvl - cmd_with_handler_lvl,
			&argv[cmd_with_handler_lvl], &help_entry);
}

static void tab_handle(const struct shell *sh)
{
	const char *__argv[CONFIG_SHELL_ARGC_MAX + 1];
	/* d_entry - placeholder for dynamic command */
	struct shell_static_entry d_entry;
	const struct shell_static_entry *cmd;
	const char **argv = __argv;
	size_t first = 0;
	size_t arg_idx;
	uint16_t longest;
	size_t argc;
	size_t cnt;

	bool tab_possible = tab_prepare(sh, &cmd, &argv, &argc, &arg_idx,
					&d_entry);

	if (tab_possible == false) {
		return;
	}

	find_completion_candidates(sh, cmd, argv[arg_idx], &first, &cnt,
				   &longest);

	if (cnt == 1) {
		/* Autocompletion.*/
		autocomplete(sh, cmd, argv[arg_idx], first);
	} else if (cnt > 1) {
		tab_options_print(sh, cmd, argv[arg_idx], first, cnt,
				  longest);
		partial_autocomplete(sh, cmd, argv[arg_idx], first, cnt);
	}
}

static void alt_metakeys_handle(const struct shell *sh, char data)
{
	/* Optional feature */
	if (!IS_ENABLED(CONFIG_SHELL_METAKEYS)) {
		return;
	}
	if (data == SHELL_VT100_ASCII_ALT_B) {
		z_shell_op_cursor_word_move(sh, -1);
	} else if (data == SHELL_VT100_ASCII_ALT_F) {
		z_shell_op_cursor_word_move(sh, 1);
	} else if (data == SHELL_VT100_ASCII_ALT_R &&
		   IS_ENABLED(CONFIG_SHELL_CMDS_SELECT)) {
		if (selected_cmd_get(sh) != NULL) {
			z_shell_cmd_line_erase(sh);
			z_shell_fprintf(sh, SHELL_WARNING,
					"Restored default root commands\n");
			if (CONFIG_SHELL_CMD_ROOT[0]) {
				sh->ctx->selected_cmd = root_cmd_find(CONFIG_SHELL_CMD_ROOT);
			} else {
				sh->ctx->selected_cmd = NULL;
			}
			z_shell_print_prompt_and_cmd(sh);
		}
	}
}

static void ctrl_metakeys_handle(const struct shell *sh, char data)
{
	/* Optional feature */
	if (!IS_ENABLED(CONFIG_SHELL_METAKEYS)) {
		return;
	}

	switch (data) {
	case SHELL_VT100_ASCII_CTRL_A: /* CTRL + A */
		z_shell_op_cursor_home_move(sh);
		break;

	case SHELL_VT100_ASCII_CTRL_B: /* CTRL + B */
		z_shell_op_left_arrow(sh);
		break;

	case SHELL_VT100_ASCII_CTRL_C: /* CTRL + C */
		z_shell_op_cursor_end_move(sh);
		if (!z_shell_cursor_in_empty_line(sh)) {
			z_cursor_next_line_move(sh);
		}
		z_flag_history_exit_set(sh, true);
		state_set(sh, SHELL_STATE_ACTIVE);
		break;

	case SHELL_VT100_ASCII_CTRL_D: /* CTRL + D */
		z_shell_op_char_delete(sh);
		break;

	case SHELL_VT100_ASCII_CTRL_E: /* CTRL + E */
		z_shell_op_cursor_end_move(sh);
		break;

	case SHELL_VT100_ASCII_CTRL_F: /* CTRL + F */
		z_shell_op_right_arrow(sh);
		break;

	case SHELL_VT100_ASCII_CTRL_K: /* CTRL + K */
		z_shell_op_delete_from_cursor(sh);
		break;

	case SHELL_VT100_ASCII_CTRL_L: /* CTRL + L */
		Z_SHELL_VT100_CMD(sh, SHELL_VT100_CURSORHOME);
		Z_SHELL_VT100_CMD(sh, SHELL_VT100_CLEARSCREEN);
		z_shell_print_prompt_and_cmd(sh);
		break;

	case SHELL_VT100_ASCII_CTRL_N: /* CTRL + N */
		history_handle(sh, false);
		break;

	case SHELL_VT100_ASCII_CTRL_P: /* CTRL + P */
		history_handle(sh, true);
		break;

	case SHELL_VT100_ASCII_CTRL_U: /* CTRL + U */
		z_shell_op_cursor_home_move(sh);
		cmd_buffer_clear(sh);
		z_flag_history_exit_set(sh, true);
		z_clear_eos(sh);
		break;

	case SHELL_VT100_ASCII_CTRL_W: /* CTRL + W */
		z_shell_op_word_remove(sh);
		z_flag_history_exit_set(sh, true);
		break;

	default:
		break;
	}
}

/* Functions returns true if new line character shall be processed */
static bool process_nl(const struct shell *sh, uint8_t data)
{
	if ((data != '\r') && (data != '\n')) {
		z_flag_last_nl_set(sh, 0);
		return false;
	}

	if ((z_flag_last_nl_get(sh) == 0U) ||
	    (data == z_flag_last_nl_get(sh))) {
		z_flag_last_nl_set(sh, data);
		return true;
	}

	return false;
}

#define SHELL_ASCII_MAX_CHAR (127u)
static inline int ascii_filter(const char data)
{
	if (IS_ENABLED(CONFIG_SHELL_ASCII_FILTER)) {
		return (uint8_t) data > SHELL_ASCII_MAX_CHAR ? -EINVAL : 0;
	} else {
		return 0;
	}
}

static void state_collect(const struct shell *sh)
{
	size_t count = 0;
	char data;

	while (true) {
		shell_bypass_cb_t bypass = sh->ctx->bypass;

		if (bypass) {
			uint8_t buf[16];

			(void)sh->iface->api->read(sh->iface, buf,
							sizeof(buf), &count);
			if (count) {
				z_flag_cmd_ctx_set(sh, true);
				bypass(sh, buf, count);
				z_flag_cmd_ctx_set(sh, false);
				/* Check if bypass mode ended. */
				if (!(volatile shell_bypass_cb_t *)sh->ctx->bypass) {
					state_set(sh, SHELL_STATE_ACTIVE);
				} else {
					continue;
				}
			}

			return;
		}

		(void)sh->iface->api->read(sh->iface, &data,
					      sizeof(data), &count);
		if (count == 0) {
			return;
		}

		if (ascii_filter(data) != 0) {
			continue;
		}

		switch (sh->ctx->receive_state) {
		case SHELL_RECEIVE_DEFAULT:
			if (process_nl(sh, data)) {
				if (!sh->ctx->cmd_buff_len) {
					history_mode_exit(sh);
					z_cursor_next_line_move(sh);
				} else {
					/* Command execution */
					sh->ctx->ret_val = execute(sh);
				}
				/* Function responsible for printing prompt
				 * on received NL.
				 */
				state_set(sh, SHELL_STATE_ACTIVE);
				continue;
			}

			switch (data) {
			case SHELL_VT100_ASCII_ESC: /* ESCAPE */
				receive_state_change(sh, SHELL_RECEIVE_ESC);
				break;

			case '\0':
				break;

			case '\t': /* TAB */
				if (z_flag_echo_get(sh) &&
				    IS_ENABLED(CONFIG_SHELL_TAB)) {
					/* If the Tab key is pressed, "history
					 * mode" must be terminated because
					 * tab and history handlers are sharing
					 * the same array: temp_buff.
					 */
					z_flag_history_exit_set(sh, true);
					tab_handle(sh);
				}
				break;

			case SHELL_VT100_ASCII_BSPACE: /* BACKSPACE */
				if (z_flag_echo_get(sh)) {
					z_flag_history_exit_set(sh, true);
					z_shell_op_char_backspace(sh);
				}
				break;

			case SHELL_VT100_ASCII_DEL: /* DELETE */
				if (z_flag_echo_get(sh)) {
					z_flag_history_exit_set(sh, true);
					if (z_flag_mode_delete_get(sh)) {
						z_shell_op_char_backspace(sh);

					} else {
						z_shell_op_char_delete(sh);
					}
				}
				break;

			default:
				if (isprint((int) data) != 0) {
					z_flag_history_exit_set(sh, true);
					z_shell_op_char_insert(sh, data);
				} else if (z_flag_echo_get(sh)) {
					ctrl_metakeys_handle(sh, data);
				}
				break;
			}
			break;

		case SHELL_RECEIVE_ESC:
			if (data == '[') {
				receive_state_change(sh,
						SHELL_RECEIVE_ESC_SEQ);
				break;
			} else if (z_flag_echo_get(sh)) {
				alt_metakeys_handle(sh, data);
			}
			receive_state_change(sh, SHELL_RECEIVE_DEFAULT);
			break;

		case SHELL_RECEIVE_ESC_SEQ:
			receive_state_change(sh, SHELL_RECEIVE_DEFAULT);

			if (!z_flag_echo_get(sh)) {
				continue;
			}

			switch (data) {
			case 'A': /* UP arrow */
				history_handle(sh, true);
				break;

			case 'B': /* DOWN arrow */
				history_handle(sh, false);
				break;

			case 'C': /* RIGHT arrow */
				z_shell_op_right_arrow(sh);
				break;

			case 'D': /* LEFT arrow */
				z_shell_op_left_arrow(sh);
				break;

			case '4': /* END Button in ESC[n~ mode */
				receive_state_change(sh,
						SHELL_RECEIVE_TILDE_EXP);
				__fallthrough;
			case 'F': /* END Button in VT100 mode */
				z_shell_op_cursor_end_move(sh);
				break;

			case '1': /* HOME Button in ESC[n~ mode */
				receive_state_change(sh,
						SHELL_RECEIVE_TILDE_EXP);
				__fallthrough;
			case 'H': /* HOME Button in VT100 mode */
				z_shell_op_cursor_home_move(sh);
				break;

			case '2': /* INSERT Button in ESC[n~ mode */
				receive_state_change(sh,
						SHELL_RECEIVE_TILDE_EXP);
				__fallthrough;
			case 'L': {/* INSERT Button in VT100 mode */
				bool status = z_flag_insert_mode_get(sh);

				z_flag_insert_mode_set(sh, !status);
				break;
			}

			case '3':/* DELETE Button in ESC[n~ mode */
				receive_state_change(sh,
						SHELL_RECEIVE_TILDE_EXP);
				if (z_flag_echo_get(sh)) {
					z_shell_op_char_delete(sh);
				}
				break;

			default:
				break;
			}
			break;

		case SHELL_RECEIVE_TILDE_EXP:
			receive_state_change(sh, SHELL_RECEIVE_DEFAULT);
			break;

		default:
			receive_state_change(sh, SHELL_RECEIVE_DEFAULT);
			break;
		}
	}

	z_transport_buffer_flush(sh);
}

static void transport_evt_handler(enum shell_transport_evt evt_type, void *ctx)
{
	struct shell *sh = (struct shell *)ctx;
	struct k_poll_signal *signal;

	signal = (evt_type == SHELL_TRANSPORT_EVT_RX_RDY) ?
			&sh->ctx->signals[SHELL_SIGNAL_RXRDY] :
			&sh->ctx->signals[SHELL_SIGNAL_TXDONE];
	k_poll_signal_raise(signal, 0);
}

static void shell_log_process(const struct shell *sh)
{
	bool processed = false;
	int signaled = 0;
	int result;

	do {
		if (!IS_ENABLED(CONFIG_LOG_MODE_IMMEDIATE)) {
			z_shell_cmd_line_erase(sh);

			processed = z_shell_log_backend_process(
					sh->log_backend);
		}

		struct k_poll_signal *signal =
			&sh->ctx->signals[SHELL_SIGNAL_RXRDY];

		z_shell_print_prompt_and_cmd(sh);

		/* Arbitrary delay added to ensure that prompt is
		 * readable and can be used to enter further commands.
		 */
		if (sh->ctx->cmd_buff_len) {
			k_sleep(K_MSEC(15));
		}

		k_poll_signal_check(signal, &signaled, &result);

	} while (processed && !signaled);
}

static int instance_init(const struct shell *sh,
			 const void *transport_config,
			 struct shell_backend_config_flags cfg_flags)
{
	__ASSERT_NO_MSG((sh->shell_flag == SHELL_FLAG_CRLF_DEFAULT) ||
			(sh->shell_flag == SHELL_FLAG_OLF_CRLF));

	memset(sh->ctx, 0, sizeof(*sh->ctx));
	if (CONFIG_SHELL_CMD_ROOT[0]) {
		sh->ctx->selected_cmd = root_cmd_find(CONFIG_SHELL_CMD_ROOT);
	}

	history_init(sh);

	k_mutex_init(&sh->ctx->wr_mtx);

	for (int i = 0; i < SHELL_SIGNALS; i++) {
		k_poll_signal_init(&sh->ctx->signals[i]);
		k_poll_event_init(&sh->ctx->events[i],
				  K_POLL_TYPE_SIGNAL,
				  K_POLL_MODE_NOTIFY_ONLY,
				  &sh->ctx->signals[i]);
	}

	if (IS_ENABLED(CONFIG_SHELL_STATS)) {
		sh->stats->log_lost_cnt = 0;
	}

	z_flag_tx_rdy_set(sh, true);

	sh->ctx->vt100_ctx.cons.terminal_wid =
					CONFIG_SHELL_DEFAULT_TERMINAL_WIDTH;
	sh->ctx->vt100_ctx.cons.terminal_hei =
					CONFIG_SHELL_DEFAULT_TERMINAL_HEIGHT;

#if defined(CONFIG_SHELL_PROMPT_CHANGE) && CONFIG_SHELL_PROMPT_CHANGE
	shell_prompt_change(sh, sh->default_prompt);
#else
	sh->ctx->prompt = sh->default_prompt;
	sh->ctx->vt100_ctx.cons.name_len = z_shell_strlen(sh->ctx->prompt);
#endif

	/* Configure backend according to enabled shell features and backend
	 * specific settings.
	 */
	cfg_flags.obscure     &= IS_ENABLED(CONFIG_SHELL_START_OBSCURED);
	cfg_flags.use_colors  &= IS_ENABLED(CONFIG_SHELL_VT100_COLORS);
	cfg_flags.use_vt100   &= IS_ENABLED(CONFIG_SHELL_VT100_COMMANDS);
	cfg_flags.echo        &= IS_ENABLED(CONFIG_SHELL_ECHO_STATUS);
	cfg_flags.mode_delete &= IS_ENABLED(CONFIG_SHELL_BACKSPACE_MODE_DELETE);
	sh->ctx->cfg.flags = cfg_flags;

	int ret = sh->iface->api->init(sh->iface, transport_config,
				       transport_evt_handler,
				       (void *)sh);
	if (ret == 0) {
		state_set(sh, SHELL_STATE_INITIALIZED);
	}

	return ret;
}

static int instance_uninit(const struct shell *sh)
{
	__ASSERT_NO_MSG(sh);
	__ASSERT_NO_MSG(sh->ctx && sh->iface);

	int err;

	if (z_flag_processing_get(sh)) {
		return -EBUSY;
	}

	if (IS_ENABLED(CONFIG_SHELL_LOG_BACKEND)) {
		/* todo purge log queue */
		z_shell_log_backend_disable(sh->log_backend);
	}

	err = sh->iface->api->uninit(sh->iface);
	if (err != 0) {
		return err;
	}

	history_purge(sh);
	state_set(sh, SHELL_STATE_UNINITIALIZED);

	return 0;
}

typedef void (*shell_signal_handler_t)(const struct shell *sh);

static void shell_signal_handle(const struct shell *sh,
				enum shell_signal sig_idx,
				shell_signal_handler_t handler)
{
	struct k_poll_signal *sig = &sh->ctx->signals[sig_idx];
	int set;
	int res;

	k_poll_signal_check(sig, &set, &res);

	if (set) {
		k_poll_signal_reset(sig);
		handler(sh);
	}
}

static void kill_handler(const struct shell *sh)
{
	int err = instance_uninit(sh);

	if (sh->ctx->uninit_cb) {
		sh->ctx->uninit_cb(sh, err);
	}

	sh->ctx->tid = NULL;
	k_thread_abort(k_current_get());

	CODE_UNREACHABLE;
}

void shell_thread(void *shell_handle, void *arg_log_backend,
		  void *arg_log_level)
{
	struct shell *sh = shell_handle;
	int err;

	z_flag_handle_log_set(sh, (bool)arg_log_backend);
	sh->ctx->log_level = POINTER_TO_UINT(arg_log_level);

	err = sh->iface->api->enable(sh->iface, false);
	if (err != 0) {
		return;
	}

	if (IS_ENABLED(CONFIG_SHELL_AUTOSTART)) {
		/* Enable shell and print prompt. */
		err = shell_start(sh);
		if (err != 0) {
			return;
		}
	}

	while (true) {
		/* waiting for all signals except SHELL_SIGNAL_TXDONE */
		err = k_poll(sh->ctx->events, SHELL_SIGNAL_TXDONE,
			     K_FOREVER);

		if (err != 0) {
			k_mutex_lock(&sh->ctx->wr_mtx, K_FOREVER);
			z_shell_fprintf(sh, SHELL_ERROR,
					"Shell thread error: %d", err);
			k_mutex_unlock(&sh->ctx->wr_mtx);
			return;
		}

		k_mutex_lock(&sh->ctx->wr_mtx, K_FOREVER);

		shell_signal_handle(sh, SHELL_SIGNAL_KILL, kill_handler);
		shell_signal_handle(sh, SHELL_SIGNAL_RXRDY, shell_process);
		if (IS_ENABLED(CONFIG_SHELL_LOG_BACKEND)) {
			shell_signal_handle(sh, SHELL_SIGNAL_LOG_MSG,
					    shell_log_process);
		}

		if (sh->iface->api->update) {
			sh->iface->api->update(sh->iface);
		}

		k_mutex_unlock(&sh->ctx->wr_mtx);
	}
}

int shell_init(const struct shell *sh, const void *transport_config,
	       struct shell_backend_config_flags cfg_flags,
	       bool log_backend, uint32_t init_log_level)
{
	__ASSERT_NO_MSG(sh);
	__ASSERT_NO_MSG(sh->ctx && sh->iface && sh->default_prompt);

	if (sh->ctx->tid) {
		return -EALREADY;
	}

	int err = instance_init(sh, transport_config, cfg_flags);

	if (err != 0) {
		return err;
	}

	k_tid_t tid = k_thread_create(sh->thread,
				  sh->stack, CONFIG_SHELL_STACK_SIZE,
				  shell_thread, (void *)sh, (void *)log_backend,
				  UINT_TO_POINTER(init_log_level),
				  SHELL_THREAD_PRIORITY, 0, K_NO_WAIT);

	sh->ctx->tid = tid;
	k_thread_name_set(tid, sh->name);

	return 0;
}

void shell_uninit(const struct shell *sh, shell_uninit_cb_t cb)
{
	__ASSERT_NO_MSG(sh);

	if (IS_ENABLED(CONFIG_MULTITHREADING)) {
		struct k_poll_signal *signal =
				&sh->ctx->signals[SHELL_SIGNAL_KILL];

		sh->ctx->uninit_cb = cb;
		/* signal kill message */
		(void)k_poll_signal_raise(signal, 0);

		return;
	}

	int err = instance_uninit(sh);

	if (cb) {
		cb(sh, err);
	} else {
		__ASSERT_NO_MSG(0);
	}
}

int shell_start(const struct shell *sh)
{
	__ASSERT_NO_MSG(sh);
	__ASSERT_NO_MSG(sh->ctx && sh->iface && sh->default_prompt);

	if (state_get(sh) != SHELL_STATE_INITIALIZED) {
		return -ENOTSUP;
	}

	if (IS_ENABLED(CONFIG_SHELL_LOG_BACKEND) && z_flag_handle_log_get(sh)
	    && !z_flag_obscure_get(sh)) {
		z_shell_log_backend_enable(sh->log_backend, (void *)sh, sh->ctx->log_level);
	}

	k_mutex_lock(&sh->ctx->wr_mtx, K_FOREVER);

	if (IS_ENABLED(CONFIG_SHELL_VT100_COLORS)) {
		z_shell_vt100_color_set(sh, SHELL_NORMAL);
	}

	/* print new line before printing the prompt to clear the line
	 * vt100 are not used here for compatibility reasons
	 */
	z_cursor_next_line_move(sh);
	state_set(sh, SHELL_STATE_ACTIVE);

	k_mutex_unlock(&sh->ctx->wr_mtx);

	return 0;
}

int shell_stop(const struct shell *sh)
{
	__ASSERT_NO_MSG(sh);
	__ASSERT_NO_MSG(sh->ctx);

	enum shell_state state = state_get(sh);

	if ((state == SHELL_STATE_INITIALIZED) ||
	    (state == SHELL_STATE_UNINITIALIZED)) {
		return -ENOTSUP;
	}

	state_set(sh, SHELL_STATE_INITIALIZED);

	if (IS_ENABLED(CONFIG_SHELL_LOG_BACKEND)) {
		z_shell_log_backend_disable(sh->log_backend);
	}

	return 0;
}

void shell_process(const struct shell *sh)
{
	__ASSERT_NO_MSG(sh);
	__ASSERT_NO_MSG(sh->ctx);

	/* atomically set the processing flag */
	z_flag_processing_set(sh, true);

	switch (sh->ctx->state) {
	case SHELL_STATE_UNINITIALIZED:
	case SHELL_STATE_INITIALIZED:
		/* Console initialized but not started. */
		break;

	case SHELL_STATE_ACTIVE:
		state_collect(sh);
		break;
	default:
		break;
	}

	/* atomically clear the processing flag */
	z_flag_processing_set(sh, false);
}

const struct shell *shell_backend_get_by_name(const char *backend_name)
{
	STRUCT_SECTION_FOREACH(shell, backend) {
		if (strcmp(backend_name, backend->name) == 0) {
			return backend;
		}
	}

	return NULL;
}

/* This function mustn't be used from shell context to avoid deadlock.
 * However it can be used in shell command handlers.
 */
void shell_vfprintf(const struct shell *sh, enum shell_vt100_color color,
		   const char *fmt, va_list args)
{
	__ASSERT_NO_MSG(sh);
	__ASSERT(!k_is_in_isr(), "Thread context required.");
	__ASSERT_NO_MSG(sh->ctx);
	__ASSERT_NO_MSG(z_flag_cmd_ctx_get(sh) ||
			(k_current_get() != sh->ctx->tid));
	__ASSERT_NO_MSG(sh->fprintf_ctx);
	__ASSERT_NO_MSG(fmt);

	/* Sending a message to a non-active shell leads to a dead lock. */
	if (state_get(sh) != SHELL_STATE_ACTIVE) {
		z_flag_print_noinit_set(sh, true);
		return;
	}

	k_mutex_lock(&sh->ctx->wr_mtx, K_FOREVER);
	if (!z_flag_cmd_ctx_get(sh) && !sh->ctx->bypass && z_flag_use_vt100_get(sh)) {
		z_shell_cmd_line_erase(sh);
	}
	z_shell_vfprintf(sh, color, fmt, args);
	if (!z_flag_cmd_ctx_get(sh) && !sh->ctx->bypass && z_flag_use_vt100_get(sh)) {
		z_shell_print_prompt_and_cmd(sh);
	}
	z_transport_buffer_flush(sh);
	k_mutex_unlock(&sh->ctx->wr_mtx);
}

/* These functions mustn't be used from shell context to avoid deadlock:
 * - shell_fprintf_impl
 * - shell_fprintf_info
 * - shell_fprintf_normal
 * - shell_fprintf_warn
 * - shell_fprintf_error
 * However, they can be used in shell command handlers.
 */
void shell_fprintf_impl(const struct shell *sh, enum shell_vt100_color color,
		   const char *fmt, ...)
{
	va_list args;

	va_start(args, fmt);
	shell_vfprintf(sh, color, fmt, args);
	va_end(args);
}

void shell_fprintf_info(const struct shell *sh, const char *fmt, ...)
{
	va_list args;

	va_start(args, fmt);
	shell_vfprintf(sh, SHELL_INFO, fmt, args);
	va_end(args);
}

void shell_fprintf_normal(const struct shell *sh, const char *fmt, ...)
{
	va_list args;

	va_start(args, fmt);
	shell_vfprintf(sh, SHELL_NORMAL, fmt, args);
	va_end(args);
}

void shell_fprintf_warn(const struct shell *sh, const char *fmt, ...)
{
	va_list args;

	va_start(args, fmt);
	shell_vfprintf(sh, SHELL_WARNING, fmt, args);
	va_end(args);
}

void shell_fprintf_error(const struct shell *sh, const char *fmt, ...)
{
	va_list args;

	va_start(args, fmt);
	shell_vfprintf(sh, SHELL_ERROR, fmt, args);
	va_end(args);
}

void shell_hexdump_line(const struct shell *sh, unsigned int offset,
			const uint8_t *data, size_t len)
{
	__ASSERT_NO_MSG(sh);

	int i;

	shell_fprintf_normal(sh, "%08X: ", offset);

	for (i = 0; i < SHELL_HEXDUMP_BYTES_IN_LINE; i++) {
		if (i > 0 && !(i % 8)) {
			shell_fprintf_normal(sh, " ");
		}

		if (i < len) {
			shell_fprintf_normal(sh, "%02x ",
					     data[i] & 0xFF);
		} else {
			shell_fprintf_normal(sh, "   ");
		}
	}

	shell_fprintf_normal(sh, "|");

	for (i = 0; i < SHELL_HEXDUMP_BYTES_IN_LINE; i++) {
		if (i > 0 && !(i % 8)) {
			shell_fprintf_normal(sh, " ");
		}

		if (i < len) {
			char c = data[i];

			shell_fprintf_normal(sh, "%c",
					     isprint((int)c) != 0 ? c : '.');
		} else {
			shell_fprintf_normal(sh, " ");
		}
	}

	shell_print(sh, "|");
}

void shell_hexdump(const struct shell *sh, const uint8_t *data, size_t len)
{
	__ASSERT_NO_MSG(sh);

	const uint8_t *p = data;
	size_t line_len;

	while (len) {
		line_len = MIN(len, SHELL_HEXDUMP_BYTES_IN_LINE);

		shell_hexdump_line(sh, p - data, p, line_len);

		len -= line_len;
		p += line_len;
	}
}

int shell_prompt_change(const struct shell *sh, const char *prompt)
{
#if defined(CONFIG_SHELL_PROMPT_CHANGE) && CONFIG_SHELL_PROMPT_CHANGE
	__ASSERT_NO_MSG(sh);

	if (prompt == NULL) {
		return -EINVAL;
	}

	static const size_t mtx_timeout_ms = 20;
	size_t prompt_length = z_shell_strlen(prompt);

	if (k_mutex_lock(&sh->ctx->wr_mtx, K_MSEC(mtx_timeout_ms))) {
		return -EBUSY;
	}

	if ((prompt_length + 1 > CONFIG_SHELL_PROMPT_BUFF_SIZE) || (prompt_length == 0)) {
		k_mutex_unlock(&sh->ctx->wr_mtx);
		return -EINVAL;
	}

	strcpy(sh->ctx->prompt, prompt);

	sh->ctx->vt100_ctx.cons.name_len = prompt_length;

	k_mutex_unlock(&sh->ctx->wr_mtx);

	return 0;
#else
	return -EPERM;
#endif
}

void shell_help(const struct shell *sh)
{
	k_mutex_lock(&sh->ctx->wr_mtx, K_FOREVER);
	shell_internal_help_print(sh);
	k_mutex_unlock(&sh->ctx->wr_mtx);
}

int shell_execute_cmd(const struct shell *sh, const char *cmd)
{
	uint16_t cmd_len = z_shell_strlen(cmd);
	int ret_val;

	if (cmd == NULL) {
		return -ENOEXEC;
	}

	if (cmd_len > (CONFIG_SHELL_CMD_BUFF_SIZE - 1)) {
		return -ENOMEM;
	}

	if (sh == NULL) {
#if defined(CONFIG_SHELL_BACKEND_DUMMY)
		sh = shell_backend_dummy_get_ptr();
#else
		return -EINVAL;
#endif
	}

	__ASSERT(!z_flag_cmd_ctx_get(sh), "Function cannot be called"
					  " from command context");

	strcpy(sh->ctx->cmd_buff, cmd);
	sh->ctx->cmd_buff_len = cmd_len;
	sh->ctx->cmd_buff_pos = cmd_len;

	k_mutex_lock(&sh->ctx->wr_mtx, K_FOREVER);
	ret_val = execute(sh);
	k_mutex_unlock(&sh->ctx->wr_mtx);

	cmd_buffer_clear(sh);

	return ret_val;
}

int shell_insert_mode_set(const struct shell *sh, bool val)
{
	if (sh == NULL) {
		return -EINVAL;
	}

	return (int)z_flag_insert_mode_set(sh, val);
}

int shell_use_colors_set(const struct shell *sh, bool val)
{
	if (sh == NULL) {
		return -EINVAL;
	}

	return (int)z_flag_use_colors_set(sh, val);
}

int shell_use_vt100_set(const struct shell *sh, bool val)
{
	if (sh == NULL) {
		return -EINVAL;
	}

	return (int)z_flag_use_vt100_set(sh, val);
}

int shell_get_return_value(const struct shell *sh)
{
	if (sh == NULL) {
		return -EINVAL;
	}

	return z_shell_get_return_value(sh);
}

int shell_echo_set(const struct shell *sh, bool val)
{
	if (sh == NULL) {
		return -EINVAL;
	}

	return (int)z_flag_echo_set(sh, val);
}

int shell_obscure_set(const struct shell *sh, bool val)
{
	if (sh == NULL) {
		return -EINVAL;
	}

	return (int)z_flag_obscure_set(sh, val);
}

int shell_mode_delete_set(const struct shell *sh, bool val)
{
	if (sh == NULL) {
		return -EINVAL;
	}

	return (int)z_flag_mode_delete_set(sh, val);
}

void shell_set_bypass(const struct shell *sh, shell_bypass_cb_t bypass)
{
	__ASSERT_NO_MSG(sh);

	sh->ctx->bypass = bypass;

	if (bypass == NULL) {
		cmd_buffer_clear(sh);
	}
}

bool shell_ready(const struct shell *sh)
{
	__ASSERT_NO_MSG(sh);

	return state_get(sh) ==	SHELL_STATE_ACTIVE;
}

static int cmd_help(const struct shell *sh, size_t argc, char **argv)
{
	ARG_UNUSED(argc);
	ARG_UNUSED(argv);

#if defined(CONFIG_SHELL_TAB)
	shell_print(sh, "Please press the <Tab> button to see all available "
			   "commands.");
#endif

#if defined(CONFIG_SHELL_TAB_AUTOCOMPLETION)
	shell_print(sh,
		"You can also use the <Tab> button to prompt or auto-complete"
		" all commands or its subcommands.");
#endif

#if defined(CONFIG_SHELL_HELP)
	shell_print(sh,
		"You can try to call commands with <-h> or <--help> parameter"
		" for more information.");
#endif

#if defined(CONFIG_SHELL_METAKEYS)
	shell_print(sh,
		"\nShell supports following meta-keys:\n"
		"  Ctrl + (a key from: abcdefklnpuw)\n"
		"  Alt  + (a key from: bf)\n"
		"Please refer to shell documentation for more details.");
#endif

	if (IS_ENABLED(CONFIG_SHELL_HELP)) {
		/* For NULL argument function will print all root commands */
		z_shell_help_subcmd_print(sh, NULL,
					 "\nAvailable commands:\n");
	} else {
		const struct shell_static_entry *entry;
		size_t idx = 0;

		shell_print(sh, "\nAvailable commands:");
		while ((entry = z_shell_cmd_get(NULL, idx++, NULL)) != NULL) {
			shell_print(sh, "  %s", entry->syntax);
		}
	}

	return 0;
}

SHELL_CMD_ARG_REGISTER(help, NULL, "Prints the help message.", cmd_help, 1, 0);
