/*
 * SCLP event types
 *    Operations Command - Line Mode input
 *    Message            - Line Mode output
 *
 * Copyright IBM, Corp. 2013
 *
 * Authors:
 *  Heinz Graalfs <graalfs@linux.vnet.ibm.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or (at your
 * option) any later version.  See the COPYING file in the top-level directory.
 *
 */

#include "hw/qdev.h"
#include "qemu/thread.h"
#include "qemu/error-report.h"
#include "sysemu/char.h"

#include "hw/s390x/sclp.h"
#include "hw/s390x/event-facility.h"
#include "hw/s390x/ebcdic.h"

#define SIZE_BUFFER 4096
#define NEWLINE     "\n"

typedef struct OprtnsCommand {
    EventBufferHeader header;
    MDMSU message_unit;
    char data[0];
} QEMU_PACKED OprtnsCommand;

/* max size for line-mode data in 4K SCCB page */
#define SIZE_CONSOLE_BUFFER (SCCB_DATA_LEN - sizeof(OprtnsCommand))

typedef struct SCLPConsoleLM {
    SCLPEvent event;
    CharDriverState *chr;
    bool echo;                  /* immediate echo of input if true        */
    uint32_t write_errors;      /* errors writing to char layer           */
    uint32_t length;            /* length of byte stream in buffer        */
    uint8_t buf[SIZE_CONSOLE_BUFFER];
} SCLPConsoleLM;

/*
*  Character layer call-back functions
 *
 * Allow 1 character at a time
 *
 * Accumulate bytes from character layer in console buffer,
 * event_pending is set when a newline character is encountered
 *
 * The maximum command line length is limited by the maximum
 * space available in an SCCB. Line mode console input is sent
 * truncated to the guest in case it doesn't fit into the SCCB.
 */

static int chr_can_read(void *opaque)
{
    SCLPConsoleLM *scon = opaque;

    if (scon->event.event_pending) {
        return 0;
    }
    return 1;
}

static void chr_read(void *opaque, const uint8_t *buf, int size)
{
    SCLPConsoleLM *scon = opaque;

    assert(size == 1);

    if (*buf == '\r' || *buf == '\n') {
        scon->event.event_pending = true;
        sclp_service_interrupt(0);
        return;
    }
    if (scon->length == SIZE_CONSOLE_BUFFER) {
        /* Eat the character, but still process CR and LF.  */
        return;
    }
    scon->buf[scon->length] = *buf;
    scon->length += 1;
    if (scon->echo) {
        qemu_chr_fe_write(scon->chr, buf, size);
    }
}

/* functions to be called by event facility */

static bool can_handle_event(uint8_t type)
{
    return type == SCLP_EVENT_MESSAGE || type == SCLP_EVENT_PMSGCMD;
}

static unsigned int send_mask(void)
{
    return SCLP_EVENT_MASK_OP_CMD | SCLP_EVENT_MASK_PMSGCMD;
}

static unsigned int receive_mask(void)
{
    return SCLP_EVENT_MASK_MSG | SCLP_EVENT_MASK_PMSGCMD;
}

/*
 * Triggered by SCLP's read_event_data
 * - convert ASCII byte stream to EBCDIC and
 * - copy converted data into provided (SCLP) buffer
 */
static int get_console_data(SCLPEvent *event, uint8_t *buf, size_t *size,
                            int avail)
{
    int len;

    SCLPConsoleLM *cons = DO_UPCAST(SCLPConsoleLM, event, event);

    len = cons->length;
    /* data need to fit into provided SCLP buffer */
    if (len > avail) {
        return 1;
    }

    ebcdic_put(buf, (char *)&cons->buf, len);
    *size = len;
    cons->length = 0;
    /* data provided and no more data pending */
    event->event_pending = false;
    qemu_notify_event();
    return 0;
}

