/*
 * Command line editing and history
 * Copyright (c) 2010-2011, Jouni Malinen <j@w1.fi>
 *
 * This software may be distributed under the terms of the BSD license.
 * See README for more details.
 */

#include "includes.h"
#include <termios.h>

#include "common.h"
#include "eloop.h"
#include "list.h"
#include "edit.h"

#define CMD_BUF_LEN 256
static char cmdbuf[CMD_BUF_LEN];
static int cmdbuf_pos = 0;
static int cmdbuf_len = 0;
static char currbuf[CMD_BUF_LEN];
static int currbuf_valid = 0;
static const char *ps2 = NULL;

#define HISTORY_MAX 100

struct edit_history {
	struct dl_list list;
	char str[1];
};

static struct dl_list history_list;
static struct edit_history *history_curr;

static void *edit_cb_ctx;
static void (*edit_cmd_cb)(void *ctx, char *cmd);
static void (*edit_eof_cb)(void *ctx);
static char ** (*edit_completion_cb)(void *ctx, const char *cmd, int pos) =
	NULL;

static struct termios prevt, newt;


#define CLEAR_END_LINE "\e[K"


void edit_clear_line(void)
{
	int i;
	putchar('\r');
	for (i = 0; i < cmdbuf_len + 2 + (ps2 ? (int) os_strlen(ps2) : 0); i++)
		putchar(' ');
}


static void move_start(void)
{
	cmdbuf_pos = 0;
	edit_redraw();
}


static void move_end(void)
{
	cmdbuf_pos = cmdbuf_len;
	edit_redraw();
}


static void move_left(void)
{
	if (cmdbuf_pos > 0) {
		cmdbuf_pos--;
		edit_redraw();
	}
}


static void move_right(void)
{
	if (cmdbuf_pos < cmdbuf_len) {
		cmdbuf_pos++;
		edit_redraw();
	}
}


static void move_word_left(void)
{
	while (cmdbuf_pos > 0 && cmdbuf[cmdbuf_pos - 1] == ' ')
		cmdbuf_pos--;
	while (cmdbuf_pos > 0 && cmdbuf[cmdbuf_pos - 1] != ' ')
		cmdbuf_pos--;
	edit_redraw();
}


static void move_word_right(void)
{
	while (cmdbuf_pos < cmdbuf_len && cmdbuf[cmdbuf_pos] == ' ')
		cmdbuf_pos++;
	while (cmdbuf_pos < cmdbuf_len && cmdbuf[cmdbuf_pos] != ' ')
		cmdbuf_pos++;
	edit_redraw();
}


static void delete_left(void)
{
	if (cmdbuf_pos == 0)
		return;

	edit_clear_line();
	os_memmove(cmdbuf + cmdbuf_pos - 1, cmdbuf + cmdbuf_pos,
		   cmdbuf_len - cmdbuf_pos);
	cmdbuf_pos--;
	cmdbuf_len--;
	edit_redraw();
}


static void delete_current(void)
{
	if (cmdbuf_pos == cmdbuf_len)
		return;

	edit_clear_line();
	os_memmove(cmdbuf + cmdbuf_pos, cmdbuf + cmdbuf_pos + 1,
		   cmdbuf_len - cmdbuf_pos);
	cmdbuf_len--;
	edit_redraw();
}


static void delete_word(void)
{
	int pos;

	edit_clear_line();
	pos = cmdbuf_pos;
	while (pos > 0 && cmdbuf[pos - 1] == ' ')
		pos--;
	while (pos > 0 && cmdbuf[pos - 1] != ' ')
		pos--;
	os_memmove(cmdbuf + pos, cmdbuf + cmdbuf_pos, cmdbuf_len - cmdbuf_pos);
	cmdbuf_len -= cmdbuf_pos - pos;
	cmdbuf_pos = pos;
	edit_redraw();
}


