/*
 * 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 "qemu/osdep.h"
#include "qemu/thread.h"
#include "qemu/error-report.h"
#include "qemu/module.h"
#include "chardev/char-fe.h"

#include "hw/s390x/sclp.h"
#include "migration/vmstate.h"
#include "hw/s390x/event-facility.h"
#include "hw/qdev-properties.h"
#include "hw/qdev-properties-system.h"
#include "hw/s390x/ebcdic.h"
#include "qom/object.h"

#define SIZE_BUFFER 4096
#define NEWLINE     "\n"

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

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

struct SCLPConsoleLM {
    SCLPEvent event;
    CharBackend 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];
};
typedef struct SCLPConsoleLM SCLPConsoleLM;

#define TYPE_SCLPLM_CONSOLE "sclplmconsole"
DECLARE_INSTANCE_CHECKER(SCLPConsoleLM, SCLPLM_CONSOLE,
                         TYPE_SCLPLM_CONSOLE)

/*
*  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) {
        /* XXX this blocks entire thread. Rewrite to use
         * qemu_chr_fe_write and background I/O callbacks */
        qemu_chr_fe_write_all(&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 sccb_mask_t send_mask(void)
{
    return SCLP_EVENT_MASK_OP_CMD | SCLP_EVENT_MASK_PMSGCMD;
}

static sccb_mask_t 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 = SCLPLM_CONSOLE(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)
{
    SCLPConsoleLM *scon = SCLPLM_CONSOLE(event);

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

    /* XXX this blocks entire thread. Rewrite to use
     * qemu_chr_fe_write and background I/O callbacks */
    return qemu_chr_fe_write_all(&scon->chr, buf, len);
}

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 = SCLPLM_CONSOLE(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 = SCLPLM_CONSOLE(event);

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

    qemu_chr_fe_set_handlers(&scon->chr, chr_can_read,
                             chr_read, NULL, NULL, scon, NULL, true);

    return 0;
}

static void console_reset(DeviceState *dev)
{
   SCLPEvent *event = SCLP_EVENT(dev);
   SCLPConsoleLM *scon = SCLPLM_CONSOLE(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);

    device_class_set_props(dc, console_properties);
    dc->reset = console_reset;
    dc->vmsd = &vmstate_sclplmconsole;
    ec->init = console_init;
    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;
    set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
}

static const TypeInfo sclp_console_info = {
    .name          = TYPE_SCLPLM_CONSOLE,
    .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)
