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

#include <utils.h>

#include "atmel_start.h"
#include "command.h"

struct cmd_state {
	const char *prompt;
	char buf[128];
	unsigned int buf_idx;
	const struct command_fn *cmd[32];
	unsigned int cmd_idx;
};

static struct cmd_state g_cmds;

int command_register(const struct command_fn *cmd)
{
	if (g_cmds.cmd_idx >= ARRAY_SIZE(g_cmds.cmd))
		return -1;
	g_cmds.cmd[g_cmds.cmd_idx++] = cmd;
	return 0;
}

DEFUN(help, help_cmd, "help", "Print command reference")
{
	unsigned int i;
	printf("Help:\r\n");
	printf(" Command          Help\r\n");
	printf(" ---------------- ----\r\n");
	for (i = 0; i < g_cmds.cmd_idx; i++)
		printf(" %-16s %s\r\n", g_cmds.cmd[i]->command, g_cmds.cmd[i]->help);
}

static void cmd_execute()
{
	char *argv[16];
	unsigned int i;
	int argc = 0;
	char *cur;

	printf("\r\n");
	memset(argv, 0, sizeof(argv));

	for (cur = strtok(g_cmds.buf, " "); cur; cur = strtok(NULL, " ")) {
		if (argc >= ARRAY_SIZE(argv))
			break;
		argv[argc++] = cur;
	}

	for (i = 0; i < g_cmds.cmd_idx; i++) {
		if (!strcmp(g_cmds.cmd[i]->command, argv[0])) {
			g_cmds.cmd[i]->fn(argc, argv);
			return;
		}
	}
	printf("Unknown command: '%s'\r\n", argv[0]);
}

static void cmd_buf_reset(void)
{
	memset(g_cmds.buf, 0, sizeof(g_cmds.buf));
	g_cmds.buf_idx = 0;
}

static void cmd_buf_append(char c)
{
	g_cmds.buf[g_cmds.buf_idx++] = c;
}

void command_print_prompt(void)
{
	printf(g_cmds.prompt);
}

void command_try_recv(void)
{
	unsigned int i = 0;

	/* yield CPU after maximum of 10 received characters */
	while (usart_async_rings_is_rx_not_empty(&UART_debug) && (i < 10)) {
		int c = getchar();
		if (c < 0)
			return;
		if (c == '\r' || c == '\n' || g_cmds.buf_idx >= sizeof(g_cmds.buf)-1) {
			/* skip empty commands */
			if (g_cmds.buf_idx == 0)
				return;
			cmd_execute();
			cmd_buf_reset();
			printf(g_cmds.prompt);
			return;
		} else {
			/* print + append character */
			putchar(c);
			cmd_buf_append(c);
		}

		i++;
	}
}

void command_init(const char *prompt)
{
	g_cmds.prompt = prompt;
	command_register(&help_cmd);
}