static void clear_left(void)
{
	if (cmdbuf_pos == 0)
		return;

	edit_clear_line();
	os_memmove(cmdbuf, cmdbuf + cmdbuf_pos, cmdbuf_len - cmdbuf_pos);
	cmdbuf_len -= cmdbuf_pos;
	cmdbuf_pos = 0;
	edit_redraw();
}


static void clear_right(void)
{
	if (cmdbuf_pos == cmdbuf_len)
		return;

	edit_clear_line();
	cmdbuf_len = cmdbuf_pos;
	edit_redraw();
}


static void history_add(const char *str)
{
	struct edit_history *h, *match = NULL, *last = NULL;
	size_t len, count = 0;

	if (str[0] == '\0')
		return;

	dl_list_for_each(h, &history_list, struct edit_history, list) {
		if (os_strcmp(str, h->str) == 0) {
			match = h;
			break;
		}
		last = h;
		count++;
	}

	if (match) {
		dl_list_del(&h->list);
		dl_list_add(&history_list, &h->list);
		history_curr = h;
		return;
	}

	if (count >= HISTORY_MAX && last) {
		dl_list_del(&last->list);
		os_free(last);
	}

	len = os_strlen(str);
	h = os_zalloc(sizeof(*h) + len);
	if (h == NULL)
		return;
	dl_list_add(&history_list, &h->list);
	os_strlcpy(h->str, str, len + 1);
	history_curr = h;
}


static void history_use(void)
{
	edit_clear_line();
	cmdbuf_len = cmdbuf_pos = os_strlen(history_curr->str);
	os_memcpy(cmdbuf, history_curr->str, cmdbuf_len);
	edit_redraw();
}


static void history_prev(void)
{
	if (history_curr == NULL)
		return;

	if (history_curr ==
	    dl_list_first(&history_list, struct edit_history, list)) {
		if (!currbuf_valid) {
			cmdbuf[cmdbuf_len] = '\0';
			os_memcpy(currbuf, cmdbuf, cmdbuf_len + 1);
			currbuf_valid = 1;
			history_use();
			return;
		}
	}

	if (history_curr ==
	    dl_list_last(&history_list, struct edit_history, list))
		return;

	history_curr = dl_list_entry(history_curr->list.next,
				     struct edit_history, list);
	history_use();
}


static void history_next(void)
{
	if (history_curr == NULL ||
	    history_curr ==
	    dl_list_first(&history_list, struct edit_history, list)) {
		if (currbuf_valid) {
			currbuf_valid = 0;
			edit_clear_line();
			cmdbuf_len = cmdbuf_pos = os_strlen(currbuf);
			os_memcpy(cmdbuf, currbuf, cmdbuf_len);
			edit_redraw();
		}
		return;
	}

	history_curr = dl_list_entry(history_curr->list.prev,
				     struct edit_history, list);
	history_use();
}


static void history_read(const char *fname)
{
	FILE *f;
	char buf[CMD_BUF_LEN], *pos;

	f = fopen(fname, "r");
	if (f == NULL)
		return;

	while (fgets(buf, CMD_BUF_LEN, f)) {
		for (pos = buf; *pos; pos++) {
			if (*pos == '\r' || *pos == '\n') {
				*pos = '\0';
				break;
			}
		}
		history_add(buf);
	}

	fclose(f);
}


static void history_write(const char *fname,
			  int (*filter_cb)(void *ctx, const char *cmd))
{
	FILE *f;
	struct edit_history *h;

	f = fopen(fname, "w");
	if (f == NULL)
		return;

	dl_list_for_each_reverse(h, &history_list, struct edit_history, list) {
		if (filter_cb && filter_cb(edit_cb_ctx, h->str))
			continue;
		fprintf(f, "%s\n", h->str);
	}

	fclose(f);
}


