/*
 * 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)
{
	currbuf_valid = 0;
	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);
}
