/*
 * Test Server
 *
 * Copyright IBM, Corp. 2011
 *
 * Authors:
 *  Anthony Liguori   <aliguori@us.ibm.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 *
 */

#include "qemu/osdep.h"
#include "qapi/error.h"
#include "system/qtest.h"
#include "system/runstate.h"
#include "chardev/char-fe.h"
#include "exec/ioport.h"
#include "exec/memory.h"
#include "exec/tswap.h"
#include "hw/qdev-core.h"
#include "hw/irq.h"
#include "hw/core/cpu.h"
#include "qemu/accel.h"
#include "system/cpu-timers.h"
#include "qemu/config-file.h"
#include "qemu/option.h"
#include "qemu/error-report.h"
#include "qemu/module.h"
#include "qemu/cutils.h"
#include "qom/object_interfaces.h"

#define MAX_IRQ 256

#define TYPE_QTEST "qtest"

OBJECT_DECLARE_SIMPLE_TYPE(QTest, QTEST)

struct QTest {
    Object parent;

    bool has_machine_link;
    char *chr_name;
    Chardev *chr;
    CharBackend qtest_chr;
    char *log;
};

bool qtest_allowed;

static DeviceState *irq_intercept_dev;
static FILE *qtest_log_fp;
static QTest *qtest;
static GString *inbuf;
static int irq_levels[MAX_IRQ];
static GTimer *timer;
static bool qtest_opened;
static void (*qtest_server_send)(void*, const char*);
static void *qtest_server_send_opaque;

#define FMT_timeval "%.06f"

/**
 * DOC: QTest Protocol
 *
 * Line based protocol, request/response based.  Server can send async messages
 * so clients should always handle many async messages before the response
 * comes in.
 *
 * Valid requests
 * ^^^^^^^^^^^^^^
 *
 * Clock management:
 * """""""""""""""""
 *
 * The qtest client is completely in charge of the QEMU_CLOCK_VIRTUAL.  qtest commands
 * let you adjust the value of the clock (monotonically).  All the commands
 * return the current value of the clock in nanoseconds.
 *
 * If the commands FAIL then time wasn't advanced which is likely
 * because the machine was in a paused state or no timer events exist
 * in the future. This will cause qtest to abort and the test will
 * need to check its assumptions.
 *
 * .. code-block:: none
 *
 *  > clock_step
 *  < OK VALUE
 *
 * Advance the clock to the next deadline.  Useful when waiting for
 * asynchronous events.
 *
 * .. code-block:: none
 *
 *  > clock_step NS
 *  < OK VALUE
 *
 * Advance the clock by NS nanoseconds.
 *
 * .. code-block:: none
 *
 *  > clock_set NS
 *  < OK VALUE
 *
 * Advance the clock to NS nanoseconds (do nothing if it's already past).
 *
 * PIO and memory access:
 * """"""""""""""""""""""
 *
 * .. code-block:: none
 *
 *  > outb ADDR VALUE
 *  < OK
 *
 * .. code-block:: none
 *
 *  > outw ADDR VALUE
 *  < OK
 *
 * .. code-block:: none
 *
 *  > outl ADDR VALUE
 *  < OK
 *
 * .. code-block:: none
 *
 *  > inb ADDR
 *  < OK VALUE
 *
 * .. code-block:: none
 *
 *  > inw ADDR
 *  < OK VALUE
 *
 * .. code-block:: none
 *
 *  > inl ADDR
 *  < OK VALUE
 *
 * .. code-block:: none
 *
 *  > writeb ADDR VALUE
 *  < OK
 *
 * .. code-block:: none
 *
 *  > writew ADDR VALUE
 *  < OK
 *
 * .. code-block:: none
 *
 *  > writel ADDR VALUE
 *  < OK
 *
 * .. code-block:: none
 *
 *  > writeq ADDR VALUE
 *  < OK
 *
 * .. code-block:: none
 *
 *  > readb ADDR
 *  < OK VALUE
 *
 * .. code-block:: none
 *
 *  > readw ADDR
 *  < OK VALUE
 *
 * .. code-block:: none
 *
 *  > readl ADDR
 *  < OK VALUE
 *
 * .. code-block:: none
 *
 *  > readq ADDR
 *  < OK VALUE
 *
 * .. code-block:: none
 *
 *  > read ADDR SIZE
 *  < OK DATA
 *
 * .. code-block:: none
 *
 *  > write ADDR SIZE DATA
 *  < OK
 *
 * .. code-block:: none
 *
 *  > b64read ADDR SIZE
 *  < OK B64_DATA
 *
 * .. code-block:: none
 *
 *  > b64write ADDR SIZE B64_DATA
 *  < OK
 *
 * .. code-block:: none
 *
 *  > memset ADDR SIZE VALUE
 *  < OK
 *
 * ADDR, SIZE, VALUE are all integers parsed with strtoul() with a base of 0.
 * For 'memset' a zero size is permitted and does nothing.
 *
 * DATA is an arbitrarily long hex number prefixed with '0x'.  If it's smaller
 * than the expected size, the value will be zero filled at the end of the data
 * sequence.
 *
 * B64_DATA is an arbitrarily long base64 encoded string.
 * If the sizes do not match, the data will be truncated.
 *
 * IRQ management:
 * """""""""""""""
 *
 * .. code-block:: none
 *
 *  > irq_intercept_in QOM-PATH
 *  < OK
 *
 * .. code-block:: none
 *
 *  > irq_intercept_out QOM-PATH
 *  < OK
 *
 * Attach to the gpio-in (resp. gpio-out) pins exported by the device at
 * QOM-PATH.  When the pin is triggered, one of the following async messages
 * will be printed to the qtest stream::
 *
 *  IRQ raise NUM
 *  IRQ lower NUM
 *
 * where NUM is an IRQ number.  For the PC, interrupts can be intercepted
 * simply with "irq_intercept_in ioapic" (note that IRQ0 comes out with
 * NUM=0 even though it is remapped to GSI 2).
 *
 * Setting interrupt level:
 * """"""""""""""""""""""""
 *
 * .. code-block:: none
 *
 *  > set_irq_in QOM-PATH NAME NUM LEVEL
 *  < OK
 *
 * where NAME is the name of the irq/gpio list, NUM is an IRQ number and
 * LEVEL is an signed integer IRQ level.
 *
 * Forcibly set the given interrupt pin to the given level.
 *
 */

