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

#include <shell/shell.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>

#define MAX_CMD_CNT (20u)
#define MAX_CMD_LEN (33u)

/* buffer holding dynamicly created user commands */
static char dynamic_cmd_buffer[MAX_CMD_CNT][MAX_CMD_LEN];
/* commands counter */
static uint8_t dynamic_cmd_cnt;

typedef int cmp_t(const void *, const void *);
extern void qsort(void *a, size_t n, size_t es, cmp_t *cmp);

/* function required by qsort */
static int string_cmp(const void *p_a, const void *p_b)
{
	return strcmp((const char *)p_a, (const char *)p_b);
}

static int cmd_dynamic_add(const struct shell *shell,
			   size_t argc, char **argv)
{
	uint16_t cmd_len;
	uint8_t idx;

	ARG_UNUSED(argc);

	if (dynamic_cmd_cnt >= MAX_CMD_CNT) {
		shell_error(shell, "command limit reached");
		return -ENOEXEC;
	}

	cmd_len = strlen(argv[1]);

	if (cmd_len >= MAX_CMD_LEN) {
		shell_error(shell, "too long command");
		return -ENOEXEC;
	}

	for (idx = 0U; idx < cmd_len; idx++) {
		if (!isalnum((int)(argv[1][idx]))) {
			shell_error(shell,
				    "bad command name - please use only"
				    " alphanumerical characters");
			return -ENOEXEC;
		}
	}

	for (idx = 0U; idx < MAX_CMD_CNT; idx++) {
		if (!strcmp(dynamic_cmd_buffer[idx], argv[1])) {
			shell_error(shell, "duplicated command");
			return -ENOEXEC;
		}
	}

	sprintf(dynamic_cmd_buffer[dynamic_cmd_cnt++], "%s", argv[1]);

	qsort(dynamic_cmd_buffer, dynamic_cmd_cnt,
	      sizeof(dynamic_cmd_buffer[0]), string_cmp);

	shell_print(shell, "command added successfully");

	return 0;
}

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

	for (uint8_t idx = 0; idx <  dynamic_cmd_cnt; idx++) {
		if (!strcmp(dynamic_cmd_buffer[idx], argv[1])) {
			shell_print(shell, "dynamic command: %s", argv[1]);
			return 0;
		}
	}

	shell_error(shell, "%s: uknown parameter: %s", argv[0], argv[1]);

	return -ENOEXEC;
}

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

	for (uint8_t idx = 0; idx <  dynamic_cmd_cnt; idx++) {
		if (!strcmp(dynamic_cmd_buffer[idx], argv[1])) {
			if (idx == MAX_CMD_CNT - 1) {
				dynamic_cmd_buffer[idx][0] = '\0';
			} else {
				memmove(dynamic_cmd_buffer[idx],
					dynamic_cmd_buffer[idx + 1],
					sizeof(dynamic_cmd_buffer[idx]) *
					(dynamic_cmd_cnt - idx));
			}

			--dynamic_cmd_cnt;
			shell_print(shell, "command removed successfully");
			return 0;
		}
	}
	shell_error(shell, "did not find command: %s", argv[1]);

	return -ENOEXEC;
}

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

	if (dynamic_cmd_cnt == 0U) {
		shell_warn(shell, "Please add some commands first.");
		return -ENOEXEC;
	}

	shell_print(shell, "Dynamic command list:");

	for (uint8_t i = 0; i < dynamic_cmd_cnt; i++) {
		shell_print(shell, "[%3d] %s", i, dynamic_cmd_buffer[i]);
	}

	return 0;
}

/* dynamic command creation */
static void dynamic_cmd_get(size_t idx, struct shell_static_entry *entry)
{
	if (idx < dynamic_cmd_cnt) {
		/* m_dynamic_cmd_buffer must be sorted alphabetically to ensure
		 * correct CLI completion
		 */
		entry->syntax = dynamic_cmd_buffer[idx];
		entry->handler  = NULL;
		entry->subcmd = NULL;
		entry->help = "Show dynamic command name.";
	} else {
		/* if there are no more dynamic commands available syntax
		 * must be set to NULL.
		 */
		entry->syntax = NULL;
	}
}

SHELL_DYNAMIC_CMD_CREATE(m_sub_dynamic_set, dynamic_cmd_get);
SHELL_STATIC_SUBCMD_SET_CREATE(m_sub_dynamic,
	SHELL_CMD_ARG(add, NULL,
		"Add a new dynamic command.\nExample usage: [ dynamic add test "
		"] will add a dynamic command 'test'.\nIn this example, command"
		" name length is limited to 32 chars. You can add up to 20"
		" commands. Commands are automatically sorted to ensure correct"
		" shell completion.",
		cmd_dynamic_add, 2, 0),
	SHELL_CMD_ARG(execute, &m_sub_dynamic_set,
		"Execute a command.", cmd_dynamic_execute, 2, 0),
	SHELL_CMD_ARG(remove, &m_sub_dynamic_set,
		"Remove a command.", cmd_dynamic_remove, 2, 0),
	SHELL_CMD_ARG(show, NULL,
		"Show all added dynamic commands.", cmd_dynamic_show, 1, 0),
	SHELL_SUBCMD_SET_END
);

SHELL_CMD_REGISTER(dynamic, &m_sub_dynamic,
		   "Demonstrate dynamic command usage.", NULL);
