/* vi: set sw=4 ts=4: */
/*
 * Termios command line History and Editting, originally 
 * intended for NetBSD sh (ash)
 * Copyright (c) 1999
 *      Main code:            Adam Rogoyski <rogoyski@cs.utexas.edu> 
 *      Etc:                  Dave Cinege <dcinege@psychosis.com>
 *  Majorly adjusted/re-written for busybox:
 *                            Erik Andersen <andersee@debian.org>
 *
 * You may use this code as you wish, so long as the original author(s)
 * are attributed in any redistributions of the source code.
 * This code is 'as is' with no warranty.
 * This code may safely be consumed by a BSD or GPL license.
 *
 * v 0.5  19990328      Initial release 
 *
 * Future plans: Simple file and path name completion. (like BASH)
 *
 */

/*
   Usage and Known bugs:
   Terminal key codes are not extensive, and more will probably
   need to be added. This version was created on Debian GNU/Linux 2.x.
   Delete, Backspace, Home, End, and the arrow keys were tested
   to work in an Xterm and console. Ctrl-A also works as Home.
   Ctrl-E also works as End. The binary size increase is <3K.

   Editting will not display correctly for lines greater then the 
   terminal width. (more then one line.) However, history will.
 */

#include "internal.h"
#ifdef BB_FEATURE_SH_COMMAND_EDITING

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <termio.h>
#include <ctype.h>
#include <signal.h>


#define  MAX_HISTORY   15		/* Maximum length of the linked list for the command line history */

#define ESC	27
#define DEL	127
#define member(c, s) ((c) ? ((char *)strchr ((s), (c)) != (char *)NULL) : 0)
#define whitespace(c) (((c) == ' ') || ((c) == '\t'))

static struct history *his_front = NULL;	/* First element in command line list */
static struct history *his_end = NULL;	/* Last element in command line list */
static struct termio old_term, new_term;	/* Current termio and the previous termio before starting ash */

static int cmdedit_termw = 80;  /* actual terminal width */
static int cmdedit_scroll = 27; /* width of EOL scrolling region */
static int history_counter = 0;	/* Number of commands in history list */
static int reset_term = 0;		/* Set to true if the terminal needs to be reset upon exit */

struct history {
	char *s;
	struct history *p;
	struct history *n;
};

#define xwrite write

void
cmdedit_setwidth(int w)
{
	if (w > 20) {
		cmdedit_termw = w;
		cmdedit_scroll = w / 3;
	} else {
		errorMsg("\n*** Error: minimum screen width is 21\n");
	}
}


void cmdedit_reset_term(void)
{
	if (reset_term)
		/* sparc and other have broken termios support: use old termio handling. */
		ioctl(fileno(stdin), TCSETA, (void *) &old_term);
}

void clean_up_and_die(int sig)
{
	cmdedit_reset_term();
	fprintf(stdout, "\n");
	exit(TRUE);
}

/* Go to HOME position */
void input_home(int outputFd, int *cursor)
{
	while (*cursor > 0) {
		xwrite(outputFd, "\b", 1);
		--*cursor;
	}
}

/* Go to END position */
void input_end(int outputFd, int *cursor, int len)
{
	while (*cursor < len) {
		xwrite(outputFd, "\033[C", 3);
		++*cursor;
	}
}

/* Delete the char in back of the cursor */
void input_backspace(char* command, int outputFd, int *cursor, int *len)
{
	int j = 0;

	if (*cursor > 0) {
		xwrite(outputFd, "\b \b", 3);
		--*cursor;
		memmove(command + *cursor, command + *cursor + 1,
				BUFSIZ - *cursor + 1);

		for (j = *cursor; j < (BUFSIZ - 1); j++) {
			if (!*(command + j))
				break;
			else
				xwrite(outputFd, (command + j), 1);
		}

		xwrite(outputFd, " \b", 2);

		while (j-- > *cursor)
			xwrite(outputFd, "\b", 1);

		--*len;
	}
}

/* Delete the char in front of the cursor */
void input_delete(char* command, int outputFd, int cursor, int *len)
{
	int j = 0;

	if (cursor == *len)
		return;
	
	memmove(command + cursor, command + cursor + 1,
			BUFSIZ - cursor - 1);
	for (j = cursor; j < (BUFSIZ - 1); j++) {
		if (!*(command + j))
			break;
		else
			xwrite(outputFd, (command + j), 1);
	}

	xwrite(outputFd, " \b", 2);

	while (j-- > cursor)
		xwrite(outputFd, "\b", 1);
	--*len;
}