static int hex2nib(char ch)
{
    if (ch >= '0' && ch <= '9') {
        return ch - '0';
    } else if (ch >= 'a' && ch <= 'f') {
        return 10 + (ch - 'a');
    } else if (ch >= 'A' && ch <= 'F') {
        return 10 + (ch - 'A');
    } else {
        return -1;
    }
}

static void qtest_log_timestamp(void)
{
    if (!qtest_log_fp || !qtest_opened) {
        return;
    }

    fprintf(qtest_log_fp, "[S +" FMT_timeval "] ", g_timer_elapsed(timer, NULL));
}

static void G_GNUC_PRINTF(1, 2) qtest_log_send(const char *fmt, ...)
{
    va_list ap;

    if (!qtest_log_fp || !qtest_opened) {
        return;
    }

    qtest_log_timestamp();

    va_start(ap, fmt);
    vfprintf(qtest_log_fp, fmt, ap);
    va_end(ap);
}

static void qtest_server_char_be_send(void *opaque, const char *str)
{
    size_t len = strlen(str);
    CharBackend* chr = (CharBackend *)opaque;
    qemu_chr_fe_write_all(chr, (uint8_t *)str, len);
    if (qtest_log_fp && qtest_opened) {
        fprintf(qtest_log_fp, "%s", str);
    }
}

static void qtest_send(CharBackend *chr, const char *str)
{
    qtest_log_timestamp();
    qtest_server_send(qtest_server_send_opaque, str);
}

void qtest_sendf(CharBackend *chr, const char *fmt, ...)
{
    va_list ap;
    gchar *buffer;

    va_start(ap, fmt);
    buffer = g_strdup_vprintf(fmt, ap);
    qtest_send(chr, buffer);
    g_free(buffer);
    va_end(ap);
}

static void qtest_irq_handler(void *opaque, int n, int level)
{
    qemu_irq old_irq = *(qemu_irq *)opaque;
    qemu_set_irq(old_irq, level);

    if (irq_levels[n] != level) {
        CharBackend *chr = &qtest->qtest_chr;
        irq_levels[n] = level;
        qtest_sendf(chr, "IRQ %s %d\n",
                    level ? "raise" : "lower", n);
    }
}

