/* 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 "busybox.h"
#ifdef BB_FEATURE_SH_COMMAND_EDITING

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <ctype.h>
#include <signal.h>


static const int MAX_HISTORY = 15;		/* Maximum length of the linked list for the command line history */

enum {
	ESC = 27,
	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 */

/* ED: sparc termios is broken: revert back to old termio handling. */
#ifdef BB_FEATURE_USE_TERMIOS

#if #cpu(sparc)
#      include <termio.h>
#      define termios termio
#      define setTermSettings(fd,argp) ioctl(fd,TCSETAF,argp)
#      define getTermSettings(fd,argp) ioctl(fd,TCGETA,argp)
#else
#      include <termios.h>
#      define setTermSettings(fd,argp) tcsetattr(fd,TCSANOW,argp)
#      define getTermSettings(fd,argp) tcgetattr(fd, argp);
#endif

/* Current termio and the previous termio before starting sh */
static struct termios initial_settings, new_settings;


#ifndef	_POSIX_VDISABLE
#define	_POSIX_VDISABLE	'\0'
#endif

#endif



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 */
static int exithandler_set = 0;	/* Set to true when atexit() has been called */
	

/* Link into lash to reset context to 0
 * on ^C and such */
extern unsigned int shell_context;


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

#define xwrite write

/*
 * TODO: Someday we want to implement 'horizontal scrolling' of the
 * command-line when the user has typed more than the current width. This
 * would allow the user to see a 'window' of what he has typed.
 */
static void cmdedit_setwidth(int w)
{
	if (w > 20) {
		cmdedit_termw = w;
		cmdedit_scroll = w / 3;
	} else {
		error_msg("\n*** Error: minimum screen width is 21\n");
	}
}

static void win_changed(int junk)
{
	struct winsize win = { 0, 0, 0, 0 };
	ioctl(0, TIOCGWINSZ, &win);
	if (win.ws_col > 0) {
		cmdedit_setwidth( win.ws_col - 1);
	}
}


static void cmdedit_reset_term(void)
{
	if (reset_term)
		/* sparc and other have broken termios support: use old termio handling. */
		setTermSettings(fileno(stdin), (void*) &initial_settings);
#ifdef BB_FEATURE_CLEAN_UP
	if (his_front) {
		struct history *n;
		//while(his_front!=his_end) {
		while(his_front!=his_end) {
			n = his_front->n;
			free(his_front->s);
			free(his_front);
			his_front=n;
		}
	}
#endif
}

static void clean_up_and_die(int sig)
{
	cmdedit_reset_term();
	printf("\n");
	if (sig!=SIGINT)
		exit(EXIT_SUCCESS);
}

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

/* Go to END position */
static 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 */
static void input_backspace(char* command, int outputFd, int *cursor, int *len)
{
	int j = 0;

/* Debug crap */
//fprintf(stderr, "\nerik: len=%d, cursor=%d, strlen(command)='%d'\n", *len, *cursor, strlen(command));
//xwrite(outputFd, command, *len);
//*cursor = *len;


	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 */
static 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 */
static void input_forward(int outputFd, int *cursor, int len)
{
	if (*cursor < len) {
		xwrite(outputFd, "\033[C", 3);
		++*cursor;
	}
}

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



#ifdef BB_FEATURE_SH_TAB_COMPLETION
static 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>
static char** exe_n_cwd_tab_completion(char* command, int *num_matches)
{
	char *dirName;
	char **matches;
	DIR *dir;
	struct dirent *next;
			
	matches = xmalloc( 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] = xmalloc(strlen(next->d_name)+1);
			strcpy( matches[*num_matches], next->d_name);
			++*num_matches;
			//matches = realloc( matches, sizeof(char*)*(*num_matches));
		}
	}

	return (matches);
}

static void input_tab(char* command, char* prompt, int outputFd, int *cursor, int *len, int lastWasTab)
{
	/* 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 possible 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 *) xcalloc(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);
			return;
		}
	} 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

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

static void get_next_history(struct history **hp, char* command)
{
	if ((*hp)->s)
		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;

	if (!reset_term) {
		
		getTermSettings(inputFd, (void*) &initial_settings);
		memcpy(&new_settings, &initial_settings, sizeof(struct termios));
		new_settings.c_cc[VMIN] = 1;
		new_settings.c_cc[VTIME] = 0;
		new_settings.c_cc[VINTR] = _POSIX_VDISABLE; /* Turn off CTRL-C, so we can trap it */
		new_settings.c_lflag &= ~ICANON;	/* unbuffered input */
		new_settings.c_lflag &= ~(ECHO|ECHOCTL|ECHONL); /* Turn off echoing */
		reset_term = 1;
	}
	setTermSettings(inputFd, (void*) &new_settings);

	memset(command, 0, BUFSIZ);

	/* Print out the command prompt */
	xwrite(outputFd, prompt, strlen(prompt));

	while (1) {

		if ((ret = read(inputFd, &c, 1)) < 1)
			return;
		//fprintf(stderr, "got a '%c' (%d)\n", c, c);

		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 3:
			/* Control-c -- stop gathering input */
			
			/* Link into lash to reset context to 0 on ^C and such */
			shell_context = 0;

			/* Go to the next line */
			xwrite(outputFd, "\n", 1);

#if 0
			/* Rewrite the prompt */
			xwrite(outputFd, prompt, strlen(prompt));

			/* Reset the command string */
			memset(command, 0, BUFSIZ);
			len = cursor = 0;
#endif
			return;

		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, prompt, outputFd, &cursor,
&len, lastWasTab);
#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>cursor)
							input_delete(command, outputFd, cursor, &len);
						while (cursor>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;
	setTermSettings(inputFd, (void *) &initial_settings);
	reset_term = 0;


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

		struct history *h = his_end;

		if (!h) {
			/* No previous history -- this memory is never freed */
			h = his_front = xmalloc(sizeof(struct history));
			h->n = xmalloc(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 -- this memory is never freed */
			h->n = xmalloc(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)
{
	win_changed(0);
	signal(SIGWINCH, win_changed);

	if(exithandler_set == 0) {
		atexit(cmdedit_reset_term);	/* be sure to do this only once */
		exithandler_set = 1;
	}
	signal(SIGKILL, clean_up_and_die);
	signal(SIGINT, clean_up_and_die);
	signal(SIGQUIT, clean_up_and_die);
	signal(SIGTERM, clean_up_and_die);
}

/*
** Undo the effects of cmdedit_init() as good as we can:
** I am not aware of a way to revoke an atexit() handler,
** but, fortunately, our particular handler can be made
** a no-op by setting reset_term = 0.
*/
extern void cmdedit_terminate(void)
{
	cmdedit_reset_term();
	reset_term = 0;
	signal(SIGKILL, SIG_DFL);
	signal(SIGINT, SIG_DFL);
	signal(SIGQUIT, SIG_DFL);
	signal(SIGTERM, SIG_DFL);
	signal(SIGWINCH, SIG_DFL);
}



#endif							/* BB_FEATURE_SH_COMMAND_EDITING */
