/*
 * QEMU readline utility
 *
 * Copyright (c) 2003-2004 Fabrice Bellard
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
#include "vl.h"

#define TERM_CMD_BUF_SIZE 4095
#define TERM_MAX_CMDS 64
#define NB_COMPLETIONS_MAX 256

#define IS_NORM 0
#define IS_ESC  1
#define IS_CSI  2

#define printf do_not_use_printf

static char term_cmd_buf[TERM_CMD_BUF_SIZE + 1];
static int term_cmd_buf_index;
static int term_cmd_buf_size;

static char term_last_cmd_buf[TERM_CMD_BUF_SIZE + 1];
static int term_last_cmd_buf_index;
static int term_last_cmd_buf_size;

static int term_esc_state;
static int term_esc_param;

static char *term_history[TERM_MAX_CMDS];
static int term_hist_entry = -1;

static int nb_completions;
int completion_index;
static char *completions[NB_COMPLETIONS_MAX];

static ReadLineFunc *term_readline_func;
static int term_is_password;
static char term_prompt[256];
static void *term_readline_opaque;

static void term_show_prompt2(void)
{
    term_printf("%s", term_prompt);
    term_flush();
    term_last_cmd_buf_index = 0;
    term_last_cmd_buf_size = 0;
    term_esc_state = IS_NORM;
}

static void term_show_prompt(void)
{
    term_show_prompt2();
    term_cmd_buf_index = 0;
    term_cmd_buf_size = 0;
}

/* update the displayed command line */
static void term_update(void)
{
    int i, delta, len;

    if (term_cmd_buf_size != term_last_cmd_buf_size ||
        memcmp(term_cmd_buf, term_last_cmd_buf, term_cmd_buf_size) != 0) {
        for(i = 0; i < term_last_cmd_buf_index; i++) {
            term_printf("\033[D");
        }
        term_cmd_buf[term_cmd_buf_size] = '\0';
        if (term_is_password) {
            len = strlen(term_cmd_buf);
            for(i = 0; i < len; i++)
                term_printf("*");
        } else {
            term_printf("%s", term_cmd_buf);
        }
        term_printf("\033[K");
        memcpy(term_last_cmd_buf, term_cmd_buf, term_cmd_buf_size);
        term_last_cmd_buf_size = term_cmd_buf_size;
        term_last_cmd_buf_index = term_cmd_buf_size;
    }
    if (term_cmd_buf_index != term_last_cmd_buf_index) {
        delta = term_cmd_buf_index - term_last_cmd_buf_index;
        if (delta > 0) {
            for(i = 0;i < delta; i++) {
                term_printf("\033[C");
            }
        } else {
            delta = -delta;
            for(i = 0;i < delta; i++) {
                term_printf("\033[D");
            }
        }
        term_last_cmd_buf_index = term_cmd_buf_index;
    }
    term_flush();
}

static void term_insert_char(int ch)
{
    if (term_cmd_buf_index < TERM_CMD_BUF_SIZE) {
        memmove(term_cmd_buf + term_cmd_buf_index + 1,
                term_cmd_buf + term_cmd_buf_index,
                term_cmd_buf_size - term_cmd_buf_index);
        term_cmd_buf[term_cmd_buf_index] = ch;
        term_cmd_buf_size++;
        term_cmd_buf_index++;
    }
}

static void term_backward_char(void)
{
    if (term_cmd_buf_index > 0) {
        term_cmd_buf_index--;
    }
}

static void term_forward_char(void)
{
    if (term_cmd_buf_index < term_cmd_buf_size) {
        term_cmd_buf_index++;
    }
}

static void term_delete_char(void)
{
    if (term_cmd_buf_index < term_cmd_buf_size) {
        memmove(term_cmd_buf + term_cmd_buf_index,
                term_cmd_buf + term_cmd_buf_index + 1,
                term_cmd_buf_size - term_cmd_buf_index - 1);
        term_cmd_buf_size--;
    }
}

static void term_backspace(void)
{
    if (term_cmd_buf_index > 0) {
        term_backward_char();
        term_delete_char();
    }
}