static bool (*process_command_cb)(CharBackend *chr, gchar **words);

void qtest_set_command_cb(bool (*pc_cb)(CharBackend *chr, gchar **words))
{
    assert(!process_command_cb);  /* Switch to a list if we need more than one */

    process_command_cb = pc_cb;
}

static void qtest_install_gpio_out_intercept(DeviceState *dev, const char *name, int n)
{
    qemu_irq *disconnected = g_new0(qemu_irq, 1);
    qemu_irq icpt = qemu_allocate_irq(qtest_irq_handler,
                                      disconnected, n);

    *disconnected = qdev_intercept_gpio_out(dev, icpt, name, n);
}

static void qtest_process_command(CharBackend *chr, gchar **words)
{
    const gchar *command;

    g_assert(words);

    command = words[0];

    if (qtest_log_fp) {
        int i;

        fprintf(qtest_log_fp, "[R +" FMT_timeval "]", g_timer_elapsed(timer, NULL));
        for (i = 0; words[i]; i++) {
            fprintf(qtest_log_fp, " %s", words[i]);
        }
        fprintf(qtest_log_fp, "\n");
    }

    g_assert(command);
    if (strcmp(words[0], "irq_intercept_out") == 0
        || strcmp(words[0], "irq_intercept_in") == 0) {
        DeviceState *dev;
        NamedGPIOList *ngl;
        bool is_named;
        bool is_outbound;
        bool interception_succeeded = false;

        g_assert(words[1]);
        is_named = words[2] != NULL;
        is_outbound = words[0][14] == 'o';
        dev = DEVICE(object_resolve_path(words[1], NULL));
        if (!dev) {
            qtest_send(chr, "FAIL Unknown device\n");
            return;
        }

        if (is_named && !is_outbound) {
            qtest_send(chr, "FAIL Interception of named in-GPIOs not yet supported\n");
            return;
        }

        if (irq_intercept_dev) {
            if (irq_intercept_dev != dev) {
                qtest_send(chr, "FAIL IRQ intercept already enabled\n");
            } else {
                qtest_send(chr, "OK\n");
            }
            return;
        }

        QLIST_FOREACH(ngl, &dev->gpios, node) {
            /* We don't support inbound interception of named GPIOs yet */
            if (is_outbound) {
                /* NULL is valid and matchable, for "unnamed GPIO" */
                if (g_strcmp0(ngl->name, words[2]) == 0) {
                    int i;
                    for (i = 0; i < ngl->num_out; ++i) {
                        qtest_install_gpio_out_intercept(dev, ngl->name, i);
                    }
                    interception_succeeded = true;
                }
            } else {
                qemu_irq_intercept_in(ngl->in, qtest_irq_handler,
                                      ngl->num_in);
                interception_succeeded = true;
            }
        }

        if (interception_succeeded) {
            irq_intercept_dev = dev;
            qtest_send(chr, "OK\n");
        } else {
            qtest_send(chr, "FAIL No intercepts installed\n");
        }
    } else if (strcmp(words[0], "set_irq_in") == 0) {
        DeviceState *dev;
        qemu_irq irq;
        char *name;
        int ret;
        int num;
        int level;

        g_assert(words[1] && words[2] && words[3] && words[4]);

        dev = DEVICE(object_resolve_path(words[1], NULL));
        if (!dev) {
            qtest_send(chr, "FAIL Unknown device\n");
            return;
        }

        if (strcmp(words[2], "unnamed-gpio-in") == 0) {
            name = NULL;
        } else {
            name = words[2];
        }

        ret = qemu_strtoi(words[3], NULL, 0, &num);
        g_assert(!ret);
        ret = qemu_strtoi(words[4], NULL, 0, &level);
        g_assert(!ret);

        irq = qdev_get_gpio_in_named(dev, name, num);

        qemu_set_irq(irq, level);
        qtest_send(chr, "OK\n");
    } else if (strcmp(words[0], "outb") == 0 ||
               strcmp(words[0], "outw") == 0 ||
               strcmp(words[0], "outl") == 0) {
        unsigned long addr;
        unsigned long value;
        int ret;

        g_assert(words[1] && words[2]);
        ret = qemu_strtoul(words[1], NULL, 0, &addr);
        g_assert(ret == 0);
        ret = qemu_strtoul(words[2], NULL, 0, &value);
        g_assert(ret == 0);
        g_assert(addr <= 0xffff);

        if (words[0][3] == 'b') {
            cpu_outb(addr, value);
        } else if (words[0][3] == 'w') {
            cpu_outw(addr, value);
        } else if (words[0][3] == 'l') {
            cpu_outl(addr, value);
        }
        qtest_send(chr, "OK\n");
    } else if (strcmp(words[0], "inb") == 0 ||
        strcmp(words[0], "inw") == 0 ||
        strcmp(words[0], "inl") == 0) {
        unsigned long addr;
        uint32_t value = -1U;
        int ret;

        g_assert(words[1]);
        ret = qemu_strtoul(words[1], NULL, 0, &addr);
        g_assert(ret == 0);
        g_assert(addr <= 0xffff);

        if (words[0][2] == 'b') {
            value = cpu_inb(addr);
        } else if (words[0][2] == 'w') {
            value = cpu_inw(addr);
        } else if (words[0][2] == 'l') {
            value = cpu_inl(addr);
        }
        qtest_sendf(chr, "OK 0x%04x\n", value);
    } else if (strcmp(words[0], "writeb") == 0 ||
               strcmp(words[0], "writew") == 0 ||
               strcmp(words[0], "writel") == 0 ||
               strcmp(words[0], "writeq") == 0) {
        uint64_t addr;
        uint64_t value;
        int ret;

        g_assert(words[1] && words[2]);
        ret = qemu_strtou64(words[1], NULL, 0, &addr);
        g_assert(ret == 0);
        ret = qemu_strtou64(words[2], NULL, 0, &value);
        g_assert(ret == 0);

        if (words[0][5] == 'b') {
            uint8_t data = value;
            address_space_write(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED,
                                &data, 1);
        } else if (words[0][5] == 'w') {
            uint16_t data = value;
            tswap16s(&data);
            address_space_write(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED,
                                &data, 2);
        } else if (words[0][5] == 'l') {
            uint32_t data = value;
            tswap32s(&data);
            address_space_write(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED,
                                &data, 4);
        } else if (words[0][5] == 'q') {
            uint64_t data = value;
            tswap64s(&data);
            address_space_write(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED,
                                &data, 8);
        }
        qtest_send(chr, "OK\n");
    } else if (strcmp(words[0], "readb") == 0 ||
               strcmp(words[0], "readw") == 0 ||
               strcmp(words[0], "readl") == 0 ||
               strcmp(words[0], "readq") == 0) {
        uint64_t addr;
        uint64_t value = UINT64_C(-1);
        int ret;

        g_assert(words[1]);
        ret = qemu_strtou64(words[1], NULL, 0, &addr);
        g_assert(ret == 0);

        if (words[0][4] == 'b') {
            uint8_t data;
            address_space_read(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED,
                               &data, 1);
            value = data;
        } else if (words[0][4] == 'w') {
            uint16_t data;
            address_space_read(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED,
                               &data, 2);
            value = tswap16(data);
        } else if (words[0][4] == 'l') {
            uint32_t data;
            address_space_read(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED,
                               &data, 4);
            value = tswap32(data);
        } else if (words[0][4] == 'q') {
            address_space_read(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED,
                               &value, 8);
            tswap64s(&value);
        }
        qtest_sendf(chr, "OK 0x%016" PRIx64 "\n", value);
    } else if (strcmp(words[0], "read") == 0) {
        g_autoptr(GString) enc = NULL;
        uint64_t addr, len;
        uint8_t *data;
        int ret;

        g_assert(words[1] && words[2]);
        ret = qemu_strtou64(words[1], NULL, 0, &addr);
        g_assert(ret == 0);
        ret = qemu_strtou64(words[2], NULL, 0, &len);
        g_assert(ret == 0);
        /* We'd send garbage to libqtest if len is 0 */
        g_assert(len);

        data = g_malloc(len);
        address_space_read(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED, data,
                           len);

        enc = qemu_hexdump_line(NULL, data, len, 0, 0);

        qtest_sendf(chr, "OK 0x%s\n", enc->str);

        g_free(data);
    } else if (strcmp(words[0], "b64read") == 0) {
        uint64_t addr, len;
        uint8_t *data;
        gchar *b64_data;
        int ret;

        g_assert(words[1] && words[2]);
        ret = qemu_strtou64(words[1], NULL, 0, &addr);
        g_assert(ret == 0);
        ret = qemu_strtou64(words[2], NULL, 0, &len);
        g_assert(ret == 0);

        data = g_malloc(len);
        address_space_read(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED, data,
                           len);
        b64_data = g_base64_encode(data, len);
        qtest_sendf(chr, "OK %s\n", b64_data);

        g_free(data);
        g_free(b64_data);
    } else if (strcmp(words[0], "write") == 0) {
        uint64_t addr, len, i;
        uint8_t *data;
        size_t data_len;
        int ret;

        g_assert(words[1] && words[2] && words[3]);
        ret = qemu_strtou64(words[1], NULL, 0, &addr);
        g_assert(ret == 0);
        ret = qemu_strtou64(words[2], NULL, 0, &len);
        g_assert(ret == 0);

        data_len = strlen(words[3]);
        if (data_len < 3) {
            qtest_send(chr, "ERR invalid argument size\n");
            return;
        }

        data = g_malloc(len);
        for (i = 0; i < len; i++) {
            if ((i * 2 + 4) <= data_len) {
                data[i] = hex2nib(words[3][i * 2 + 2]) << 4;
                data[i] |= hex2nib(words[3][i * 2 + 3]);
            } else {
                data[i] = 0;
            }
        }
        address_space_write(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED, data,
                            len);
        g_free(data);

        qtest_send(chr, "OK\n");
    } else if (strcmp(words[0], "memset") == 0) {
        uint64_t addr, len;
        uint8_t *data;
        unsigned long pattern;
        int ret;

        g_assert(words[1] && words[2] && words[3]);
        ret = qemu_strtou64(words[1], NULL, 0, &addr);
        g_assert(ret == 0);
        ret = qemu_strtou64(words[2], NULL, 0, &len);
        g_assert(ret == 0);
        ret = qemu_strtoul(words[3], NULL, 0, &pattern);
        g_assert(ret == 0);

        if (len) {
            data = g_malloc(len);
            memset(data, pattern, len);
            address_space_write(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED,
                                data, len);
            g_free(data);
        }

        qtest_send(chr, "OK\n");
    }  else if (strcmp(words[0], "b64write") == 0) {
        uint64_t addr, len;
        uint8_t *data;
        size_t data_len;
        gsize out_len;
        int ret;

        g_assert(words[1] && words[2] && words[3]);
        ret = qemu_strtou64(words[1], NULL, 0, &addr);
        g_assert(ret == 0);
        ret = qemu_strtou64(words[2], NULL, 0, &len);
        g_assert(ret == 0);

        data_len = strlen(words[3]);
        if (data_len < 3) {
            qtest_send(chr, "ERR invalid argument size\n");
            return;
        }

        data = g_base64_decode_inplace(words[3], &out_len);
        if (out_len != len) {
            qtest_log_send("b64write: data length mismatch (told %"PRIu64", "
                           "found %zu)\n",
                           len, out_len);
            out_len = MIN(out_len, len);
        }

        address_space_write(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED, data,
                            len);

        qtest_send(chr, "OK\n");
    } else if (strcmp(words[0], "endianness") == 0) {
        if (target_words_bigendian()) {
            qtest_sendf(chr, "OK big\n");
        } else {
            qtest_sendf(chr, "OK little\n");
        }
    } else if (qtest_enabled() && strcmp(words[0], "clock_step") == 0) {
        int64_t old_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
        int64_t ns, new_ns;

        if (words[1]) {
            int ret = qemu_strtoi64(words[1], NULL, 0, &ns);
            g_assert(ret == 0);
        } else {
            ns = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
                                            QEMU_TIMER_ATTR_ALL);
            if (ns < 0) {
                qtest_send(chr, "FAIL "
                           "cannot advance clock to the next deadline "
                           "because there is no pending deadline\n");
                return;
            }
        }
        new_ns = qemu_clock_advance_virtual_time(old_ns + ns);
        if (new_ns > old_ns) {
            qtest_sendf(chr, "OK %"PRIi64"\n", new_ns);
        } else {
            qtest_sendf(chr, "FAIL could not advance time\n");
        }
    } else if (strcmp(words[0], "module_load") == 0) {
        Error *local_err = NULL;
        int rv;
        g_assert(words[1] && words[2]);

        rv = module_load(words[1], words[2], &local_err);
        if (rv > 0) {
            qtest_sendf(chr, "OK\n");
        } else {
            if (rv < 0) {
                error_report_err(local_err);
            }
            qtest_sendf(chr, "FAIL\n");
        }
    } else if (qtest_enabled() && strcmp(words[0], "clock_set") == 0) {
        int64_t ns, new_ns;
        int ret;

        g_assert(words[1]);
        ret = qemu_strtoi64(words[1], NULL, 0, &ns);
        g_assert(ret == 0);
        new_ns = qemu_clock_advance_virtual_time(ns);
        qtest_sendf(chr, "%s %"PRIi64"\n",
                    new_ns == ns ? "OK" : "FAIL", new_ns);
    } else if (process_command_cb && process_command_cb(chr, words)) {
        /* Command got consumed by the callback handler */
    } else {
        qtest_sendf(chr, "FAIL Unknown command '%s'\n", words[0]);
    }
}