/* Move forward one charactor */
void input_forward(int outputFd, int *cursor, int len)
{
	if (*cursor < len) {
		xwrite(outputFd, "\033[C", 3);
		++*cursor;
	}
}

/* Move back one charactor */
void input_backward(int outputFd, int *cursor)
{
	if (*cursor > 0) {
		xwrite(outputFd, "\033[D", 3);
		--*cursor;
	}
}



#ifdef BB_FEATURE_SH_TAB_COMPLETION
char** username_tab_completion(char* command, int *num_matches)
{
	char **matches = (char **) NULL;
	*num_matches=0;
	fprintf(stderr, "\nin username_tab_completion\n");
	return (matches);
}

#include <dirent.h>
char** exe_n_cwd_tab_completion(char* command, int *num_matches)
{
	char *dirName;
	char **matches = (char **) NULL;
	DIR *dir;
	struct dirent *next;
			
	matches = malloc( sizeof(char*)*50);

	/* Stick a wildcard onto the command, for later use */
	strcat( command, "*");

	/* Now wall the current directory */
	dirName = get_current_dir_name();
	dir = opendir(dirName);
	if (!dir) {
		/* Don't print an error, just shut up and return */
		*num_matches=0;
		return (matches);
	}
	while ((next = readdir(dir)) != NULL) {

		/* Some quick sanity checks */
		if ((strcmp(next->d_name, "..") == 0)
			|| (strcmp(next->d_name, ".") == 0)) {
			continue;
		} 
		/* See if this matches */
		if (check_wildcard_match(next->d_name, command) == TRUE) {
			/* Cool, found a match.  Add it to the list */
			matches[*num_matches] = malloc(strlen(next->d_name)+1);
			strcpy( matches[*num_matches], next->d_name);
			++*num_matches;
			//matches = realloc( matches, sizeof(char*)*(*num_matches));
		}
	}

	return (matches);
}

void input_tab(char* command, int outputFd, int *cursor, int *len)
{
	/* Do TAB completion */
	static int num_matches=0;
	static char **matches = (char **) NULL;
	int pos = cursor;


	if (lastWasTab == FALSE) {
		char *tmp, *tmp1, *matchBuf;

		/* For now, we will not bother with trying to distinguish
		 * whether the cursor is in/at a command extression -- we
		 * will always try all possable matches.  If you don't like
		 * that then feel free to fix it.
		 */

		/* Make a local copy of the string -- up 
		 * to the position of the cursor */
		matchBuf = (char *) calloc(BUFSIZ, sizeof(char));
		strncpy(matchBuf, command, cursor);
		tmp=matchBuf;

		/* skip past any command seperator tokens */
		while (*tmp && (tmp1=strpbrk(tmp, ";|&{(`")) != NULL) {
			tmp=++tmp1;
			/* skip any leading white space */
			while (*tmp && isspace(*tmp)) 
				++tmp;
		}

		/* skip any leading white space */
		while (*tmp && isspace(*tmp)) 
			++tmp;

		/* Free up any memory already allocated */
		if (matches) {
			free(matches);
			matches = (char **) NULL;
		}

		/* If the word starts with `~' and there is no slash in the word, 
		 * then try completing this word as a username. */

		/* FIXME -- this check is broken! */
		if (*tmp == '~' && !strchr(tmp, '/'))
			matches = username_tab_completion(tmp, &num_matches);

		/* Try to match any executable in our path and everything 
		 * in the current working directory that matches.  */
		if (!matches)
			matches = exe_n_cwd_tab_completion(tmp, &num_matches);

		/* Don't leak memory */
		free( matchBuf);

		/* Did we find exactly one match? */
		if (matches && num_matches==1) {
			/* write out the matched command */
			strncpy(command+pos, matches[0]+pos, strlen(matches[0])-pos);
			len=strlen(command);
			cursor=len;
			xwrite(outputFd, matches[0]+pos, strlen(matches[0])-pos);
			break;
		}
	} else {
		/* Ok -- the last char was a TAB.  Since they
		 * just hit TAB again, print a list of all the
		 * available choices... */
		if ( matches && num_matches>0 ) {
			int i, col;

			/* Go to the next line */
			xwrite(outputFd, "\n", 1);
			/* Print the list of matches */
			for (i=0,col=0; i<num_matches; i++) {
				char foo[17];
				sprintf(foo, "%-14s  ", matches[i]);
				col += xwrite(outputFd, foo, strlen(foo));
				if (col > 60 && matches[i+1] != NULL) {
					xwrite(outputFd, "\n", 1);
					col = 0;
				}
			}
			/* Go to the next line */
			xwrite(outputFd, "\n", 1);
			/* Rewrite the prompt */
			xwrite(outputFd, prompt, strlen(prompt));
			/* Rewrite the command */
			xwrite(outputFd, command, len);
			/* Put the cursor back to where it used to be */
			for (cursor=len; cursor > pos; cursor--)
				xwrite(outputFd, "\b", 1);
		}
	}
}
#endif