static void term_backword(void)
{
    int start;

    if (term_cmd_buf_index == 0 || term_cmd_buf_index > term_cmd_buf_size) {
        return;
    }

    start = term_cmd_buf_index - 1;

    /* find first word (backwards) */
    while (start > 0) {
        if (!isspace(term_cmd_buf[start])) {
            break;
        }

        --start;
    }

    /* find first space (backwards) */
    while (start > 0) {
        if (isspace(term_cmd_buf[start])) {
            ++start;
            break;
        }

        --start;
    }

    /* remove word */
    if (start < term_cmd_buf_index) {
        memmove(term_cmd_buf + start,
                term_cmd_buf + term_cmd_buf_index,
                term_cmd_buf_size - term_cmd_buf_index);
        term_cmd_buf_size -= term_cmd_buf_index - start;
        term_cmd_buf_index = start;
    }
}

static void term_bol(void)
{
    term_cmd_buf_index = 0;
}

static void term_eol(void)
{
    term_cmd_buf_index = term_cmd_buf_size;
}

static void term_up_char(void)
{
    int idx;

    if (term_hist_entry == 0)
	return;
    if (term_hist_entry == -1) {
	/* Find latest entry */
	for (idx = 0; idx < TERM_MAX_CMDS; idx++) {
	    if (term_history[idx] == NULL)
		break;
	}
	term_hist_entry = idx;
    }
    term_hist_entry--;
    if (term_hist_entry >= 0) {
	pstrcpy(term_cmd_buf, sizeof(term_cmd_buf),
                term_history[term_hist_entry]);
	term_cmd_buf_index = term_cmd_buf_size = strlen(term_cmd_buf);
    }
}

static void term_down_char(void)
{
    if (term_hist_entry == TERM_MAX_CMDS - 1 || term_hist_entry == -1)
	return;
    if (term_history[++term_hist_entry] != NULL) {
	pstrcpy(term_cmd_buf, sizeof(term_cmd_buf),
                term_history[term_hist_entry]);
    } else {
	term_hist_entry = -1;
    }
    term_cmd_buf_index = term_cmd_buf_size = strlen(term_cmd_buf);
}

static void term_hist_add(const char *cmdline)
{
    char *hist_entry, *new_entry;
    int idx;

    if (cmdline[0] == '\0')
	return;
    new_entry = NULL;
    if (term_hist_entry != -1) {
	/* We were editing an existing history entry: replace it */
	hist_entry = term_history[term_hist_entry];
	idx = term_hist_entry;
	if (strcmp(hist_entry, cmdline) == 0) {
	    goto same_entry;
	}
    }
    /* Search cmdline in history buffers */
    for (idx = 0; idx < TERM_MAX_CMDS; idx++) {
	hist_entry = term_history[idx];
	if (hist_entry == NULL)
	    break;
	if (strcmp(hist_entry, cmdline) == 0) {
	same_entry:
	    new_entry = hist_entry;
	    /* Put this entry at the end of history */
	    memmove(&term_history[idx], &term_history[idx + 1],
		    &term_history[TERM_MAX_CMDS] - &term_history[idx + 1]);
	    term_history[TERM_MAX_CMDS - 1] = NULL;
	    for (; idx < TERM_MAX_CMDS; idx++) {
		if (term_history[idx] == NULL)
		    break;
	    }
	    break;
	}
    }
    if (idx == TERM_MAX_CMDS) {
	/* Need to get one free slot */
	free(term_history[0]);
	memcpy(term_history, &term_history[1],
	       &term_history[TERM_MAX_CMDS] - &term_history[1]);
	term_history[TERM_MAX_CMDS - 1] = NULL;
	idx = TERM_MAX_CMDS - 1;
    }
    if (new_entry == NULL)
	new_entry = strdup(cmdline);
    term_history[idx] = new_entry;
    term_hist_entry = -1;
}

/* completion support */

void add_completion(const char *str)
{
    if (nb_completions < NB_COMPLETIONS_MAX) {
        completions[nb_completions++] = qemu_strdup(str);
    }
}