/*
 * Process as much of @inbuf as we can in newline terminated chunks.
 * Remove the processed commands from @inbuf as we go.
 */
static void qtest_process_inbuf(CharBackend *chr, GString *inbuf)
{
    char *end;

    while ((end = strchr(inbuf->str, '\n')) != NULL) {
        size_t len = end - inbuf->str;
        g_autofree char *cmd = g_strndup(inbuf->str, len);
        g_auto(GStrv) words = g_strsplit(cmd, " ", 0);

        g_string_erase(inbuf, 0, len + 1);
        qtest_process_command(chr, words);
    }
}

static void qtest_read(void *opaque, const uint8_t *buf, int size)
{
    CharBackend *chr = opaque;

    g_string_append_len(inbuf, (const gchar *)buf, size);
    qtest_process_inbuf(chr, inbuf);
}

static int qtest_can_read(void *opaque)
{
    return 1024;
}

static void qtest_event(void *opaque, QEMUChrEvent event)
{
    int i;

    switch (event) {
    case CHR_EVENT_OPENED:
        /*
         * We used to call qemu_system_reset() here, hoping we could
         * use the same process for multiple tests that way.  Never
         * used.  Injects an extra reset even when it's not used, and
         * that can mess up tests, e.g. -boot once.
         */
        for (i = 0; i < ARRAY_SIZE(irq_levels); i++) {
            irq_levels[i] = 0;
        }

        g_clear_pointer(&timer, g_timer_destroy);
        timer = g_timer_new();
        qtest_opened = true;
        if (qtest_log_fp) {
            fprintf(qtest_log_fp, "[I " FMT_timeval "] OPENED\n", g_timer_elapsed(timer, NULL));
        }
        break;
    case CHR_EVENT_CLOSED:
        qtest_opened = false;
        if (qtest_log_fp) {
            fprintf(qtest_log_fp, "[I +" FMT_timeval "] CLOSED\n", g_timer_elapsed(timer, NULL));
        }
        g_clear_pointer(&timer, g_timer_destroy);
        break;
    default:
        break;
    }
}

