/*
 * Copyright (c) 2015 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @file
 * @brief Console handler implementation of shell.h API
 */


#include <zephyr.h>
#include <stdio.h>
#include <string.h>

#include <console/console.h>
#include <misc/printk.h>
#include <misc/util.h>

#ifdef CONFIG_UART_CONSOLE
#include <console/uart_console.h>
#endif
#ifdef CONFIG_TELNET_CONSOLE
#include <console/telnet_console.h>
#endif

#include <shell/shell.h>

#define ARGC_MAX 10
#define COMMAND_MAX_LEN 50
#define MODULE_NAME_MAX_LEN 20
/* additional chars are " >" (include '\0' )*/
#define PROMPT_SUFFIX 3
#define PROMPT_MAX_LEN (MODULE_NAME_MAX_LEN + PROMPT_SUFFIX)

/* command table is located in the dedicated memory segment (.shell_) */
extern struct shell_module __shell_cmd_start[];
extern struct shell_module __shell_cmd_end[];
#define NUM_OF_SHELL_ENTITIES (__shell_cmd_end - __shell_cmd_start)

static const char *prompt;
static char default_module_prompt[PROMPT_MAX_LEN];
static int default_module = -1;

#define STACKSIZE CONFIG_CONSOLE_SHELL_STACKSIZE
static K_THREAD_STACK_DEFINE(stack, STACKSIZE);
static struct k_thread shell_thread;

#define MAX_CMD_QUEUED CONFIG_CONSOLE_SHELL_MAX_CMD_QUEUED
static struct console_input buf[MAX_CMD_QUEUED];

static struct k_fifo avail_queue;
static struct k_fifo cmds_queue;

static shell_cmd_function_t app_cmd_handler;
static shell_prompt_function_t app_prompt_handler;

static const char *get_prompt(void)
{
	if (app_prompt_handler) {
		const char *str;

		str = app_prompt_handler();
		if (str) {
			return str;
		}
	}

	if (default_module != -1) {
		if (__shell_cmd_start[default_module].prompt) {
			const char *ret;

			ret = __shell_cmd_start[default_module].prompt();
			if (ret) {
				return ret;
			}
		}

		return default_module_prompt;
	}

	return prompt;
}

static void line_queue_init(void)
{
	int i;

	for (i = 0; i < MAX_CMD_QUEUED; i++) {
		k_fifo_put(&avail_queue, &buf[i]);
	}
}

static size_t line2argv(char *str, char *argv[], size_t size)
{
	size_t argc = 0;

	if (!strlen(str)) {
		return 0;
	}

	while (*str && *str == ' ') {
		str++;
	}

	if (!*str) {
		return 0;
	}

	argv[argc++] = str;

	while ((str = strchr(str, ' '))) {
		*str++ = '\0';

		while (*str && *str == ' ') {
			str++;
		}

		if (!*str) {
			break;
		}

		argv[argc++] = str;

		if (argc == size) {
			printk("Too many parameters (max %zu)\n", size - 1);
			return 0;
		}
	}

	/* keep it POSIX style where argv[argc] is required to be NULL */
	argv[argc] = NULL;

	return argc;
}

static int get_destination_module(const char *module_str)
{
	int i;

	for (i = 0; i < NUM_OF_SHELL_ENTITIES; i++) {
		if (!strncmp(module_str,
			     __shell_cmd_start[i].module_name,
			     MODULE_NAME_MAX_LEN)) {
			return i;
		}
	}

	return -1;
}

/* For a specific command: argv[0] = module name, argv[1] = command name
 * If a default module was selected: argv[0] = command name
 */
static const char *get_command_and_module(char *argv[], int *module)
{
	*module = -1;

	if (!argv[0]) {
		printk("Unrecognized command\n");
		return NULL;
	}

	if (default_module == -1) {
		if (!argv[1] || argv[1][0] == '\0') {
			printk("Unrecognized command: %s\n", argv[0]);
			return NULL;
		}

		*module = get_destination_module(argv[0]);
		if (*module == -1) {
			printk("Illegal module %s\n", argv[0]);
			return NULL;
		}

		return argv[1];
	}

	*module = default_module;
	return argv[0];
}

static int show_cmd_help(char *argv[], bool full)
{
	const char *command = NULL;
	int module = -1;
	const struct shell_module *shell_module;
	int i;

	command = get_command_and_module(argv, &module);
	if ((module == -1) || (command == NULL)) {
		return 0;
	}

	shell_module = &__shell_cmd_start[module];
	for (i = 0; shell_module->commands[i].cmd_name; i++) {
		if (!strcmp(command, shell_module->commands[i].cmd_name)) {
			printk("Usage: %s %s\n",
			       shell_module->commands[i].cmd_name,
			       shell_module->commands[i].help ?
			       shell_module->commands[i].help : "");
			if (full && shell_module->commands[i].desc) {
				printk("%s\n", shell_module->commands[i].desc);
			}
			return 0;
		}
	}

	printk("Unrecognized command: %s\n", argv[0]);
	return -EINVAL;
}

