/*
 * QEMU I/O channel test helpers
 *
 * Copyright (c) 2015 Red Hat, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 *
 */

#include "qemu/osdep.h"
#include "io-channel-helpers.h"
#include "qemu/iov.h"

struct QIOChannelTest {
    QIOChannel *src;
    QIOChannel *dst;
    size_t len;
    size_t niov;
    char *input;
    struct iovec *inputv;
    char *output;
    struct iovec *outputv;
    Error *writeerr;
    Error *readerr;
};


/* This thread sends all data using iovecs */
static gpointer test_io_thread_writer(gpointer opaque)
{
    QIOChannelTest *data = opaque;

    qio_channel_writev_all(data->src,
                           data->inputv,
                           data->niov,
                           &data->writeerr);

    return NULL;
}


/* This thread receives all data using iovecs */
static gpointer test_io_thread_reader(gpointer opaque)
{
    QIOChannelTest *data = opaque;

    qio_channel_readv_all(data->dst,
                          data->outputv,
                          data->niov,
                          &data->readerr);

    return NULL;
}


QIOChannelTest *qio_channel_test_new(void)
{
    QIOChannelTest *data = g_new0(QIOChannelTest, 1);
    size_t i;
    size_t offset;


    /* We'll send 1 MB of data */
#define CHUNK_COUNT 250
#define CHUNK_LEN 4194

    data->len = CHUNK_COUNT * CHUNK_LEN;
    data->input = g_new0(char, data->len);
    data->output = g_new0(gchar, data->len);

    /* Fill input with a pattern */
    for (i = 0; i < data->len; i += CHUNK_LEN) {
        memset(data->input + i, (i / CHUNK_LEN), CHUNK_LEN);
    }

    /* We'll split the data across a bunch of IO vecs */
    data->niov = CHUNK_COUNT;
    data->inputv = g_new0(struct iovec, data->niov);
    data->outputv = g_new0(struct iovec, data->niov);

    for (i = 0, offset = 0; i < data->niov; i++, offset += CHUNK_LEN) {
        data->inputv[i].iov_base = data->input + offset;
        data->outputv[i].iov_base = data->output + offset;
        data->inputv[i].iov_len = CHUNK_LEN;
        data->outputv[i].iov_len = CHUNK_LEN;
    }

    return data;
}

void qio_channel_test_run_threads(QIOChannelTest *test,
                                  bool blocking,
                                  QIOChannel *src,
                                  QIOChannel *dst)
{
    GThread *reader, *writer;

    test->src = src;
    test->dst = dst;

    qio_channel_set_blocking(test->dst, blocking, NULL);
    qio_channel_set_blocking(test->src, blocking, NULL);

    reader = g_thread_new("reader",
                          test_io_thread_reader,
                          test);
    writer = g_thread_new("writer",
                          test_io_thread_writer,
                          test);

    g_thread_join(reader);
    g_thread_join(writer);

    test->dst = test->src = NULL;
}


void qio_channel_test_run_writer(QIOChannelTest *test,
                                 QIOChannel *src)
{
    test->src = src;
    test_io_thread_writer(test);
    test->src = NULL;
}


void qio_channel_test_run_reader(QIOChannelTest *test,
                                 QIOChannel *dst)
{
    test->dst = dst;
    test_io_thread_reader(test);
    test->dst = NULL;
}


void qio_channel_test_validate(QIOChannelTest *test)
{
    g_assert(test->readerr == NULL);
    g_assert(test->writeerr == NULL);
    g_assert_cmpint(memcmp(test->input,
                           test->output,
                           test->len), ==, 0);

    g_free(test->inputv);
    g_free(test->outputv);
    g_free(test->input);
    g_free(test->output);
    g_free(test);
}