void qtest_server_init(const char *qtest_chrdev, const char *qtest_log, Error **errp)
{
    ERRP_GUARD();
    Chardev *chr;
    Object *qobj;

    chr = qemu_chr_new("qtest", qtest_chrdev, NULL);
    if (chr == NULL) {
        error_setg(errp, "Failed to initialize device for qtest: \"%s\"",
                   qtest_chrdev);
        return;
    }

    qobj = object_new(TYPE_QTEST);
    object_property_set_str(qobj, "chardev", chr->label, &error_abort);
    if (qtest_log) {
        object_property_set_str(qobj, "log", qtest_log, &error_abort);
    }
    object_property_add_child(qdev_get_machine(), "qtest", qobj);
    user_creatable_complete(USER_CREATABLE(qobj), errp);
    if (*errp) {
        object_unparent(qobj);
    }
    object_unref(OBJECT(chr));
    object_unref(qobj);
}

static bool qtest_server_start(QTest *q, Error **errp)
{
    Chardev *chr = q->chr;
    const char *qtest_log = q->log;

    if (qtest_log) {
        if (strcmp(qtest_log, "none") != 0) {
            qtest_log_fp = fopen(qtest_log, "w+");
        }
    } else {
        qtest_log_fp = stderr;
    }

    if (!qemu_chr_fe_init(&q->qtest_chr, chr, errp)) {
        return false;
    }
    qemu_chr_fe_set_handlers(&q->qtest_chr, qtest_can_read, qtest_read,
                             qtest_event, NULL, &q->qtest_chr, NULL, true);
    qemu_chr_fe_set_echo(&q->qtest_chr, true);

    inbuf = g_string_new("");

    if (!qtest_server_send) {
        qtest_server_set_send_handler(qtest_server_char_be_send, &q->qtest_chr);
    }
    qtest = q;
    return true;
}