static void history_debug_dump(void)
{
	struct edit_history *h;
	edit_clear_line();
	printf("\r");
	dl_list_for_each_reverse(h, &history_list, struct edit_history, list)
		printf("%s%s\n", h == history_curr ? "[C]" : "", h->str);
	if (currbuf_valid)
		printf("{%s}\n", currbuf);
	edit_redraw();
}


static void insert_char(int c)
{
	if (cmdbuf_len >= (int) sizeof(cmdbuf) - 1)
		return;
	if (cmdbuf_len == cmdbuf_pos) {
		cmdbuf[cmdbuf_pos++] = c;
		cmdbuf_len++;
		putchar(c);
		fflush(stdout);
	} else {
		os_memmove(cmdbuf + cmdbuf_pos + 1, cmdbuf + cmdbuf_pos,
			   cmdbuf_len - cmdbuf_pos);
		cmdbuf[cmdbuf_pos++] = c;
		cmdbuf_len++;
		edit_redraw();
	}
}


static void process_cmd(void)
{

	if (cmdbuf_len == 0) {
		printf("\n%s> ", ps2 ? ps2 : "");
		fflush(stdout);
		return;
	}
	printf("\n");
	cmdbuf[cmdbuf_len] = '\0';
	history_add(cmdbuf);
	cmdbuf_pos = 0;
	cmdbuf_len = 0;
	edit_cmd_cb(edit_cb_ctx, cmdbuf);
	printf("%s> ", ps2 ? ps2 : "");
	fflush(stdout);
}


static void free_completions(char **c)
{
	int i;
	if (c == NULL)
		return;
	for (i = 0; c[i]; i++)
		os_free(c[i]);
	os_free(c);
}


static int filter_strings(char **c, char *str, size_t len)
{
	int i, j;

	for (i = 0, j = 0; c[j]; j++) {
		if (os_strncasecmp(c[j], str, len) == 0) {
			if (i != j) {
				c[i] = c[j];
				c[j] = NULL;
			}
			i++;
		} else {
			os_free(c[j]);
			c[j] = NULL;
		}
	}
	c[i] = NULL;
	return i;
}


static int common_len(const char *a, const char *b)
{
	int len = 0;
	while (a[len] && a[len] == b[len])
		len++;
	return len;
}


static int max_common_length(char **c)
{
	int len, i;

	len = os_strlen(c[0]);
	for (i = 1; c[i]; i++) {
		int same = common_len(c[0], c[i]);
		if (same < len)
			len = same;
	}

	return len;
}


static int cmp_str(const void *a, const void *b)
{
	return os_strcmp(* (const char **) a, * (const char **) b);
}

static void complete(int list)
{
	char **c;
	int i, len, count;
	int start, end;
	int room, plen, add_space;

	if (edit_completion_cb == NULL)
		return;

	cmdbuf[cmdbuf_len] = '\0';
	c = edit_completion_cb(edit_cb_ctx, cmdbuf, cmdbuf_pos);
	if (c == NULL)
		return;

	end = cmdbuf_pos;
	start = end;
	while (start > 0 && cmdbuf[start - 1] != ' ')
		start--;
	plen = end - start;

	count = filter_strings(c, &cmdbuf[start], plen);
	if (count == 0) {
		free_completions(c);
		return;
	}

	len = max_common_length(c);
	if (len <= plen && count > 1) {
		if (list) {
			qsort(c, count, sizeof(char *), cmp_str);
			edit_clear_line();
			printf("\r");
			for (i = 0; c[i]; i++)
				printf("%s%s", i > 0 ? " " : "", c[i]);
			printf("\n");
			edit_redraw();
		}
		free_completions(c);
		return;
	}
	len -= plen;

	room = sizeof(cmdbuf) - 1 - cmdbuf_len;
	if (room < len)
		len = room;
	add_space = count == 1 && len < room;

	os_memmove(cmdbuf + cmdbuf_pos + len + add_space, cmdbuf + cmdbuf_pos,
		   cmdbuf_len - cmdbuf_pos);
	os_memcpy(&cmdbuf[cmdbuf_pos - plen], c[0], plen + len);
	if (add_space)
		cmdbuf[cmdbuf_pos + len] = ' ';

	cmdbuf_pos += len + add_space;
	cmdbuf_len += len + add_space;

	edit_redraw();

	free_completions(c);
}