static int read_event_data(SCLPEvent *event, EventBufferHeader *evt_buf_hdr,
                           int *slen)
{
    int avail, rc;
    size_t src_len;
    uint8_t *to;
    OprtnsCommand *oc = (OprtnsCommand *) evt_buf_hdr;

    if (!event->event_pending) {
        /* no data pending */
        return 0;
    }

    to = (uint8_t *)&oc->data;
    avail = *slen - sizeof(OprtnsCommand);
    rc = get_console_data(event, to, &src_len, avail);
    if (rc) {
        /* data didn't fit, try next SCCB */
        return 1;
    }

    oc->message_unit.mdmsu.gds_id = GDS_ID_MDSMU;
    oc->message_unit.mdmsu.length = cpu_to_be16(sizeof(struct MDMSU));

    oc->message_unit.cpmsu.gds_id = GDS_ID_CPMSU;
    oc->message_unit.cpmsu.length =
        cpu_to_be16(sizeof(struct MDMSU) - sizeof(GdsVector));

    oc->message_unit.text_command.gds_id = GDS_ID_TEXTCMD;
    oc->message_unit.text_command.length =
        cpu_to_be16(sizeof(struct MDMSU) - (2 * sizeof(GdsVector)));

    oc->message_unit.self_def_text_message.key = GDS_KEY_SELFDEFTEXTMSG;
    oc->message_unit.self_def_text_message.length =
        cpu_to_be16(sizeof(struct MDMSU) - (3 * sizeof(GdsVector)));

    oc->message_unit.text_message.key = GDS_KEY_TEXTMSG;
    oc->message_unit.text_message.length =
        cpu_to_be16(sizeof(GdsSubvector) + src_len);

    oc->header.length = cpu_to_be16(sizeof(OprtnsCommand) + src_len);
    oc->header.type = SCLP_EVENT_OPRTNS_COMMAND;
    *slen = avail - src_len;

    return 1;
}

/*
 * Triggered by SCLP's write_event_data
 *  - write console data to character layer
 *  returns < 0 if an error occurred
 */
static int write_console_data(SCLPEvent *event, const uint8_t *buf, int len)
{
    int ret = 0;
    const uint8_t *buf_offset;

    SCLPConsoleLM *scon = DO_UPCAST(SCLPConsoleLM, event, event);

    if (!scon->chr) {
        /* If there's no backend, we can just say we consumed all data. */
        return len;
    }

    buf_offset = buf;
    while (len > 0) {
        ret = qemu_chr_fe_write(scon->chr, buf, len);
        if (ret == 0) {
            /* a pty doesn't seem to be connected - no error */
            len = 0;
        } else if (ret == -EAGAIN || (ret > 0 && ret < len)) {
            len -= ret;
            buf_offset += ret;
        } else {
            len = 0;
        }
    }

    return ret;
}

static int process_mdb(SCLPEvent *event, MDBO *mdbo)
{
    int rc;
    int len;
    uint8_t buffer[SIZE_BUFFER];

    len = be16_to_cpu(mdbo->length);
    len -= sizeof(mdbo->length) + sizeof(mdbo->type)
            + sizeof(mdbo->mto.line_type_flags)
            + sizeof(mdbo->mto.alarm_control)
            + sizeof(mdbo->mto._reserved);

    assert(len <= SIZE_BUFFER);

    /* convert EBCDIC SCLP contents to ASCII console message */
    ascii_put(buffer, mdbo->mto.message, len);
    rc = write_console_data(event, (uint8_t *)NEWLINE, 1);
    if (rc < 0) {
        return rc;
    }
    return write_console_data(event, buffer, len);
}

