/*
 * QTest migration helpers
 *
 * Copyright (c) 2016-2018 Red Hat, Inc. and/or its affiliates
 *   based on the vhost-user-test.c that is:
 *      Copyright (c) 2014 Virtual Open Systems Sarl.
 *
 * 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 "qemu/ctype.h"
#include "qapi/qmp/qjson.h"
#include "qapi/qapi-visit-sockets.h"
#include "qapi/qobject-input-visitor.h"
#include "qapi/error.h"
#include "qapi/qmp/qlist.h"
#include "qemu/cutils.h"
#include "qemu/memalign.h"

#include "migration-helpers.h"

/*
 * Number of seconds we wait when looking for migration
 * status changes, to avoid test suite hanging forever
 * when things go wrong. Needs to be higher enough to
 * avoid false positives on loaded hosts.
 */
#define MIGRATION_STATUS_WAIT_TIMEOUT 120

static char *SocketAddress_to_str(SocketAddress *addr)
{
    switch (addr->type) {
    case SOCKET_ADDRESS_TYPE_INET:
        return g_strdup_printf("tcp:%s:%s",
                               addr->u.inet.host,
                               addr->u.inet.port);
    case SOCKET_ADDRESS_TYPE_UNIX:
        return g_strdup_printf("unix:%s",
                               addr->u.q_unix.path);
    case SOCKET_ADDRESS_TYPE_FD:
        return g_strdup_printf("fd:%s", addr->u.fd.str);
    case SOCKET_ADDRESS_TYPE_VSOCK:
        return g_strdup_printf("vsock:%s:%s",
                               addr->u.vsock.cid,
                               addr->u.vsock.port);
    default:
        return g_strdup("unknown address type");
    }
}

static QDict *SocketAddress_to_qdict(SocketAddress *addr)
{
    QDict *dict = qdict_new();

    switch (addr->type) {
    case SOCKET_ADDRESS_TYPE_INET:
        qdict_put_str(dict, "type", "inet");
        qdict_put_str(dict, "host", addr->u.inet.host);
        qdict_put_str(dict, "port", addr->u.inet.port);
        break;
    case SOCKET_ADDRESS_TYPE_UNIX:
        qdict_put_str(dict, "type", "unix");
        qdict_put_str(dict, "path", addr->u.q_unix.path);
        break;
    case SOCKET_ADDRESS_TYPE_FD:
        qdict_put_str(dict, "type", "fd");
        qdict_put_str(dict, "str", addr->u.fd.str);
        break;
    case SOCKET_ADDRESS_TYPE_VSOCK:
        qdict_put_str(dict, "type", "vsock");
        qdict_put_str(dict, "cid", addr->u.vsock.cid);
        qdict_put_str(dict, "port", addr->u.vsock.port);
        break;
    default:
        g_assert_not_reached();
        break;
    }

    return dict;
}

static SocketAddress *migrate_get_socket_address(QTestState *who)
{
    QDict *rsp;
    SocketAddressList *addrs;
    SocketAddress *addr;
    Visitor *iv = NULL;
    QObject *object;

    rsp = migrate_query(who);
    object = qdict_get(rsp, "socket-address");

    iv = qobject_input_visitor_new(object);
    visit_type_SocketAddressList(iv, NULL, &addrs, &error_abort);
    addr = addrs->value;
    visit_free(iv);

    qobject_unref(rsp);
    return addr;
}

static char *
migrate_get_connect_uri(QTestState *who)
{
    SocketAddress *addrs;
    char *connect_uri;

    addrs = migrate_get_socket_address(who);
    connect_uri = SocketAddress_to_str(addrs);

    qapi_free_SocketAddress(addrs);
    return connect_uri;
}

static QDict *
migrate_get_connect_qdict(QTestState *who)
{
    SocketAddress *addrs;
    QDict *connect_qdict;

    addrs = migrate_get_socket_address(who);
    connect_qdict = SocketAddress_to_qdict(addrs);

    qapi_free_SocketAddress(addrs);
    return connect_qdict;
}

