/*
 * 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/osdep.h"
#include "qemu-common.h"
#include "qemu/readline.h"
#include "qemu/cutils.h"

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

void readline_show_prompt(ReadLineState *rs)
{
    rs->printf_func(rs->opaque, "%s", rs->prompt);
    rs->flush_func(rs->opaque);
    rs->last_cmd_buf_index = 0;
    rs->last_cmd_buf_size = 0;
    rs->esc_state = IS_NORM;
}

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

    if (rs->cmd_buf_size != rs->last_cmd_buf_size ||
        memcmp(rs->cmd_buf, rs->last_cmd_buf, rs->cmd_buf_size) != 0) {
        for (i = 0; i < rs->last_cmd_buf_index; i++) {
            rs->printf_func(rs->opaque, "\033[D");
        }
        rs->cmd_buf[rs->cmd_buf_size] = '\0';
        if (rs->read_password) {
            len = strlen(rs->cmd_buf);
            for (i = 0; i < len; i++) {
                rs->printf_func(rs->opaque, "*");
            }
        } else {
            rs->printf_func(rs->opaque, "%s", rs->cmd_buf);
        }
        rs->printf_func(rs->opaque, "\033[K");
        memcpy(rs->last_cmd_buf, rs->cmd_buf, rs->cmd_buf_size);
        rs->last_cmd_buf_size = rs->cmd_buf_size;
        rs->last_cmd_buf_index = rs->cmd_buf_size;
    }
    if (rs->cmd_buf_index != rs->last_cmd_buf_index) {
        delta = rs->cmd_buf_index - rs->last_cmd_buf_index;
        if (delta > 0) {
            for (i = 0; i < delta; i++) {
                rs->printf_func(rs->opaque, "\033[C");
            }
        } else {
            delta = -delta;
            for (i = 0; i < delta; i++) {
                rs->printf_func(rs->opaque, "\033[D");
            }
        }
        rs->last_cmd_buf_index = rs->cmd_buf_index;
    }
    rs->flush_func(rs->opaque);
}

static void readline_insert_char(ReadLineState *rs, int ch)
{
    if (rs->cmd_buf_index < READLINE_CMD_BUF_SIZE) {
        memmove(rs->cmd_buf + rs->cmd_buf_index + 1,
                rs->cmd_buf + rs->cmd_buf_index,
                rs->cmd_buf_size - rs->cmd_buf_index);
        rs->cmd_buf[rs->cmd_buf_index] = ch;
        rs->cmd_buf_size++;
        rs->cmd_buf_index++;
    }
}

static void readline_backward_char(ReadLineState *rs)
{
    if (rs->cmd_buf_index > 0) {
        rs->cmd_buf_index--;
    }
}

static void readline_forward_char(ReadLineState *rs)
{
    if (rs->cmd_buf_index < rs->cmd_buf_size) {
        rs->cmd_buf_index++;
    }
}

static void readline_delete_char(ReadLineState *rs)
{
    if (rs->cmd_buf_index < rs->cmd_buf_size) {
        memmove(rs->cmd_buf + rs->cmd_buf_index,
                rs->cmd_buf + rs->cmd_buf_index + 1,
                rs->cmd_buf_size - rs->cmd_buf_index - 1);
        rs->cmd_buf_size--;
    }
}

static void readline_backspace(ReadLineState *rs)
{
    if (rs->cmd_buf_index > 0) {
        readline_backward_char(rs);
        readline_delete_char(rs);
    }
}

static void readline_backword(ReadLineState *rs)
{
    int start;

    if (rs->cmd_buf_index == 0 || rs->cmd_buf_index > rs->cmd_buf_size) {
        return;
    }

    start = rs->cmd_buf_index - 1;

    /* find first word (backwards) */
    while (start > 0) {
        if (!qemu_isspace(rs->cmd_buf[start])) {
            break;
        }

        --start;
    }

    /* find first space (backwards) */
    while (start > 0) {
        if (qemu_isspace(rs->cmd_buf[start])) {
            ++start;
            break;
        }

        --start;
    }

    /* remove word */
    if (start < rs->cmd_buf_index) {
        memmove(rs->cmd_buf + start,
                rs->cmd_buf + rs->cmd_buf_index,
                rs->cmd_buf_size - rs->cmd_buf_index);
        rs->cmd_buf_size -= rs->cmd_buf_index - start;
        rs->cmd_buf_index = start;
    }
}

static void readline_bol(ReadLineState *rs)
{
    rs->cmd_buf_index = 0;
}

static void readline_eol(ReadLineState *rs)
{
    rs->cmd_buf_index = rs->cmd_buf_size;
}