static int write_event_data(SCLPEvent *event, EventBufferHeader *ebh)
{
    int len;
    int written;
    int errors = 0;
    MDBO *mdbo;
    SclpMsg *data = (SclpMsg *) ebh;
    SCLPConsoleLM *scon = DO_UPCAST(SCLPConsoleLM, event, event);

    len = be16_to_cpu(data->mdb.header.length);
    if (len < sizeof(data->mdb.header)) {
        return SCLP_RC_INCONSISTENT_LENGTHS;
    }
    len -= sizeof(data->mdb.header);

    /* first check message buffers */
    mdbo = data->mdb.mdbo;
    while (len > 0) {
        if (be16_to_cpu(mdbo->length) > len
                || be16_to_cpu(mdbo->length) == 0) {
            return SCLP_RC_INCONSISTENT_LENGTHS;
        }
        len -= be16_to_cpu(mdbo->length);
        mdbo = (void *) mdbo + be16_to_cpu(mdbo->length);
    }

    /* then execute */
    len = be16_to_cpu(data->mdb.header.length) - sizeof(data->mdb.header);
    mdbo = data->mdb.mdbo;
    while (len > 0) {
        switch (be16_to_cpu(mdbo->type)) {
        case MESSAGE_TEXT:
            /* message text object */
            written = process_mdb(event, mdbo);
            if (written < 0) {
                /* character layer error */
                errors++;
            }
            break;
        default: /* ignore */
            break;
        }
        len -= be16_to_cpu(mdbo->length);
        mdbo = (void *) mdbo + be16_to_cpu(mdbo->length);
    }
    if (errors) {
        scon->write_errors += errors;
    }
    data->header.flags = SCLP_EVENT_BUFFER_ACCEPTED;

    return SCLP_RC_NORMAL_COMPLETION;
}

/* functions for live migration */

static const VMStateDescription vmstate_sclplmconsole = {
    .name = "sclplmconsole",
    .version_id = 0,
    .minimum_version_id = 0,
    .fields = (VMStateField[]) {
        VMSTATE_BOOL(event.event_pending, SCLPConsoleLM),
        VMSTATE_UINT32(write_errors, SCLPConsoleLM),
        VMSTATE_UINT32(length, SCLPConsoleLM),
        VMSTATE_UINT8_ARRAY(buf, SCLPConsoleLM, SIZE_CONSOLE_BUFFER),
        VMSTATE_END_OF_LIST()
     }
};

/* qemu object creation and initialization functions */

/* tell character layer our call-back functions */

static int console_init(SCLPEvent *event)
{
    static bool console_available;

    SCLPConsoleLM *scon = DO_UPCAST(SCLPConsoleLM, event, event);

    if (console_available) {
        error_report("Multiple line-mode operator consoles are not supported");
        return -1;
    }
    console_available = true;

    if (scon->chr) {
        qemu_chr_add_handlers(scon->chr, chr_can_read, chr_read, NULL, scon);
    }

    return 0;
}

static int console_exit(SCLPEvent *event)
{
    return 0;
}

static void console_reset(DeviceState *dev)
{
   SCLPEvent *event = SCLP_EVENT(dev);
   SCLPConsoleLM *scon = DO_UPCAST(SCLPConsoleLM, event, event);

   event->event_pending = false;
   scon->length = 0;
   scon->write_errors = 0;
}

static Property console_properties[] = {
    DEFINE_PROP_CHR("chardev", SCLPConsoleLM, chr),
    DEFINE_PROP_UINT32("write_errors", SCLPConsoleLM, write_errors, 0),
    DEFINE_PROP_BOOL("echo", SCLPConsoleLM, echo, true),
    DEFINE_PROP_END_OF_LIST(),
};

static void console_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    SCLPEventClass *ec = SCLP_EVENT_CLASS(klass);

    dc->props = console_properties;
    dc->reset = console_reset;
    dc->vmsd = &vmstate_sclplmconsole;
    ec->init = console_init;
    ec->exit = console_exit;
    ec->get_send_mask = send_mask;
    ec->get_receive_mask = receive_mask;
    ec->can_handle_event = can_handle_event;
    ec->read_event_data = read_event_data;
    ec->write_event_data = write_event_data;
}

static const TypeInfo sclp_console_info = {
    .name          = "sclplmconsole",
    .parent        = TYPE_SCLP_EVENT,
    .instance_size = sizeof(SCLPConsoleLM),
    .class_init    = console_class_init,
    .class_size    = sizeof(SCLPEventClass),
};

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

type_init(register_types)
