/*
 * 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;
	__ASSERT_NO_MSG(columns != 0);
	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);

	/*
	 * If the shell is stopped with the shell_stop function, its backend remains active
	 * and continues to buffer incoming data. As a result, when the shell is resumed,
	 * all buffered data is processed, which may lead to the execution of commands
	 * received while the shell was stopped.
	 */
	z_shell_backend_rx_buffer_flush(sh);

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