void get_previous_history(struct history **hp, char* command)
{
	free((*hp)->s);
	(*hp)->s = strdup(command);
	*hp = (*hp)->p;
}

void get_next_history(struct history **hp, char* command)
{
	free((*hp)->s);
	(*hp)->s = strdup(command);
	*hp = (*hp)->n;
}

/*
 * This function is used to grab a character buffer
 * from the input file descriptor and allows you to
 * a string with full command editing (sortof like
 * a mini readline).
 *
 * The following standard commands are not implemented:
 * ESC-b -- Move back one word
 * ESC-f -- Move forward one word
 * ESC-d -- Delete back one word
 * ESC-h -- Delete forward one word
 * CTL-t -- Transpose two characters
 *
 * Furthermore, the "vi" command editing keys are not implemented.
 *
 * TODO: implement TAB command completion. :)
 */
extern void cmdedit_read_input(char* prompt, char command[BUFSIZ])
{

	int inputFd=fileno(stdin);
	int outputFd=fileno(stdout);
	int nr = 0;
	int len = 0;
	int j = 0;
	int cursor = 0;
	int break_out = 0;
	int ret = 0;
	int lastWasTab = FALSE;
	char c = 0;
	struct history *hp = his_end;

	memset(command, 0, sizeof(command));
	if (!reset_term) {
		/* sparc and other have broken termios support: use old termio handling. */
		ioctl(inputFd, TCGETA, (void *) &old_term);
		memcpy(&new_term, &old_term, sizeof(struct termio));

		new_term.c_cc[VMIN] = 1;
		new_term.c_cc[VTIME] = 0;
		new_term.c_lflag &= ~ICANON;	/* unbuffered input */
		new_term.c_lflag &= ~ECHO;
		reset_term = 1;
		ioctl(inputFd, TCSETA, (void *) &new_term);
	} else {
		ioctl(inputFd, TCSETA, (void *) &new_term);
	}

	memset(command, 0, BUFSIZ);

	while (1) {

		if ((ret = read(inputFd, &c, 1)) < 1)
			return;

		switch (c) {
		case '\n':
		case '\r':
			/* Enter */
			*(command + len++ + 1) = c;
			xwrite(outputFd, &c, 1);
			break_out = 1;
			break;
		case 1:
			/* Control-a -- Beginning of line */
			input_home(outputFd, &cursor);
		case 2:
			/* Control-b -- Move back one character */
			input_backward(outputFd, &cursor);
			break;
		case 4:
			/* Control-d -- Delete one character, or exit 
			 * if the len=0 and no chars to delete */
			if (len == 0) {
				xwrite(outputFd, "exit", 4);
				clean_up_and_die(0);
			} else {
				input_delete(command, outputFd, cursor, &len);
			}
			break;
		case 5:
			/* Control-e -- End of line */
			input_end(outputFd, &cursor, len);
			break;
		case 6:
			/* Control-f -- Move forward one character */
			input_forward(outputFd, &cursor, len);
			break;
		case '\b':
		case DEL:
			/* control-h and DEL */
			input_backspace(command, outputFd, &cursor, &len);
			break;
		case '\t':
#ifdef BB_FEATURE_SH_TAB_COMPLETION
			input_tab(command, outputFd, &cursor, &len);
#endif
			break;
		case 14:
			/* Control-n -- Get next command in history */
			if (hp && hp->n && hp->n->s) {
				get_next_history(&hp, command);
				goto rewrite_line;
			} else {
				xwrite(outputFd, "\007", 1);
			}
			break;
		case 16:
			/* Control-p -- Get previous command from history */
			if (hp && hp->p) {
				get_previous_history(&hp, command);
				goto rewrite_line;
			} else {
				xwrite(outputFd, "\007", 1);
			}
			break;
		case ESC:{
				/* escape sequence follows */
				if ((ret = read(inputFd, &c, 1)) < 1)
					return;

				if (c == '[') {	/* 91 */
					if ((ret = read(inputFd, &c, 1)) < 1)
						return;

					switch (c) {
					case 'A':
						/* Up Arrow -- Get previous command from history */
						if (hp && hp->p) {
							get_previous_history(&hp, command);
							goto rewrite_line;
						} else {
							xwrite(outputFd, "\007", 1);
						}
						break;
					case 'B':
						/* Down Arrow -- Get next command in history */
						if (hp && hp->n && hp->n->s) {
							get_next_history(&hp, command);
							goto rewrite_line;
						} else {
							xwrite(outputFd, "\007", 1);
						}
						break;

						/* Rewrite the line with the selected history item */
					  rewrite_line:
						/* erase old command from command line */
						len = strlen(command)-strlen(hp->s);
						while (len>0)
							input_backspace(command, outputFd, &cursor, &len);
						input_home(outputFd, &cursor);
						
						/* write new command */
						strcpy(command, hp->s);
						len = strlen(hp->s);
						xwrite(outputFd, command, len);
						cursor = len;
						break;
					case 'C':
						/* Right Arrow -- Move forward one character */
						input_forward(outputFd, &cursor, len);
						break;
					case 'D':
						/* Left Arrow -- Move back one character */
						input_backward(outputFd, &cursor);
						break;
					case '3':
						/* Delete */
						input_delete(command, outputFd, cursor, &len);
						break;
					case '1':
						/* Home (Ctrl-A) */
						input_home(outputFd, &cursor);
						break;
					case '4':
						/* End (Ctrl-E) */
						input_end(outputFd, &cursor, len);
						break;
					default:
						xwrite(outputFd, "\007", 1);
					}
					if (c == '1' || c == '3' || c == '4')
						if ((ret = read(inputFd, &c, 1)) < 1)
							return;	/* read 126 (~) */
				}
				if (c == 'O') {
					/* 79 */
					if ((ret = read(inputFd, &c, 1)) < 1)
						return;
					switch (c) {
					case 'H':
						/* Home (xterm) */
						input_home(outputFd, &cursor);
						break;
					case 'F':
						/* End (xterm) */
						input_end(outputFd, &cursor, len);
						break;
					default:
						xwrite(outputFd, "\007", 1);
					}
				}
				c = 0;
				break;
			}

		default:				/* If it's regular input, do the normal thing */

			if (!isprint(c)) {	/* Skip non-printable characters */
				break;
			}

			if (len >= (BUFSIZ - 2))	/* Need to leave space for enter */
				break;

			len++;

			if (cursor == (len - 1)) {	/* Append if at the end of the line */
				*(command + cursor) = c;
			} else {			/* Insert otherwise */
				memmove(command + cursor + 1, command + cursor,
						len - cursor - 1);

				*(command + cursor) = c;

				for (j = cursor; j < len; j++)
					xwrite(outputFd, command + j, 1);
				for (; j > cursor; j--)
					xwrite(outputFd, "\033[D", 3);
			}

			cursor++;
			xwrite(outputFd, &c, 1);
			break;
		}
		if (c == '\t')
			lastWasTab = TRUE;
		else
			lastWasTab = FALSE;

		if (break_out)			/* Enter is the command terminator, no more input. */
			break;
	}

	nr = len + 1;
	/* sparc and other have broken termios support: use old termio handling. */
	ioctl(inputFd, TCSETA, (void *) &old_term);
	reset_term = 0;


	/* Handle command history log */
	if (*(command)) {

		struct history *h = his_end;

		if (!h) {
			/* No previous history */
			h = his_front = malloc(sizeof(struct history));
			h->n = malloc(sizeof(struct history));

			h->p = NULL;
			h->s = strdup(command);
			h->n->p = h;
			h->n->n = NULL;
			h->n->s = NULL;
			his_end = h->n;
			history_counter++;
		} else {
			/* Add a new history command */
			h->n = malloc(sizeof(struct history));

			h->n->p = h;
			h->n->n = NULL;
			h->n->s = NULL;
			h->s = strdup(command);
			his_end = h->n;

			/* After max history, remove the oldest command */
			if (history_counter >= MAX_HISTORY) {

				struct history *p = his_front->n;

				p->p = NULL;
				free(his_front->s);
				free(his_front);
				his_front = p;
			} else {
				history_counter++;
			}
		}
	}

	return;
}

extern void cmdedit_init(void)
{
	atexit(cmdedit_reset_term);
	signal(SIGINT, clean_up_and_die);
	signal(SIGQUIT, clean_up_and_die);
	signal(SIGTERM, clean_up_and_die);
}
#endif							/* BB_FEATURE_SH_COMMAND_EDITING */