enum edit_key_code {
	EDIT_KEY_NONE = 256,
	EDIT_KEY_TAB,
	EDIT_KEY_UP,
	EDIT_KEY_DOWN,
	EDIT_KEY_RIGHT,
	EDIT_KEY_LEFT,
	EDIT_KEY_ENTER,
	EDIT_KEY_BACKSPACE,
	EDIT_KEY_INSERT,
	EDIT_KEY_DELETE,
	EDIT_KEY_HOME,
	EDIT_KEY_END,
	EDIT_KEY_PAGE_UP,
	EDIT_KEY_PAGE_DOWN,
	EDIT_KEY_F1,
	EDIT_KEY_F2,
	EDIT_KEY_F3,
	EDIT_KEY_F4,
	EDIT_KEY_F5,
	EDIT_KEY_F6,
	EDIT_KEY_F7,
	EDIT_KEY_F8,
	EDIT_KEY_F9,
	EDIT_KEY_F10,
	EDIT_KEY_F11,
	EDIT_KEY_F12,
	EDIT_KEY_CTRL_UP,
	EDIT_KEY_CTRL_DOWN,
	EDIT_KEY_CTRL_RIGHT,
	EDIT_KEY_CTRL_LEFT,
	EDIT_KEY_CTRL_A,
	EDIT_KEY_CTRL_B,
	EDIT_KEY_CTRL_D,
	EDIT_KEY_CTRL_E,
	EDIT_KEY_CTRL_F,
	EDIT_KEY_CTRL_G,
	EDIT_KEY_CTRL_H,
	EDIT_KEY_CTRL_J,
	EDIT_KEY_CTRL_K,
	EDIT_KEY_CTRL_L,
	EDIT_KEY_CTRL_N,
	EDIT_KEY_CTRL_O,
	EDIT_KEY_CTRL_P,
	EDIT_KEY_CTRL_R,
	EDIT_KEY_CTRL_T,
	EDIT_KEY_CTRL_U,
	EDIT_KEY_CTRL_V,
	EDIT_KEY_CTRL_W,
	EDIT_KEY_ALT_UP,
	EDIT_KEY_ALT_DOWN,
	EDIT_KEY_ALT_RIGHT,
	EDIT_KEY_ALT_LEFT,
	EDIT_KEY_SHIFT_UP,
	EDIT_KEY_SHIFT_DOWN,
	EDIT_KEY_SHIFT_RIGHT,
	EDIT_KEY_SHIFT_LEFT,
	EDIT_KEY_ALT_SHIFT_UP,
	EDIT_KEY_ALT_SHIFT_DOWN,
	EDIT_KEY_ALT_SHIFT_RIGHT,
	EDIT_KEY_ALT_SHIFT_LEFT,
	EDIT_KEY_EOF
};

static void show_esc_buf(const char *esc_buf, char c, int i)
{
	edit_clear_line();
	printf("\rESC buffer '%s' c='%c' [%d]\n", esc_buf, c, i);
	edit_redraw();
}


static enum edit_key_code esc_seq_to_key1_no(char last)
{
	switch (last) {
	case 'A':
		return EDIT_KEY_UP;
	case 'B':
		return EDIT_KEY_DOWN;
	case 'C':
		return EDIT_KEY_RIGHT;
	case 'D':
		return EDIT_KEY_LEFT;
	default:
		return EDIT_KEY_NONE;
	}
}