static void migrate_set_ports(QTestState *to, QList *channel_list)
{
    QDict *addr;
    QListEntry *entry;
    const char *addr_port = NULL;

    addr = migrate_get_connect_qdict(to);

    QLIST_FOREACH_ENTRY(channel_list, entry) {
        QDict *channel = qobject_to(QDict, qlist_entry_obj(entry));
        QDict *addrdict = qdict_get_qdict(channel, "addr");

        if (qdict_haskey(addrdict, "port") &&
            qdict_haskey(addr, "port") &&
            (strcmp(qdict_get_str(addrdict, "port"), "0") == 0)) {
                addr_port = qdict_get_str(addr, "port");
                qdict_put_str(addrdict, "port", g_strdup(addr_port));
        }
    }

    qobject_unref(addr);
}

bool migrate_watch_for_events(QTestState *who, const char *name,
                              QDict *event, void *opaque)
{
    QTestMigrationState *state = opaque;

    if (g_str_equal(name, "STOP")) {
        state->stop_seen = true;
        return true;
    } else if (g_str_equal(name, "SUSPEND")) {
        state->suspend_seen = true;
        return true;
    } else if (g_str_equal(name, "RESUME")) {
        state->resume_seen = true;
        return true;
    }

    return false;
}

void migrate_qmp_fail(QTestState *who, const char *uri,
                      const char *channels, const char *fmt, ...)
{
    va_list ap;
    QDict *args, *err;

    va_start(ap, fmt);
    args = qdict_from_vjsonf_nofail(fmt, ap);
    va_end(ap);

    g_assert(!qdict_haskey(args, "uri"));
    if (uri) {
        qdict_put_str(args, "uri", uri);
    }

    g_assert(!qdict_haskey(args, "channels"));
    if (channels) {
        QObject *channels_obj = qobject_from_json(channels, &error_abort);
        qdict_put_obj(args, "channels", channels_obj);
    }

    err = qtest_qmp_assert_failure_ref(
        who, "{ 'execute': 'migrate', 'arguments': %p}", args);

    g_assert(qdict_haskey(err, "desc"));

    qobject_unref(err);
}

/*
 * Send QMP command "migrate".
 * Arguments are built from @fmt... (formatted like
 * qobject_from_jsonf_nofail()) with "uri": @uri spliced in.
 */
void migrate_qmp(QTestState *who, QTestState *to, const char *uri,
                 const char *channels, const char *fmt, ...)
{
    va_list ap;
    QDict *args;
    g_autofree char *connect_uri = NULL;

    va_start(ap, fmt);
    args = qdict_from_vjsonf_nofail(fmt, ap);
    va_end(ap);

    g_assert(!qdict_haskey(args, "uri"));
    if (uri) {
        qdict_put_str(args, "uri", uri);
    } else if (!channels) {
        connect_uri = migrate_get_connect_uri(to);
        qdict_put_str(args, "uri", connect_uri);
    }

    g_assert(!qdict_haskey(args, "channels"));
    if (channels) {
        QObject *channels_obj = qobject_from_json(channels, &error_abort);
        QList *channel_list = qobject_to(QList, channels_obj);
        migrate_set_ports(to, channel_list);
        qdict_put_obj(args, "channels", channels_obj);
    }

    qtest_qmp_assert_success(who,
                             "{ 'execute': 'migrate', 'arguments': %p}", args);
}

void migrate_set_capability(QTestState *who, const char *capability,
                            bool value)
{
    qtest_qmp_assert_success(who,
                             "{ 'execute': 'migrate-set-capabilities',"
                             "'arguments': { "
                             "'capabilities': [ { "
                             "'capability': %s, 'state': %i } ] } }",
                             capability, value);
}