static void print_module_commands(const int module)
{
	const struct shell_module *shell_module = &__shell_cmd_start[module];
	int i;

	printk("help\n");

	for (i = 0; shell_module->commands[i].cmd_name; i++) {
		printk("%-28s %s\n",
		       shell_module->commands[i].cmd_name,
		       shell_module->commands[i].help ?
		       shell_module->commands[i].help : "");
	}
}

static int show_help(int argc, char *argv[])
{
	int module;

	/* help per command */
	if ((argc > 2) || ((default_module != -1) && (argc == 2))) {
		return show_cmd_help(&argv[1], true);
	}

	/* help per module */
	if ((argc == 2) || ((default_module != -1) && (argc == 1))) {
		if (default_module == -1) {
			module = get_destination_module(argv[1]);
			if (module == -1) {
				printk("Illegal module %s\n", argv[1]);
				return -EINVAL;
			}
		} else {
			module = default_module;
		}

		print_module_commands(module);
		printk("\nEnter 'exit' to leave current module.\n");
	} else { /* help for all entities */
		printk("Available modules:\n");
		for (module = 0; module < NUM_OF_SHELL_ENTITIES; module++) {
			printk("%s\n", __shell_cmd_start[module].module_name);
		}
		printk("\nTo select a module, enter 'select <module name>'.\n");
	}

	return 0;
}

static int set_default_module(const char *name)
{
	int module;

	if (strlen(name) > MODULE_NAME_MAX_LEN) {
		printk("Module name %s is too long, default is not changed\n",
			name);
		return -EINVAL;
	}

	module = get_destination_module(name);

	if (module == -1) {
		printk("Illegal module %s, default is not changed\n", name);
		return -EINVAL;
	}

	default_module = module;

	strncpy(default_module_prompt, name, MODULE_NAME_MAX_LEN);
	strcat(default_module_prompt, "> ");

	return 0;
}

static int select_module(int argc, char *argv[])
{
	if (argc == 1) {
		default_module = -1;
		return 0;
	}

	return set_default_module(argv[1]);
}

static int exit_module(int argc, char *argv[])
{
	if (argc == 1) {
		default_module = -1;
	}

	return 0;
}

static shell_cmd_function_t get_cb(int *argc, char *argv[], int *module)
{
	const char *first_string = argv[0];
	const struct shell_module *shell_module;
	const char *command;
	int i;

	if (!strcmp(first_string, "help")) {
		return show_help;
	}

	if (!strcmp(first_string, "select")) {
		return select_module;
	}

	if (!strcmp(first_string, "exit")) {
		return exit_module;
	}

	if ((*argc == 1) && (default_module == -1)) {
		printk("Missing parameter\n");
		return NULL;
	}

	command = get_command_and_module(argv, module);
	if ((*module == -1) || (command == NULL)) {
		return NULL;
	}

	shell_module = &__shell_cmd_start[*module];
	for (i = 0; shell_module->commands[i].cmd_name; i++) {
		if (!strcmp(command, shell_module->commands[i].cmd_name)) {
			return shell_module->commands[i].cb;
		}
	}

	return NULL;
}

static inline void print_cmd_unknown(char *argv)
{
	printk("Unrecognized command: %s\n", argv);
	printk("Type 'help' for list of available commands\n");
}

int shell_exec(char *line)
{
	char *argv[ARGC_MAX + 1];
	int argc;
	int module = default_module;
	int err;
	shell_cmd_function_t cb;

	argc = line2argv(line, argv, ARRAY_SIZE(argv));
	if (!argc) {
		return -EINVAL;
	}

	cb = get_cb(&argc, argv, &module);
	if (!cb) {
		if (app_cmd_handler != NULL) {
			cb = app_cmd_handler;
		} else {
			print_cmd_unknown(argv[0]);
			return -EINVAL;
		}
	}

	/* Execute callback with arguments */
	if (module != -1 && module != default_module) {
		/* Ajust parameters to point to the actual command */
		err = cb(argc - 1, &argv[1]);
	} else {
		err = cb(argc, argv);
	}

	if (err < 0) {
		show_cmd_help(argv, false);
	}

	return err;
}