static enum edit_key_code esc_seq_to_key1_shift(char last)
{
	switch (last) {
	case 'A':
		return EDIT_KEY_SHIFT_UP;
	case 'B':
		return EDIT_KEY_SHIFT_DOWN;
	case 'C':
		return EDIT_KEY_SHIFT_RIGHT;
	case 'D':
		return EDIT_KEY_SHIFT_LEFT;
	default:
		return EDIT_KEY_NONE;
	}
}


static enum edit_key_code esc_seq_to_key1_alt(char last)
{
	switch (last) {
	case 'A':
		return EDIT_KEY_ALT_UP;
	case 'B':
		return EDIT_KEY_ALT_DOWN;
	case 'C':
		return EDIT_KEY_ALT_RIGHT;
	case 'D':
		return EDIT_KEY_ALT_LEFT;
	default:
		return EDIT_KEY_NONE;
	}
}


static enum edit_key_code esc_seq_to_key1_alt_shift(char last)
{
	switch (last) {
	case 'A':
		return EDIT_KEY_ALT_SHIFT_UP;
	case 'B':
		return EDIT_KEY_ALT_SHIFT_DOWN;
	case 'C':
		return EDIT_KEY_ALT_SHIFT_RIGHT;
	case 'D':
		return EDIT_KEY_ALT_SHIFT_LEFT;
	default:
		return EDIT_KEY_NONE;
	}
}


static enum edit_key_code esc_seq_to_key1_ctrl(char last)
{
	switch (last) {
	case 'A':
		return EDIT_KEY_CTRL_UP;
	case 'B':
		return EDIT_KEY_CTRL_DOWN;
	case 'C':
		return EDIT_KEY_CTRL_RIGHT;
	case 'D':
		return EDIT_KEY_CTRL_LEFT;
	default:
		return EDIT_KEY_NONE;
	}
}


static enum edit_key_code esc_seq_to_key1(int param1, int param2, char last)
{
	/* ESC-[<param1>;<param2><last> */

	if (param1 < 0 && param2 < 0)
		return esc_seq_to_key1_no(last);

	if (param1 == 1 && param2 == 2)
		return esc_seq_to_key1_shift(last);

	if (param1 == 1 && param2 == 3)
		return esc_seq_to_key1_alt(last);

	if (param1 == 1 && param2 == 4)
		return esc_seq_to_key1_alt_shift(last);

	if (param1 == 1 && param2 == 5)
		return esc_seq_to_key1_ctrl(last);

	if (param2 < 0) {
		if (last != '~')
			return EDIT_KEY_NONE;
		switch (param1) {
		case 2:
			return EDIT_KEY_INSERT;
		case 3:
			return EDIT_KEY_DELETE;
		case 5:
			return EDIT_KEY_PAGE_UP;
		case 6:
			return EDIT_KEY_PAGE_DOWN;
		case 15:
			return EDIT_KEY_F5;
		case 17:
			return EDIT_KEY_F6;
		case 18:
			return EDIT_KEY_F7;
		case 19:
			return EDIT_KEY_F8;
		case 20:
			return EDIT_KEY_F9;
		case 21:
			return EDIT_KEY_F10;
		case 23:
			return EDIT_KEY_F11;
		case 24:
			return EDIT_KEY_F12;
		}
	}

	return EDIT_KEY_NONE;
}


static enum edit_key_code esc_seq_to_key2(int param1, int param2, char last)
{
	/* ESC-O<param1>;<param2><last> */

	if (param1 >= 0 || param2 >= 0)
		return EDIT_KEY_NONE;

	switch (last) {
	case 'F':
		return EDIT_KEY_END;
	case 'H':
		return EDIT_KEY_HOME;
	case 'P':
		return EDIT_KEY_F1;
	case 'Q':
		return EDIT_KEY_F2;
	case 'R':
		return EDIT_KEY_F3;
	case 'S':
		return EDIT_KEY_F4;
	default:
		return EDIT_KEY_NONE;
	}
}


