/*
 * QEMU System Emulator
 *
 * Copyright (c) 2003-2008 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 "qapi/error.h"
#include "qemu/module.h"
#include "qemu/option.h"
#include "qemu/bitops.h"
#include "chardev/char.h"
#include "sysemu/block-backend.h"
#include "qapi/qapi-commands-control.h"
#include "chardev-internal.h"

/* MUX driver for serial I/O splitting */

/*
 * Set to false by suspend_mux_open.  Open events are delayed until
 * resume_mux_open.  Usually suspend_mux_open is called before
 * command line processing and resume_mux_open afterwards.
 */
static bool muxes_opened = true;

/* Called with chr_write_lock held.  */
static int mux_chr_write(Chardev *chr, const uint8_t *buf, int len)
{
    MuxChardev *d = MUX_CHARDEV(chr);
    int ret;
    if (!d->timestamps) {
        ret = qemu_chr_fe_write(&d->chr, buf, len);
    } else {
        int i;

        ret = 0;
        for (i = 0; i < len; i++) {
            if (d->linestart) {
                char buf1[64];
                int64_t ti;
                int secs;

                ti = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
                if (d->timestamps_start == -1) {
                    d->timestamps_start = ti;
                }
                ti -= d->timestamps_start;
                secs = ti / 1000;
                snprintf(buf1, sizeof(buf1),
                         "[%02d:%02d:%02d.%03d] ",
                         secs / 3600,
                         (secs / 60) % 60,
                         secs % 60,
                         (int)(ti % 1000));
                /* XXX this blocks entire thread. Rewrite to use
                 * qemu_chr_fe_write and background I/O callbacks */
                qemu_chr_fe_write_all(&d->chr,
                                      (uint8_t *)buf1, strlen(buf1));
                d->linestart = false;
            }
            ret += qemu_chr_fe_write(&d->chr, buf + i, 1);
            if (buf[i] == '\n') {
                d->linestart = true;
            }
        }
    }
    return ret;
}

static const char * const mux_help[] = {
    "% h    print this help\n\r",
    "% x    exit emulator\n\r",
    "% s    save disk data back to file (if -snapshot)\n\r",
    "% t    toggle console timestamps\n\r",
    "% b    send break (magic sysrq)\n\r",
    "% c    switch between console and monitor\n\r",
    "% %  sends %\n\r",
    NULL
};

int term_escape_char = 0x01; /* ctrl-a is used for escape */
static void mux_print_help(Chardev *chr)
{
    int i, j;
    char ebuf[15] = "Escape-Char";
    char cbuf[50] = "\n\r";

    if (term_escape_char > 0 && term_escape_char < 26) {
        snprintf(cbuf, sizeof(cbuf), "\n\r");
        snprintf(ebuf, sizeof(ebuf), "C-%c", term_escape_char - 1 + 'a');
    } else {
        snprintf(cbuf, sizeof(cbuf),
                 "\n\rEscape-Char set to Ascii: 0x%02x\n\r\n\r",
                 term_escape_char);
    }
    /* XXX this blocks entire thread. Rewrite to use
     * qemu_chr_fe_write and background I/O callbacks */
    qemu_chr_write_all(chr, (uint8_t *)cbuf, strlen(cbuf));
    for (i = 0; mux_help[i] != NULL; i++) {
        for (j = 0; mux_help[i][j] != '\0'; j++) {
            if (mux_help[i][j] == '%') {
                qemu_chr_write_all(chr, (uint8_t *)ebuf, strlen(ebuf));
            } else {
                qemu_chr_write_all(chr, (uint8_t *)&mux_help[i][j], 1);
            }
        }
    }
}

static void mux_chr_send_event(MuxChardev *d, unsigned int mux_nr,
                               QEMUChrEvent event)
{
    CharBackend *be = d->backends[mux_nr];

    if (be && be->chr_event) {
        be->chr_event(be->opaque, event);
    }
}

static void mux_chr_be_event(Chardev *chr, QEMUChrEvent event)
{
    MuxChardev *d = MUX_CHARDEV(chr);

    if (d->focus != -1) {
        mux_chr_send_event(d, d->focus, event);
    }
}