void migrate_incoming_qmp(QTestState *to, const char *uri, const char *fmt, ...)
{
    va_list ap;
    QDict *args, *rsp, *data;

    va_start(ap, fmt);
    args = qdict_from_vjsonf_nofail(fmt, ap);
    va_end(ap);

    g_assert(!qdict_haskey(args, "uri"));
    qdict_put_str(args, "uri", uri);

    migrate_set_capability(to, "events", true);

    rsp = qtest_qmp(to, "{ 'execute': 'migrate-incoming', 'arguments': %p}",
                    args);

    if (!qdict_haskey(rsp, "return")) {
        g_autoptr(GString) s = qobject_to_json_pretty(QOBJECT(rsp), true);
        g_test_message("%s", s->str);
    }

    g_assert(qdict_haskey(rsp, "return"));
    qobject_unref(rsp);

    rsp = qtest_qmp_eventwait_ref(to, "MIGRATION");
    g_assert(qdict_haskey(rsp, "data"));

    data = qdict_get_qdict(rsp, "data");
    g_assert(qdict_haskey(data, "status"));
    g_assert_cmpstr(qdict_get_str(data, "status"), ==, "setup");

    qobject_unref(rsp);
}

/*
 * Note: caller is responsible to free the returned object via
 * qobject_unref() after use
 */
QDict *migrate_query(QTestState *who)
{
    return qtest_qmp_assert_success_ref(who, "{ 'execute': 'query-migrate' }");
}

QDict *migrate_query_not_failed(QTestState *who)
{
    const char *status;
    QDict *rsp = migrate_query(who);
    status = qdict_get_str(rsp, "status");
    if (g_str_equal(status, "failed")) {
        g_printerr("query-migrate shows failed migration: %s\n",
                   qdict_get_str(rsp, "error-desc"));
    }
    g_assert(!g_str_equal(status, "failed"));
    return rsp;
}

/*
 * Note: caller is responsible to free the returned object via
 * g_free() after use
 */
static gchar *migrate_query_status(QTestState *who)
{
    QDict *rsp_return = migrate_query(who);
    gchar *status = g_strdup(qdict_get_str(rsp_return, "status"));

    g_assert(status);
    qobject_unref(rsp_return);

    return status;
}

static bool check_migration_status(QTestState *who, const char *goal,
                                   const char **ungoals)
{
    bool ready;
    char *current_status;
    const char **ungoal;

    current_status = migrate_query_status(who);
    ready = strcmp(current_status, goal) == 0;
    if (!ungoals) {
        g_assert_cmpstr(current_status, !=, "failed");
        /*
         * If looking for a state other than completed,
         * completion of migration would cause the test to
         * hang.
         */
        if (strcmp(goal, "completed") != 0) {
            g_assert_cmpstr(current_status, !=, "completed");
        }
    } else {
        for (ungoal = ungoals; *ungoal; ungoal++) {
            g_assert_cmpstr(current_status, !=,  *ungoal);
        }
    }
    g_free(current_status);
    return ready;
}

void wait_for_migration_status(QTestState *who,
                               const char *goal, const char **ungoals)
{
    g_test_timer_start();
    while (!check_migration_status(who, goal, ungoals)) {
        usleep(1000);

        g_assert(g_test_timer_elapsed() < MIGRATION_STATUS_WAIT_TIMEOUT);
    }
}

void wait_for_migration_complete(QTestState *who)
{
    wait_for_migration_status(who, "completed", NULL);
}