static enum edit_key_code esc_seq_to_key(char *seq)
{
	char last, *pos;
	int param1 = -1, param2 = -1;
	enum edit_key_code ret = EDIT_KEY_NONE;

	last = '\0';
	for (pos = seq; *pos; pos++)
		last = *pos;

	if (seq[1] >= '0' && seq[1] <= '9') {
		param1 = atoi(&seq[1]);
		pos = os_strchr(seq, ';');
		if (pos)
			param2 = atoi(pos + 1);
	}

	if (seq[0] == '[')
		ret = esc_seq_to_key1(param1, param2, last);
	else if (seq[0] == 'O')
		ret = esc_seq_to_key2(param1, param2, last);

	if (ret != EDIT_KEY_NONE)
		return ret;

	edit_clear_line();
	printf("\rUnknown escape sequence '%s'\n", seq);
	edit_redraw();
	return EDIT_KEY_NONE;
}


static enum edit_key_code edit_read_key(int sock)
{
	int c;
	unsigned char buf[1];
	int res;
	static int esc = -1;
	static char esc_buf[7];

	res = read(sock, buf, 1);
	if (res < 0)
		perror("read");
	if (res <= 0)
		return EDIT_KEY_EOF;

	c = buf[0];

	if (esc >= 0) {
		if (c == 27 /* ESC */) {
			esc = 0;
			return EDIT_KEY_NONE;
		}

		if (esc == 6) {
			show_esc_buf(esc_buf, c, 0);
			esc = -1;
		} else {
			esc_buf[esc++] = c;
			esc_buf[esc] = '\0';
		}
	}

	if (esc == 1) {
		if (esc_buf[0] != '[' && esc_buf[0] != 'O') {
			show_esc_buf(esc_buf, c, 1);
			esc = -1;
			return EDIT_KEY_NONE;
		} else
			return EDIT_KEY_NONE; /* Escape sequence continues */
	}

	if (esc > 1) {
		if ((c >= '0' && c <= '9') || c == ';')
			return EDIT_KEY_NONE; /* Escape sequence continues */

		if (c == '~' || (c >= 'A' && c <= 'Z')) {
			esc = -1;
			return esc_seq_to_key(esc_buf);
		}

		show_esc_buf(esc_buf, c, 2);
		esc = -1;
		return EDIT_KEY_NONE;
	}

	switch (c) {
	case 1:
		return EDIT_KEY_CTRL_A;
	case 2:
		return EDIT_KEY_CTRL_B;
	case 4:
		return EDIT_KEY_CTRL_D;
	case 5:
		return EDIT_KEY_CTRL_E;
	case 6:
		return EDIT_KEY_CTRL_F;
	case 7:
		return EDIT_KEY_CTRL_G;
	case 8:
		return EDIT_KEY_CTRL_H;
	case 9:
		return EDIT_KEY_TAB;
	case 10:
		return EDIT_KEY_CTRL_J;
	case 13: /* CR */
		return EDIT_KEY_ENTER;
	case 11:
		return EDIT_KEY_CTRL_K;
	case 12:
		return EDIT_KEY_CTRL_L;
	case 14:
		return EDIT_KEY_CTRL_N;
	case 15:
		return EDIT_KEY_CTRL_O;
	case 16:
		return EDIT_KEY_CTRL_P;
	case 18:
		return EDIT_KEY_CTRL_R;
	case 20:
		return EDIT_KEY_CTRL_T;
	case 21:
		return EDIT_KEY_CTRL_U;
	case 22:
		return EDIT_KEY_CTRL_V;
	case 23:
		return EDIT_KEY_CTRL_W;
	case 27: /* ESC */
		esc = 0;
		return EDIT_KEY_NONE;
	case 127:
		return EDIT_KEY_BACKSPACE;
	default:
		return c;
	}
}


static char search_buf[21];
static int search_skip;

