/*
 * 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 (!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_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];
}