static void term_completion(void)
{
    int len, i, j, max_width, nb_cols, max_prefix;
    char *cmdline;

    nb_completions = 0;

    cmdline = qemu_malloc(term_cmd_buf_index + 1);
    if (!cmdline)
        return;
    memcpy(cmdline, term_cmd_buf, term_cmd_buf_index);
    cmdline[term_cmd_buf_index] = '\0';
    readline_find_completion(cmdline);
    qemu_free(cmdline);

    /* no completion found */
    if (nb_completions <= 0)
        return;
    if (nb_completions == 1) {
        len = strlen(completions[0]);
        for(i = completion_index; i < len; i++) {
            term_insert_char(completions[0][i]);
        }
        /* extra space for next argument. XXX: make it more generic */
        if (len > 0 && completions[0][len - 1] != '/')
            term_insert_char(' ');
    } else {
        term_printf("\n");
        max_width = 0;
        max_prefix = 0;	
        for(i = 0; i < nb_completions; i++) {
            len = strlen(completions[i]);
            if (i==0) {
                max_prefix = len;
            } else {
                if (len < max_prefix)
                    max_prefix = len;
                for(j=0; j<max_prefix; j++) {
                    if (completions[i][j] != completions[0][j])
                        max_prefix = j;
                }
            }
            if (len > max_width)
                max_width = len;
        }
        if (max_prefix > 0) 
            for(i = completion_index; i < max_prefix; i++) {
                term_insert_char(completions[0][i]);
            }
        max_width += 2;
        if (max_width < 10)
            max_width = 10;
        else if (max_width > 80)
            max_width = 80;
        nb_cols = 80 / max_width;
        j = 0;
        for(i = 0; i < nb_completions; i++) {
            term_printf("%-*s", max_width, completions[i]);
            if (++j == nb_cols || i == (nb_completions - 1)) {
                term_printf("\n");
                j = 0;
            }
        }
        term_show_prompt2();
    }
}

/* return true if command handled */
void readline_handle_byte(int ch)
{
    switch(term_esc_state) {
    case IS_NORM:
        switch(ch) {
        case 1:
            term_bol();
            break;
        case 4:
            term_delete_char();
            break;
        case 5:
            term_eol();
            break;
        case 9:
            term_completion();
            break;
        case 10:
        case 13:
            term_cmd_buf[term_cmd_buf_size] = '\0';
            if (!term_is_password)
                term_hist_add(term_cmd_buf);
            term_printf("\n");
            term_cmd_buf_index = 0;
            term_cmd_buf_size = 0;
            term_last_cmd_buf_index = 0;
            term_last_cmd_buf_size = 0;
            /* NOTE: readline_start can be called here */
            term_readline_func(term_readline_opaque, term_cmd_buf);
            break;
        case 23:
            /* ^W */
            term_backword();
            break;
        case 27:
            term_esc_state = IS_ESC;
            break;
        case 127:
        case 8:
            term_backspace();
            break;
	case 155:
            term_esc_state = IS_CSI;
	    break;
        default:
            if (ch >= 32) {
                term_insert_char(ch);
            }
            break;
        }
        break;
    case IS_ESC:
        if (ch == '[') {
            term_esc_state = IS_CSI;
            term_esc_param = 0;
        } else {
            term_esc_state = IS_NORM;
        }
        break;
    case IS_CSI:
        switch(ch) {
	case 'A':
	case 'F':
	    term_up_char();
	    break;
	case 'B':
	case 'E':
	    term_down_char();
	    break;
        case 'D':
            term_backward_char();
            break;
        case 'C':
            term_forward_char();
            break;
        case '0' ... '9':
            term_esc_param = term_esc_param * 10 + (ch - '0');
            goto the_end;
        case '~':
            switch(term_esc_param) {
            case 1:
                term_bol();
                break;
            case 3:
                term_delete_char();
                break;
            case 4:
                term_eol();
                break;
            }
            break;
        default:
            break;
        }
        term_esc_state = IS_NORM;
    the_end:
        break;
    }
    term_update();
}

void readline_start(const char *prompt, int is_password,
                    ReadLineFunc *readline_func, void *opaque)
{
    pstrcpy(term_prompt, sizeof(term_prompt), prompt);
    term_readline_func = readline_func;
    term_readline_opaque = opaque;
    term_is_password = is_password;
    term_show_prompt();
}

const char *readline_get_history(unsigned int index)
{
    if (index >= TERM_MAX_CMDS)
        return NULL;
    return term_history[index];
}