void qtest_server_set_send_handler(void (*send)(void*, const char*),
                                   void *opaque)
{
    qtest_server_send = send;
    qtest_server_send_opaque = opaque;
}

bool qtest_driver(void)
{
    return qtest && qtest->qtest_chr.chr != NULL;
}

void qtest_server_inproc_recv(void *dummy, const char *buf)
{
    static GString *gstr;
    if (!gstr) {
        gstr = g_string_new(NULL);
    }
    g_string_append(gstr, buf);
    if (gstr->str[gstr->len - 1] == '\n') {
        qtest_process_inbuf(NULL, gstr);
        g_string_truncate(gstr, 0);
    }
}

static void qtest_complete(UserCreatable *uc, Error **errp)
{
    QTest *q = QTEST(uc);
    if (qtest) {
        error_setg(errp, "Only one instance of qtest can be created");
        return;
    }
    if (!q->chr_name) {
        error_setg(errp, "No backend specified");
        return;
    }

    if (OBJECT(uc)->parent != qdev_get_machine()) {
        q->has_machine_link = true;
        object_property_add_const_link(qdev_get_machine(), "qtest", OBJECT(uc));
    } else {
        /* -qtest was used.  */
    }

    qtest_server_start(q, errp);
}

static void qtest_unparent(Object *obj)
{
    QTest *q = QTEST(obj);

    if (qtest == q) {
        qemu_chr_fe_disconnect(&q->qtest_chr);
        assert(!qtest_opened);
        qemu_chr_fe_deinit(&q->qtest_chr, false);
        if (qtest_log_fp) {
            fclose(qtest_log_fp);
            qtest_log_fp = NULL;
        }
        qtest = NULL;
    }

    if (q->has_machine_link) {
        object_property_del(qdev_get_machine(), "qtest");
        q->has_machine_link = false;
    }
}