static int mux_proc_byte(Chardev *chr, MuxChardev *d, int ch)
{
    if (d->term_got_escape) {
        d->term_got_escape = false;
        if (ch == term_escape_char) {
            goto send_char;
        }
        switch (ch) {
        case '?':
        case 'h':
            mux_print_help(chr);
            break;
        case 'x':
            {
                 const char *term =  "QEMU: Terminated\n\r";
                 qemu_chr_write_all(chr, (uint8_t *)term, strlen(term));
                 qmp_quit(NULL);
                 break;
            }
        case 's':
            blk_commit_all();
            break;
        case 'b':
            qemu_chr_be_event(chr, CHR_EVENT_BREAK);
            break;
        case 'c': {
            unsigned int bit;

            /* Handler registered with first fe */
            assert(d->mux_bitset != 0);
            /* Switch to the next registered device */
            bit = find_next_bit(&d->mux_bitset, MAX_MUX, d->focus + 1);
            if (bit >= MAX_MUX) {
                bit = find_next_bit(&d->mux_bitset, MAX_MUX, 0);
            }
            mux_set_focus(chr, bit);
            break;
        } case 't':
            d->timestamps = !d->timestamps;
            d->timestamps_start = -1;
            d->linestart = false;
            break;
        }
    } else if (ch == term_escape_char) {
        d->term_got_escape = true;
    } else {
    send_char:
        return 1;
    }
    return 0;
}

static void mux_chr_accept_input(Chardev *chr)
{
    MuxChardev *d = MUX_CHARDEV(chr);
    int m = d->focus;
    CharBackend *be = d->backends[m];

    while (be && d->prod[m] != d->cons[m] &&
           be->chr_can_read && be->chr_can_read(be->opaque)) {
        be->chr_read(be->opaque,
                     &d->buffer[m][d->cons[m]++ & MUX_BUFFER_MASK], 1);
    }
}

static int mux_chr_can_read(void *opaque)
{
    MuxChardev *d = MUX_CHARDEV(opaque);
    int m = d->focus;
    CharBackend *be = d->backends[m];

    if ((d->prod[m] - d->cons[m]) < MUX_BUFFER_SIZE) {
        return 1;
    }

    if (be && be->chr_can_read) {
        return be->chr_can_read(be->opaque);
    }

    return 0;
}

static void mux_chr_read(void *opaque, const uint8_t *buf, int size)
{
    Chardev *chr = CHARDEV(opaque);
    MuxChardev *d = MUX_CHARDEV(opaque);
    int m = d->focus;
    CharBackend *be = d->backends[m];
    int i;

    mux_chr_accept_input(opaque);

    for (i = 0; i < size; i++)
        if (mux_proc_byte(chr, d, buf[i])) {
            if (d->prod[m] == d->cons[m] &&
                be && be->chr_can_read &&
                be->chr_can_read(be->opaque)) {
                be->chr_read(be->opaque, &buf[i], 1);
            } else {
                d->buffer[m][d->prod[m]++ & MUX_BUFFER_MASK] = buf[i];
            }
        }
}

void mux_chr_send_all_event(Chardev *chr, QEMUChrEvent event)
{
    MuxChardev *d = MUX_CHARDEV(chr);
    int bit;

    if (!muxes_opened) {
        return;
    }

    /* Send the event to all registered listeners */
    bit = -1;
    while ((bit = find_next_bit(&d->mux_bitset, MAX_MUX, bit + 1)) < MAX_MUX) {
        mux_chr_send_event(d, bit, event);
    }
}

static void mux_chr_event(void *opaque, QEMUChrEvent event)
{
    mux_chr_send_all_event(CHARDEV(opaque), event);
}

static GSource *mux_chr_add_watch(Chardev *s, GIOCondition cond)
{
    MuxChardev *d = MUX_CHARDEV(s);
    Chardev *chr = qemu_chr_fe_get_driver(&d->chr);
    ChardevClass *cc = CHARDEV_GET_CLASS(chr);

    if (!cc->chr_add_watch) {
        return NULL;
    }

    return cc->chr_add_watch(chr, cond);
}

static void char_mux_finalize(Object *obj)
{
    MuxChardev *d = MUX_CHARDEV(obj);
    int bit;

    bit = -1;
    while ((bit = find_next_bit(&d->mux_bitset, MAX_MUX, bit + 1)) < MAX_MUX) {
        CharBackend *be = d->backends[bit];
        be->chr = NULL;
        d->backends[bit] = NULL;
    }
    d->mux_bitset = 0;
    qemu_chr_fe_deinit(&d->chr, false);
}

static void mux_chr_update_read_handlers(Chardev *chr)
{
    MuxChardev *d = MUX_CHARDEV(chr);

    /* Fix up the real driver with mux routines */
    qemu_chr_fe_set_handlers_full(&d->chr,
                                  mux_chr_can_read,
                                  mux_chr_read,
                                  mux_chr_event,
                                  NULL,
                                  chr,
                                  chr->gcontext, true, false);
}