static char * search_find(void)
{
	struct edit_history *h;
	size_t len = os_strlen(search_buf);
	int skip = search_skip;

	if (len == 0)
		return NULL;

	dl_list_for_each(h, &history_list, struct edit_history, list) {
		if (os_strstr(h->str, search_buf)) {
			if (skip == 0)
				return h->str;
			skip--;
		}
	}

	search_skip = 0;
	return NULL;
}


static void search_redraw(void)
{
	char *match = search_find();
	printf("\rsearch '%s': %s" CLEAR_END_LINE,
	       search_buf, match ? match : "");
	printf("\rsearch '%s", search_buf);
	fflush(stdout);
}


static void search_start(void)
{
	edit_clear_line();
	search_buf[0] = '\0';
	search_skip = 0;
	search_redraw();
}


static void search_clear(void)
{
	search_redraw();
	printf("\r" CLEAR_END_LINE);
}


static void search_stop(void)
{
	char *match = search_find();
	search_buf[0] = '\0';
	search_clear();
	if (match) {
		os_strlcpy(cmdbuf, match, CMD_BUF_LEN);
		cmdbuf_len = os_strlen(cmdbuf);
		cmdbuf_pos = cmdbuf_len;
	}
	edit_redraw();
}


static void search_cancel(void)
{
	search_buf[0] = '\0';
	search_clear();
	edit_redraw();
}


static void search_backspace(void)
{
	size_t len;
	len = os_strlen(search_buf);
	if (len == 0)
		return;
	search_buf[len - 1] = '\0';
	search_skip = 0;
	search_redraw();
}


static void search_next(void)
{
	search_skip++;
	search_find();
	search_redraw();
}


static void search_char(char c)
{
	size_t len;
	len = os_strlen(search_buf);
	if (len == sizeof(search_buf) - 1)
		return;
	search_buf[len] = c;
	search_buf[len + 1] = '\0';
	search_skip = 0;
	search_redraw();
}


static enum edit_key_code search_key(enum edit_key_code c)
{
	switch (c) {
	case EDIT_KEY_ENTER:
	case EDIT_KEY_CTRL_J:
	case EDIT_KEY_LEFT:
	case EDIT_KEY_RIGHT:
	case EDIT_KEY_HOME:
	case EDIT_KEY_END:
	case EDIT_KEY_CTRL_A:
	case EDIT_KEY_CTRL_E:
		search_stop();
		return c;
	case EDIT_KEY_DOWN:
	case EDIT_KEY_UP:
		search_cancel();
		return EDIT_KEY_EOF;
	case EDIT_KEY_CTRL_H:
	case EDIT_KEY_BACKSPACE:
		search_backspace();
		break;
	case EDIT_KEY_CTRL_R:
		search_next();
		break;
	default:
		if (c >= 32 && c <= 255)
			search_char(c);
		break;
	}

	return EDIT_KEY_NONE;
}