static void shell(void *p1, void *p2, void *p3)
{
	ARG_UNUSED(p1);
	ARG_UNUSED(p2);
	ARG_UNUSED(p3);

	while (1) {
		struct console_input *cmd;

		printk("%s", get_prompt());

		cmd = k_fifo_get(&cmds_queue, K_FOREVER);

		shell_exec(cmd->line);

		k_fifo_put(&avail_queue, cmd);
	}
}

static int get_command_to_complete(char *str, char **command_prefix)
{
	char dest_str[MODULE_NAME_MAX_LEN];
	int dest = -1;
	char *start;

	/* remove ' ' at the beginning of the line */
	while (*str && *str == ' ') {
		str++;
	}

	if (!*str) {
		return -1;
	}

	start = str;

	if (default_module != -1) {
		dest = default_module;
		/* caller function already checks str len and put '\0' */
		*command_prefix = str;
	}

	/*
	 * In case of a default module: only one parameter is possible.
	 * Otherwise, only two parameters are possibles.
	 */
	str = strchr(str, ' ');
	if (default_module != -1) {
		return (str == NULL) ? dest : -1;
	}

	if (str == NULL) {
		return -1;
	}

	if ((str - start + 1) >= MODULE_NAME_MAX_LEN) {
		return -1;
	}

	strncpy(dest_str, start, (str - start + 1));
	dest_str[str - start] = '\0';
	dest = get_destination_module(dest_str);
	if (dest == -1) {
		return -1;
	}

	str++;

	/* caller func has already checked str len and put '\0' at the end */
	*command_prefix = str;
	str = strchr(str, ' ');

	/* only two parameters are possibles in case of no default module */
	return (str == NULL) ? dest : -1;
}

static u8_t completion(char *line, u8_t len)
{
	const char *first_match = NULL;
	int common_chars = -1, space = 0;
	int i, dest, command_len;
	const struct shell_module *module;
	char *command_prefix;

	if (len >= (MODULE_NAME_MAX_LEN + COMMAND_MAX_LEN - 1)) {
		return 0;
	}

	/*
	 * line to completion is not ended by '\0' as the line that gets from
	 * k_fifo_get function
	 */
	line[len] = '\0';
	dest = get_command_to_complete(line, &command_prefix);
	if (dest == -1) {
		return 0;
	}

	command_len = strlen(command_prefix);

	module = &__shell_cmd_start[dest];

	for (i = 0; module->commands[i].cmd_name; i++) {
		int j;

		if (strncmp(command_prefix,
			module->commands[i].cmd_name, command_len)) {
			continue;
		}

		if (!first_match) {
			first_match = module->commands[i].cmd_name;
			continue;
		}

		/* more commands match, print first match */
		if (first_match && (common_chars < 0)) {
			printk("\n%s\n", first_match);
			common_chars = strlen(first_match);
		}

		/* cut common part of matching names */
		for (j = 0; j < common_chars; j++) {
			if (first_match[j] != module->commands[i].cmd_name[j]) {
				break;
			}
		}

		common_chars = j;

		printk("%s\n", module->commands[i].cmd_name);
	}

	/* no match, do nothing */
	if (!first_match) {
		return 0;
	}

	if (common_chars >= 0) {
		/* multiple match, restore prompt */
		printk("%s", get_prompt());
		printk("%s", line);
	} else {
		common_chars = strlen(first_match);
		space = 1;
	}

	/* complete common part */
	for (i = command_len; i < common_chars; i++) {
		printk("%c", first_match[i]);
		line[len++] = first_match[i];
	}

	/* for convenience add space after command */
	if (space) {
		printk(" ");
		line[len] = ' ';
	}

	return common_chars - command_len + space;
}


void shell_init(const char *str)
{
	k_fifo_init(&cmds_queue);
	k_fifo_init(&avail_queue);

	line_queue_init();

	prompt = str ? str : "";

	k_thread_create(&shell_thread, stack, STACKSIZE, shell, NULL, NULL,
			NULL, K_PRIO_COOP(7), 0, K_NO_WAIT);

	/* Register serial console handler */
#ifdef CONFIG_UART_CONSOLE
	uart_register_input(&avail_queue, &cmds_queue, completion);
#endif
#ifdef CONFIG_TELNET_CONSOLE
	telnet_register_input(&avail_queue, &cmds_queue, completion);
#endif
}

/** @brief Optionally register an app default cmd handler.
 *
 *  @param handler To be called if no cmd found in cmds registered with
 *  shell_init.
 */
void shell_register_app_cmd_handler(shell_cmd_function_t handler)
{
	app_cmd_handler = handler;
}

void shell_register_prompt_handler(shell_prompt_function_t handler)
{
	app_prompt_handler = handler;
}

void shell_register_default_module(const char *name)
{
	int result = set_default_module(name);

	if (result != -1) {
		printk("\n%s", default_module_prompt);
	}
}
