/*
 * 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 dynamically 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: unknown 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);