static void readline_up_char(ReadLineState *rs)
{
    int idx;

    if (rs->hist_entry == 0) {
        return;
    }
    if (rs->hist_entry == -1) {
        /* Find latest entry */
        for (idx = 0; idx < READLINE_MAX_CMDS; idx++) {
            if (rs->history[idx] == NULL) {
                break;
            }
        }
        rs->hist_entry = idx;
    }
    rs->hist_entry--;
    if (rs->hist_entry >= 0) {
        pstrcpy(rs->cmd_buf, sizeof(rs->cmd_buf),
                rs->history[rs->hist_entry]);
        rs->cmd_buf_index = rs->cmd_buf_size = strlen(rs->cmd_buf);
    }
}

static void readline_down_char(ReadLineState *rs)
{
    if (rs->hist_entry == -1) {
        return;
    }
    if (rs->hist_entry < READLINE_MAX_CMDS - 1 &&
        rs->history[++rs->hist_entry] != NULL) {
        pstrcpy(rs->cmd_buf, sizeof(rs->cmd_buf),
                rs->history[rs->hist_entry]);
    } else {
        rs->cmd_buf[0] = 0;
        rs->hist_entry = -1;
    }
    rs->cmd_buf_index = rs->cmd_buf_size = strlen(rs->cmd_buf);
}

static void readline_hist_add(ReadLineState *rs, const char *cmdline)
{
    char *hist_entry, *new_entry;
    int idx;

    if (cmdline[0] == '\0') {
        return;
    }
    new_entry = NULL;
    if (rs->hist_entry != -1) {
        /* We were editing an existing history entry: replace it */
        hist_entry = rs->history[rs->hist_entry];
        idx = rs->hist_entry;
        if (strcmp(hist_entry, cmdline) == 0) {
            goto same_entry;
        }
    }
    /* Search cmdline in history buffers */
    for (idx = 0; idx < READLINE_MAX_CMDS; idx++) {
        hist_entry = rs->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(&rs->history[idx], &rs->history[idx + 1],
                    (READLINE_MAX_CMDS - (idx + 1)) * sizeof(char *));
            rs->history[READLINE_MAX_CMDS - 1] = NULL;
            for (; idx < READLINE_MAX_CMDS; idx++) {
                if (rs->history[idx] == NULL) {
                    break;
                }
            }
            break;
        }
    }
    if (idx == READLINE_MAX_CMDS) {
        /* Need to get one free slot */
        g_free(rs->history[0]);
        memmove(rs->history, &rs->history[1],
                (READLINE_MAX_CMDS - 1) * sizeof(char *));
        rs->history[READLINE_MAX_CMDS - 1] = NULL;
        idx = READLINE_MAX_CMDS - 1;
    }
    if (new_entry == NULL) {
        new_entry = g_strdup(cmdline);
    }
    rs->history[idx] = new_entry;
    rs->hist_entry = -1;
}

/* completion support */

void readline_add_completion(ReadLineState *rs, const char *str)
{
    if (rs->nb_completions < READLINE_MAX_COMPLETIONS) {
        int i;
        for (i = 0; i < rs->nb_completions; i++) {
            if (!strcmp(rs->completions[i], str)) {
                return;
            }
        }
        rs->completions[rs->nb_completions++] = g_strdup(str);
    }
}

void readline_set_completion_index(ReadLineState *rs, int index)
{
    rs->completion_index = index;
}

static int completion_comp(const void *a, const void *b)
{
    return strcmp(*(const char **) a, *(const char **) b);
}

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

    rs->nb_completions = 0;

    cmdline = g_strndup(rs->cmd_buf, rs->cmd_buf_index);
    rs->completion_finder(rs->opaque, cmdline);
    g_free(cmdline);

    /* no completion found */
    if (rs->nb_completions <= 0) {
        return;
    }
    if (rs->nb_completions == 1) {
        len = strlen(rs->completions[0]);
        for (i = rs->completion_index; i < len; i++) {
            readline_insert_char(rs, rs->completions[0][i]);
        }
        /* extra space for next argument. XXX: make it more generic */
        if (len > 0 && rs->completions[0][len - 1] != '/') {
            readline_insert_char(rs, ' ');
        }
    } else {
        qsort(rs->completions, rs->nb_completions, sizeof(char *),
              completion_comp);
        rs->printf_func(rs->opaque, "\n");
        max_width = 0;
        max_prefix = 0;
        for (i = 0; i < rs->nb_completions; i++) {
            len = strlen(rs->completions[i]);
            if (i == 0) {
                max_prefix = len;
            } else {
                if (len < max_prefix) {
                    max_prefix = len;
                }
                for (j = 0; j < max_prefix; j++) {
                    if (rs->completions[i][j] != rs->completions[0][j]) {
                        max_prefix = j;
                    }
                }
            }
            if (len > max_width) {
                max_width = len;
            }
        }
        if (max_prefix > 0)
            for (i = rs->completion_index; i < max_prefix; i++) {
                readline_insert_char(rs, rs->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 < rs->nb_completions; i++) {
            rs->printf_func(rs->opaque, "%-*s", max_width, rs->completions[i]);
            if (++j == nb_cols || i == (rs->nb_completions - 1)) {
                rs->printf_func(rs->opaque, "\n");
                j = 0;
            }
        }
        readline_show_prompt(rs);
    }
    for (i = 0; i < rs->nb_completions; i++) {
        g_free(rs->completions[i]);
    }
}