static void qtest_set_log(Object *obj, const char *value, Error **errp)
{
    QTest *q = QTEST(obj);

    if (qtest == q) {
        error_setg(errp, "Property 'log' can not be set now");
    } else {
        g_free(q->log);
        q->log = g_strdup(value);
    }
}

static char *qtest_get_log(Object *obj, Error **errp)
{
    QTest *q = QTEST(obj);

    return g_strdup(q->log);
}

static void qtest_set_chardev(Object *obj, const char *value, Error **errp)
{
    QTest *q = QTEST(obj);
    Chardev *chr;

    if (qtest == q) {
        error_setg(errp, "Property 'chardev' can not be set now");
        return;
    }

    chr = qemu_chr_find(value);
    if (!chr) {
        error_setg(errp, "Cannot find character device '%s'", value);
        return;
    }

    g_free(q->chr_name);
    q->chr_name = g_strdup(value);

    if (q->chr) {
        object_unref(q->chr);
    }
    q->chr = chr;
    object_ref(chr);
}

static char *qtest_get_chardev(Object *obj, Error **errp)
{
    QTest *q = QTEST(obj);

    return g_strdup(q->chr_name);
}

static void qtest_class_init(ObjectClass *oc, void *data)
{
    UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);

    oc->unparent = qtest_unparent;
    ucc->complete = qtest_complete;

    object_class_property_add_str(oc, "chardev",
                                  qtest_get_chardev, qtest_set_chardev);
    object_class_property_add_str(oc, "log",
                                  qtest_get_log, qtest_set_log);
}

static const TypeInfo qtest_info = {
    .name = TYPE_QTEST,
    .parent = TYPE_OBJECT,
    .class_init = qtest_class_init,
    .instance_size = sizeof(QTest),
    .interfaces = (InterfaceInfo[]) {
        { TYPE_USER_CREATABLE },
        { }
    }
};

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

type_init(register_types);
