/*
 * 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 4096
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);
}