void wait_for_migration_fail(QTestState *from, bool allow_active)
{
    g_test_timer_start();
    QDict *rsp_return;
    char *status;
    bool failed;

    do {
        status = migrate_query_status(from);
        bool result = !strcmp(status, "setup") || !strcmp(status, "failed") ||
            (allow_active && !strcmp(status, "active"));
        if (!result) {
            fprintf(stderr, "%s: unexpected status status=%s allow_active=%d\n",
                    __func__, status, allow_active);
        }
        g_assert(result);
        failed = !strcmp(status, "failed");
        g_free(status);

        g_assert(g_test_timer_elapsed() < MIGRATION_STATUS_WAIT_TIMEOUT);
    } while (!failed);

    /* Is the machine currently running? */
    rsp_return = qtest_qmp_assert_success_ref(from,
                                              "{ 'execute': 'query-status' }");
    g_assert(qdict_haskey(rsp_return, "running"));
    g_assert(qdict_get_bool(rsp_return, "running"));
    qobject_unref(rsp_return);
}

char *find_common_machine_version(const char *mtype, const char *var1,
                                  const char *var2)
{
    g_autofree char *type1 = qtest_resolve_machine_alias(var1, mtype);
    g_autofree char *type2 = qtest_resolve_machine_alias(var2, mtype);

    g_assert(type1 && type2);

    if (g_str_equal(type1, type2)) {
        /* either can be used */
        return g_strdup(type1);
    }

    if (qtest_has_machine_with_env(var2, type1)) {
        return g_strdup(type1);
    }

    if (qtest_has_machine_with_env(var1, type2)) {
        return g_strdup(type2);
    }

    g_test_message("No common machine version for machine type '%s' between "
                   "binaries %s and %s", mtype, getenv(var1), getenv(var2));
    g_assert_not_reached();
}

char *resolve_machine_version(const char *alias, const char *var1,
                              const char *var2)
{
    const char *mname = g_getenv("QTEST_QEMU_MACHINE_TYPE");
    g_autofree char *machine_name = NULL;

    if (mname) {
        const char *dash = strrchr(mname, '-');
        const char *dot = strrchr(mname, '.');

        machine_name = g_strdup(mname);

        if (dash && dot) {
            assert(qtest_has_machine(machine_name));
            return g_steal_pointer(&machine_name);
        }
        /* else: probably an alias, let it be resolved below */
    } else {
        /* use the hardcoded alias */
        machine_name = g_strdup(alias);
    }

    return find_common_machine_version(machine_name, var1, var2);
}

typedef struct {
    char *name;
    void (*func)(void);
} MigrationTest;

static void migration_test_destroy(gpointer data)
{
    MigrationTest *test = (MigrationTest *)data;

    g_free(test->name);
    g_free(test);
}

static void migration_test_wrapper(const void *data)
{
    MigrationTest *test = (MigrationTest *)data;

    g_test_message("Running /%s%s", qtest_get_arch(), test->name);
    test->func();
}

void migration_test_add(const char *path, void (*fn)(void))
{
    MigrationTest *test = g_new0(MigrationTest, 1);

    test->func = fn;
    test->name = g_strdup(path);

    qtest_add_data_func_full(path, test, migration_test_wrapper,
                             migration_test_destroy);
}

#ifdef O_DIRECT
/*
 * Probe for O_DIRECT support on the filesystem. Since this is used
 * for tests, be conservative, if anything fails, assume it's
 * unsupported.
 */
bool probe_o_direct_support(const char *tmpfs)
{
    g_autofree char *filename = g_strdup_printf("%s/probe-o-direct", tmpfs);
    int fd, flags = O_CREAT | O_RDWR | O_TRUNC | O_DIRECT;
    void *buf;
    ssize_t ret, len;
    uint64_t offset;

    fd = open(filename, flags, 0660);
    if (fd < 0) {
        unlink(filename);
        return false;
    }

    /*
     * Using 1MB alignment as conservative choice to satisfy any
     * plausible architecture default page size, and/or filesystem
     * alignment restrictions.
     */
    len = 0x100000;
    offset = 0x100000;

    buf = qemu_try_memalign(len, len);
    g_assert(buf);

    ret = pwrite(fd, buf, len, offset);
    unlink(filename);
    g_free(buf);

    if (ret < 0) {
        return false;
    }

    return true;
}
#endif
