/*
 * 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 "qemu-common.h"
#include "console.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 (!qemu_isspace(term_cmd_buf[start])) {
            break;
        }

        --start;
    }

    /* find first space (backwards) */
    while (start > 0) {
        if (qemu_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_MAX_CMDS - idx + 1) * sizeof(char *));
	    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_MAX_CMDS - 1) * sizeof(char *));
	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];
}


