/*
 * Copyright (c) 2008 Travis Geiselbrecht
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files
 * (the "Software"), to deal in the Software without restriction,
 * including without limitation the rights to use, copy, modify, merge,
 * publish, distribute, sublicense, and/or sell copies of the Software,
 * and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
#include <app/console.h>
#include <debug.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>

static cmd_block *command_list = NULL;

/* a linear array of statically defined command blocks,
   defined in the linker script.
 */
extern cmd_block __commands_start;
extern cmd_block __commands_end;

static int cmd_help(int argc, const cmd_args *argv);
static int cmd_test(int argc, const cmd_args *argv);

STATIC_COMMAND_START
	{ "help", "this list", &cmd_help },
	{ "test", "test the command processor", &cmd_test },
STATIC_COMMAND_END(help); 

int console_init(void)
{
	printf("console_init: entry\n");

	/* add all the statically defined commands to the list */
	cmd_block *block;
	for (block = &__commands_start; block != &__commands_end; block++) {
		console_register_commands(block);
	}
	
	return 0;
}

static const cmd *match_command(const char *command)
{
	cmd_block *block;
	size_t i;

	for (block = command_list; block != NULL; block = block->next) {
		const cmd *curr_cmd = block->list;
		for (i = 0; i < block->count; i++) {
			if (strcmp(command, curr_cmd[i].cmd_str) == 0) {
				return &curr_cmd[i];
			}
		}
	}

	return NULL;
}

static int read_line(char *buffer, int len)
{
	int pos = 0;
	int escape_level = 0;

	for (;;) {
		char c;

		/* loop until we get a char */
		if (dgetc(&c) < 0)
			continue;

//		printf("c = 0x%hhx\n", c); 
		
		if (escape_level == 0) {
			switch (c) {
				case '\r':
				case '\n':
					dputc(c);
					goto done;

				case 0x7f: // backspace or delete
				case 0x8:
					if (pos > 0) {
						pos--;
						dputs("\x1b[1D"); // move to the left one
						dputc(' ');
						dputs("\x1b[1D"); // move to the left one
					}
					break;

				case 0x1b: // escape
					escape_level++;
					break;

				default:
					buffer[pos++] = c;
					dputc(c);
			}
		} else if (escape_level == 1) {
			// inside an escape, look for '['
			if (c == '[') {
				escape_level++;
			} else {
				// we didn't get it, abort
				escape_level = 0;
			}
		} else { // escape_level > 1
			switch (c) {
				case 67: // right arrow
					buffer[pos++] = ' ';
					dputc(' ');
					break;
				case 68: // left arrow
					if (pos > 0) {
						pos--;
						dputs("\x1b[1D"); // move to the left one
						dputc(' ');
						dputs("\x1b[1D"); // move to the left one
					}
					break;
				case 65: // up arrow
				case 66: // down arrow
					// XXX do history here
					break;
				default:
					break;
			}
			escape_level = 0;
		}

		/* end of line. */
		if (pos == (len - 1)) {
			dputs("\nerror: line too long\n");
			pos = 0;
			goto done;
		}
	}

done:
//	printf("returning pos %d\n", pos);

	buffer[pos] = 0;
	return pos;
}

static int tokenize_command(char *buffer, cmd_args *args, int arg_count)
{
	int pos;
	int arg;
	bool finished;
	enum {
		INITIAL = 0,
		IN_SPACE,
		IN_TOKEN
	} state;

	pos = 0;
	arg = 0;
	state = INITIAL;
	finished = false;

	for (;;) {
		char c = buffer[pos];

		if (c == '\0')
			finished = true;

//		printf("c 0x%hhx state %d arg %d pos %d\n", c, state, arg, pos);

		switch (state) {
			case INITIAL:
				if (isspace(c)) {
					state = IN_SPACE;
				} else {
					state = IN_TOKEN;
					args[arg].str = &buffer[pos];
				}
				break;
			case IN_TOKEN:
				if (finished) {
					arg++;
					goto done;
				}
				if (isspace(c)) {
					arg++;					
					buffer[pos] = 0;			
					/* are we out of tokens? */
					if (arg == arg_count)
						goto done;
					state = IN_SPACE;
				}
				pos++;
				break;
			case IN_SPACE:
				if (finished)
					goto done;
				if (!isspace(c)) {
					state = IN_TOKEN;
					args[arg].str = &buffer[pos];
				}
				pos++;
				break;
		}
	}

done:
	return arg;
}

static void convert_args(int argc, cmd_args *argv)
{
	int i;

	for (i = 0; i < argc; i++) {
		argv[i].u = atoui(argv[i].str);
		argv[i].i = atoi(argv[i].str);
	}
}

static void console_loop(void)
{
	cmd_args args[16];
	char buffer[256];

	printf("entering main console loop\n");

	for (;;) {
		dputs("] ");

		int len = read_line(buffer, sizeof(buffer));
		if (len == 0)
			continue;

//		printf("line = '%s'\n", buffer);

		/* tokenize the line */
		int argc = tokenize_command(buffer, args, 16);
		if (argc < 0) {
			printf("syntax error\n");
			continue;
		} else if (argc == 0) {
			continue;
		}

//		printf("after tokenize: argc %d\n", argc);
//		for (int i = 0; i < argc; i++)
//			printf("%d: '%s'\n", i, args[i].str);

		/* convert the args */
		convert_args(argc, args);

		/* try to match the command */
		const cmd *command = match_command(args[0].str);
		if (!command) {
			printf("command not found\n");
			continue;
		}

		int result = command->cmd_callback(argc, args);

		// XXX do something with the result
	}
}


void console_start(void)
{

	console_loop();
}

int console_run_command(const char *string)
{
	const cmd *command;

	ASSERT(string != NULL);

	command = match_command(string);
	if (!command)
		return -1;

	int result = command->cmd_callback(0, NULL);

	return result;
}

void console_register_commands(cmd_block *block)
{
	ASSERT(block);
	ASSERT(block->next == NULL);

	block->next = command_list;
	command_list = block;
}

static int cmd_help(int argc, const cmd_args *argv)
{

	printf("command list:\n");
	
	cmd_block *block;
	size_t i;

	for (block = command_list; block != NULL; block = block->next) {
		const cmd *curr_cmd = block->list;
		for (i = 0; i < block->count; i++) {
			printf("\t%-16s: %s\n", curr_cmd[i].cmd_str, curr_cmd[i].help_str ? curr_cmd[i].help_str : "");
		}
	}

	return 0;
}

static int cmd_test(int argc, const cmd_args *argv)
{
	int i;

	printf("argc %d, argv %p\n", argc, argv);
	for (i = 0; i < argc; i++)
		printf("\t%d: str '%s', i %d, u %#x\n", i, argv[i].str, argv[i].i, argv[i].u);

	return 0;
}