static void edit_read_char(int sock, void *eloop_ctx, void *sock_ctx)
{
	static int last_tab = 0;
	static int search = 0;
	enum edit_key_code c;

	c = edit_read_key(sock);

	if (search) {
		c = search_key(c);
		if (c == EDIT_KEY_NONE)
			return;
		search = 0;
		if (c == EDIT_KEY_EOF)
			return;
	}

	if (c != EDIT_KEY_TAB && c != EDIT_KEY_NONE)
		last_tab = 0;

	switch (c) {
	case EDIT_KEY_NONE:
		break;
	case EDIT_KEY_EOF:
		edit_eof_cb(edit_cb_ctx);
		break;
	case EDIT_KEY_TAB:
		complete(last_tab);
		last_tab = 1;
		break;
	case EDIT_KEY_UP:
	case EDIT_KEY_CTRL_P:
		history_prev();
		break;
	case EDIT_KEY_DOWN:
	case EDIT_KEY_CTRL_N:
		history_next();
		break;
	case EDIT_KEY_RIGHT:
	case EDIT_KEY_CTRL_F:
		move_right();
		break;
	case EDIT_KEY_LEFT:
	case EDIT_KEY_CTRL_B:
		move_left();
		break;
	case EDIT_KEY_CTRL_RIGHT:
		move_word_right();
		break;
	case EDIT_KEY_CTRL_LEFT:
		move_word_left();
		break;
	case EDIT_KEY_DELETE:
		delete_current();
		break;
	case EDIT_KEY_END:
		move_end();
		break;
	case EDIT_KEY_HOME:
	case EDIT_KEY_CTRL_A:
		move_start();
		break;
	case EDIT_KEY_F2:
		history_debug_dump();
		break;
	case EDIT_KEY_CTRL_D:
		if (cmdbuf_len > 0) {
			delete_current();
			return;
		}
		printf("\n");
		edit_eof_cb(edit_cb_ctx);
		break;
	case EDIT_KEY_CTRL_E:
		move_end();
		break;
	case EDIT_KEY_CTRL_H:
	case EDIT_KEY_BACKSPACE:
		delete_left();
		break;
	case EDIT_KEY_ENTER:
	case EDIT_KEY_CTRL_J:
		process_cmd();
		break;
	case EDIT_KEY_CTRL_K:
		clear_right();
		break;
	case EDIT_KEY_CTRL_L:
		edit_clear_line();
		edit_redraw();
		break;
	case EDIT_KEY_CTRL_R:
		search = 1;
		search_start();
		break;
	case EDIT_KEY_CTRL_U:
		clear_left();
		break;
	case EDIT_KEY_CTRL_W:
		delete_word();
		break;
	default:
		if (c >= 32 && c <= 255)
			insert_char(c);
		break;
	}
}


int edit_init(void (*cmd_cb)(void *ctx, char *cmd),
	      void (*eof_cb)(void *ctx),
	      char ** (*completion_cb)(void *ctx, const char *cmd, int pos),
	      void *ctx, const char *history_file, const char *ps)
{
	currbuf[0] = '\0';
	dl_list_init(&history_list);
	history_curr = NULL;
	if (history_file)
		history_read(history_file);

	edit_cb_ctx = ctx;
	edit_cmd_cb = cmd_cb;
	edit_eof_cb = eof_cb;
	edit_completion_cb = completion_cb;

	tcgetattr(STDIN_FILENO, &prevt);
	newt = prevt;
	newt.c_lflag &= ~(ICANON | ECHO);
	tcsetattr(STDIN_FILENO, TCSANOW, &newt);

	eloop_register_read_sock(STDIN_FILENO, edit_read_char, NULL, NULL);

	ps2 = ps;
	printf("%s> ", ps2 ? ps2 : "");
	fflush(stdout);

	return 0;
}


void edit_deinit(const char *history_file,
		 int (*filter_cb)(void *ctx, const char *cmd))
{
	struct edit_history *h;
	if (history_file)
		history_write(history_file, filter_cb);
	while ((h = dl_list_first(&history_list, struct edit_history, list))) {
		dl_list_del(&h->list);
		os_free(h);
	}
	edit_clear_line();
	putchar('\r');
	fflush(stdout);
	eloop_unregister_read_sock(STDIN_FILENO);
	tcsetattr(STDIN_FILENO, TCSANOW, &prevt);
}


void edit_redraw(void)
{
	char tmp;
	cmdbuf[cmdbuf_len] = '\0';
	printf("\r%s> %s", ps2 ? ps2 : "", cmdbuf);
	if (cmdbuf_pos != cmdbuf_len) {
		tmp = cmdbuf[cmdbuf_pos];
		cmdbuf[cmdbuf_pos] = '\0';
		printf("\r%s> %s", ps2 ? ps2 : "", cmdbuf);
		cmdbuf[cmdbuf_pos] = tmp;
	}
	fflush(stdout);
}