bool mux_chr_attach_frontend(MuxChardev *d, CharBackend *b,
                             unsigned int *tag, Error **errp)
{
    unsigned int bit;

    bit = find_next_zero_bit(&d->mux_bitset, MAX_MUX, 0);
    if (bit >= MAX_MUX) {
        error_setg(errp,
                   "too many uses of multiplexed chardev '%s'"
                   " (maximum is " stringify(MAX_MUX) ")",
                   d->parent.label);
        return false;
    }

    d->mux_bitset |= (1 << bit);
    d->backends[bit] = b;
    *tag = bit;

    return true;
}

bool mux_chr_detach_frontend(MuxChardev *d, unsigned int tag)
{
    unsigned int bit;

    bit = find_next_bit(&d->mux_bitset, MAX_MUX, tag);
    if (bit != tag) {
        return false;
    }

    d->mux_bitset &= ~(1 << bit);
    d->backends[bit] = NULL;

    return true;
}

void mux_set_focus(Chardev *chr, unsigned int focus)
{
    MuxChardev *d = MUX_CHARDEV(chr);

    assert(find_next_bit(&d->mux_bitset, MAX_MUX, focus) == focus);

    if (d->focus != -1) {
        mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_OUT);
    }

    d->focus = focus;
    chr->be = d->backends[focus];
    mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_IN);
}

static void qemu_chr_open_mux(Chardev *chr,
                              ChardevBackend *backend,
                              bool *be_opened,
                              Error **errp)
{
    ChardevMux *mux = backend->u.mux.data;
    Chardev *drv;
    MuxChardev *d = MUX_CHARDEV(chr);

    drv = qemu_chr_find(mux->chardev);
    if (drv == NULL) {
        error_setg(errp, "mux: base chardev %s not found", mux->chardev);
        return;
    }

    d->focus = -1;
    /* only default to opened state if we've realized the initial
     * set of muxes
     */
    *be_opened = muxes_opened;
    qemu_chr_fe_init(&d->chr, drv, errp);
}

static void qemu_chr_parse_mux(QemuOpts *opts, ChardevBackend *backend,
                               Error **errp)
{
    const char *chardev = qemu_opt_get(opts, "chardev");
    ChardevMux *mux;

    if (chardev == NULL) {
        error_setg(errp, "chardev: mux: no chardev given");
        return;
    }
    backend->type = CHARDEV_BACKEND_KIND_MUX;
    mux = backend->u.mux.data = g_new0(ChardevMux, 1);
    qemu_chr_parse_common(opts, qapi_ChardevMux_base(mux));
    mux->chardev = g_strdup(chardev);
}

/**
 * Called after processing of default and command-line-specified
 * chardevs to deliver CHR_EVENT_OPENED events to any FEs attached
 * to a mux chardev. This is done here to ensure that
 * output/prompts/banners are only displayed for the FE that has
 * focus when initial command-line processing/machine init is
 * completed.
 *
 * After this point, any new FE attached to any new or existing
 * mux will receive CHR_EVENT_OPENED notifications for the BE
 * immediately.
 */
static void open_muxes(Chardev *chr)
{
    /* send OPENED to all already-attached FEs */
    mux_chr_send_all_event(chr, CHR_EVENT_OPENED);

    /*
     * mark mux as OPENED so any new FEs will immediately receive
     * OPENED event
     */
    chr->be_open = 1;
}

void suspend_mux_open(void)
{
    muxes_opened = false;
}

static int chardev_options_parsed_cb(Object *child, void *opaque)
{
    Chardev *chr = (Chardev *)child;

    if (!chr->be_open && CHARDEV_IS_MUX(chr)) {
        open_muxes(chr);
    }

    return 0;
}

void resume_mux_open(void)
{
    muxes_opened = true;
    object_child_foreach(get_chardevs_root(),
                         chardev_options_parsed_cb, NULL);
}

static void char_mux_class_init(ObjectClass *oc, void *data)
{
    ChardevClass *cc = CHARDEV_CLASS(oc);

    cc->parse = qemu_chr_parse_mux;
    cc->open = qemu_chr_open_mux;
    cc->chr_write = mux_chr_write;
    cc->chr_accept_input = mux_chr_accept_input;
    cc->chr_add_watch = mux_chr_add_watch;
    cc->chr_be_event = mux_chr_be_event;
    cc->chr_update_read_handler = mux_chr_update_read_handlers;
}

static const TypeInfo char_mux_type_info = {
    .name = TYPE_CHARDEV_MUX,
    .parent = TYPE_CHARDEV,
    .class_init = char_mux_class_init,
    .instance_size = sizeof(MuxChardev),
    .instance_finalize = char_mux_finalize,
};

static void register_types(void)
{
    type_register_static(&char_mux_type_info);
}

type_init(register_types);