static void readline_clear_screen(ReadLineState *rs)
{
    rs->printf_func(rs->opaque, "\033[2J\033[1;1H");
    readline_show_prompt(rs);
}

/* return true if command handled */
void readline_handle_byte(ReadLineState *rs, int ch)
{
    switch (rs->esc_state) {
    case IS_NORM:
        switch (ch) {
        case 1:
            readline_bol(rs);
            break;
        case 4:
            readline_delete_char(rs);
            break;
        case 5:
            readline_eol(rs);
            break;
        case 9:
            readline_completion(rs);
            break;
        case 12:
            readline_clear_screen(rs);
            break;
        case 10:
        case 13:
            rs->cmd_buf[rs->cmd_buf_size] = '\0';
            if (!rs->read_password) {
                readline_hist_add(rs, rs->cmd_buf);
            }
            rs->printf_func(rs->opaque, "\n");
            rs->cmd_buf_index = 0;
            rs->cmd_buf_size = 0;
            rs->last_cmd_buf_index = 0;
            rs->last_cmd_buf_size = 0;
            rs->readline_func(rs->opaque, rs->cmd_buf, rs->readline_opaque);
            break;
        case 23:
            /* ^W */
            readline_backword(rs);
            break;
        case 27:
            rs->esc_state = IS_ESC;
            break;
        case 127:
        case 8:
            readline_backspace(rs);
            break;
        case 155:
            rs->esc_state = IS_CSI;
            break;
        default:
            if (ch >= 32) {
                readline_insert_char(rs, ch);
            }
            break;
        }
        break;
    case IS_ESC:
        if (ch == '[') {
            rs->esc_state = IS_CSI;
            rs->esc_param = 0;
        } else if (ch == 'O') {
            rs->esc_state = IS_SS3;
            rs->esc_param = 0;
        } else {
            rs->esc_state = IS_NORM;
        }
        break;
    case IS_CSI:
        switch (ch) {
        case 'A':
        case 'F':
            readline_up_char(rs);
            break;
        case 'B':
        case 'E':
            readline_down_char(rs);
            break;
        case 'D':
            readline_backward_char(rs);
            break;
        case 'C':
            readline_forward_char(rs);
            break;
        case '0' ... '9':
            rs->esc_param = rs->esc_param * 10 + (ch - '0');
            goto the_end;
        case '~':
            switch (rs->esc_param) {
            case 1:
                readline_bol(rs);
                break;
            case 3:
                readline_delete_char(rs);
                break;
            case 4:
                readline_eol(rs);
                break;
            }
            break;
        default:
            break;
        }
        rs->esc_state = IS_NORM;
    the_end:
        break;
    case IS_SS3:
        switch (ch) {
        case 'F':
            readline_eol(rs);
            break;
        case 'H':
            readline_bol(rs);
            break;
        }
        rs->esc_state = IS_NORM;
        break;
    }
    readline_update(rs);
}

void readline_start(ReadLineState *rs, const char *prompt, int read_password,
                    ReadLineFunc *readline_func, void *opaque)
{
    pstrcpy(rs->prompt, sizeof(rs->prompt), prompt);
    rs->readline_func = readline_func;
    rs->readline_opaque = opaque;
    rs->read_password = read_password;
    readline_restart(rs);
}

void readline_restart(ReadLineState *rs)
{
    rs->cmd_buf_index = 0;
    rs->cmd_buf_size = 0;
}

const char *readline_get_history(ReadLineState *rs, unsigned int index)
{
    if (index >= READLINE_MAX_CMDS) {
        return NULL;
    }
    return rs->history[index];
}

void readline_free(ReadLineState *rs)
{
    int i;

    if (!rs) {
        return;
    }
    for (i = 0; i < READLINE_MAX_CMDS; i++) {
        g_free(rs->history[i]);
    }
    g_free(rs);
}

ReadLineState *readline_init(ReadLinePrintfFunc *printf_func,
                             ReadLineFlushFunc *flush_func,
                             void *opaque,
                             ReadLineCompletionFunc *completion_finder)
{
    ReadLineState *rs = g_new0(ReadLineState, 1);

    rs->hist_entry = -1;
    rs->opaque = opaque;
    rs->printf_func = printf_func;
    rs->flush_func = flush_func;
    rs->completion_finder = completion_finder;

    return rs;
}
