/*
 * QEMU dbus-vmstate
 *
 * Copyright (C) 2019 Red Hat Inc
 *
 * Authors:
 *  Marc-André Lureau <marcandre.lureau@redhat.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 "qemu/units.h"
#include "qemu/dbus.h"
#include "qemu/error-report.h"
#include "qapi/error.h"
#include "qom/object_interfaces.h"
#include "qapi/qmp/qerror.h"
#include "migration/vmstate.h"
#include "trace.h"
#include "qom/object.h"


#define TYPE_DBUS_VMSTATE "dbus-vmstate"
OBJECT_DECLARE_SIMPLE_TYPE(DBusVMState,
                           DBUS_VMSTATE)


struct DBusVMState {
    Object parent;

    GDBusConnection *bus;
    char *dbus_addr;
    char *id_list;

    uint32_t data_size;
    uint8_t *data;
};

static const GDBusPropertyInfo vmstate_property_info[] = {
    { -1, (char *) "Id", (char *) "s",
      G_DBUS_PROPERTY_INFO_FLAGS_READABLE, NULL },
};

static const GDBusPropertyInfo * const vmstate_property_info_pointers[] = {
    &vmstate_property_info[0],
    NULL
};

static const GDBusInterfaceInfo vmstate1_interface_info = {
    -1,
    (char *) "org.qemu.VMState1",
    (GDBusMethodInfo **) NULL,
    (GDBusSignalInfo **) NULL,
    (GDBusPropertyInfo **) &vmstate_property_info_pointers,
    NULL,
};

#define DBUS_VMSTATE_SIZE_LIMIT (1 * MiB)

static GHashTable *
get_id_list_set(DBusVMState *self)
{
    g_auto(GStrv) ids = NULL;
    g_autoptr(GHashTable) set = NULL;
    int i;

    if (!self->id_list) {
        return NULL;
    }

    ids = g_strsplit(self->id_list, ",", -1);
    set = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
    for (i = 0; ids[i]; i++) {
        g_hash_table_add(set, ids[i]);
        ids[i] = NULL;
    }

    return g_steal_pointer(&set);
}

static GHashTable *
dbus_get_proxies(DBusVMState *self, GError **err)
{
    g_autoptr(GHashTable) proxies = NULL;
    g_autoptr(GHashTable) ids = NULL;
    g_auto(GStrv) names = NULL;
    Error *error = NULL;
    size_t i;

    ids = get_id_list_set(self);
    proxies = g_hash_table_new_full(g_str_hash, g_str_equal,
                                    g_free, g_object_unref);

    names = qemu_dbus_get_queued_owners(self->bus, "org.qemu.VMState1", &error);
    if (!names) {
        g_set_error(err, G_IO_ERROR, G_IO_ERROR_FAILED, "%s",
                    error_get_pretty(error));
        error_free(error);
        return NULL;
    }

    for (i = 0; names[i]; i++) {
        g_autoptr(GDBusProxy) proxy = NULL;
        g_autoptr(GVariant) result = NULL;
        g_autofree char *id = NULL;
        size_t size;

        proxy = g_dbus_proxy_new_sync(self->bus, G_DBUS_PROXY_FLAGS_NONE,
                    (GDBusInterfaceInfo *) &vmstate1_interface_info,
                    names[i],
                    "/org/qemu/VMState1",
                    "org.qemu.VMState1",
                    NULL, err);
        if (!proxy) {
            return NULL;
        }

        result = g_dbus_proxy_get_cached_property(proxy, "Id");
        if (!result) {
            g_set_error_literal(err, G_IO_ERROR, G_IO_ERROR_FAILED,
                                "VMState Id property is missing.");
            return NULL;
        }

        id = g_variant_dup_string(result, &size);
        if (ids && !g_hash_table_remove(ids, id)) {
            g_clear_pointer(&id, g_free);
            g_clear_object(&proxy);
            continue;
        }
        if (size == 0 || size >= 256) {
            g_set_error(err, G_IO_ERROR, G_IO_ERROR_FAILED,
                        "VMState Id '%s' is invalid.", id);
            return NULL;
        }

        if (!g_hash_table_insert(proxies, id, proxy)) {
            g_set_error(err, G_IO_ERROR, G_IO_ERROR_FAILED,
                        "Duplicated VMState Id '%s'", id);
            return NULL;
        }
        id = NULL;
        proxy = NULL;

        g_clear_pointer(&result, g_variant_unref);
    }

    if (ids) {
        g_autofree char **left = NULL;

        left = (char **)g_hash_table_get_keys_as_array(ids, NULL);
        if (*left) {
            g_autofree char *leftids = g_strjoinv(",", left);
            g_set_error(err, G_IO_ERROR, G_IO_ERROR_FAILED,
                        "Required VMState Id are missing: %s", leftids);
            return NULL;
        }
    }

    return g_steal_pointer(&proxies);
}

static int
dbus_load_state_proxy(GDBusProxy *proxy, const uint8_t *data, size_t size)
{
    g_autoptr(GError) err = NULL;
    g_autoptr(GVariant) result = NULL;
    g_autoptr(GVariant) value = NULL;

    value = g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE,
                                      data, size, sizeof(char));
    result = g_dbus_proxy_call_sync(proxy, "Load",
                                    g_variant_new("(@ay)",
                                                  g_steal_pointer(&value)),
                                    G_DBUS_CALL_FLAGS_NO_AUTO_START,
                                    -1, NULL, &err);
    if (!result) {
        error_report("%s: Failed to Load: %s", __func__, err->message);
        return -1;
    }

    return 0;
}

static int dbus_vmstate_post_load(void *opaque, int version_id)
{
    DBusVMState *self = DBUS_VMSTATE(opaque);
    g_autoptr(GInputStream) m = NULL;
    g_autoptr(GDataInputStream) s = NULL;
    g_autoptr(GError) err = NULL;
    g_autoptr(GHashTable) proxies = NULL;
    uint32_t nelem;

    trace_dbus_vmstate_post_load(version_id);

    proxies = dbus_get_proxies(self, &err);
    if (!proxies) {
        error_report("%s: Failed to get proxies: %s", __func__, err->message);
        return -1;
    }

    m = g_memory_input_stream_new_from_data(self->data, self->data_size, NULL);
    s = g_data_input_stream_new(m);
    g_data_input_stream_set_byte_order(s, G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN);

    nelem = g_data_input_stream_read_uint32(s, NULL, &err);
    if (err) {
        goto error;
    }

    while (nelem > 0) {
        GDBusProxy *proxy = NULL;
        uint32_t len;
        gsize bytes_read, avail;
        char id[256];

        len = g_data_input_stream_read_uint32(s, NULL, &err);
        if (err) {
            goto error;
        }
        if (len >= 256) {
            error_report("%s: Invalid DBus vmstate proxy name %u",
                         __func__, len);
            return -1;
        }
        if (!g_input_stream_read_all(G_INPUT_STREAM(s), id, len,
                                     &bytes_read, NULL, &err)) {
            goto error;
        }
        if (bytes_read != len) {
            error_report("%s: Short read", __func__);
            return -1;
        }
        id[len] = 0;

        trace_dbus_vmstate_loading(id);

        proxy = g_hash_table_lookup(proxies, id);
        if (!proxy) {
            error_report("%s: Failed to find proxy Id '%s'", __func__, id);
            return -1;
        }

        len = g_data_input_stream_read_uint32(s, NULL, &err);
        avail = g_buffered_input_stream_get_available(
            G_BUFFERED_INPUT_STREAM(s));

        if (len > DBUS_VMSTATE_SIZE_LIMIT || len > avail) {
            error_report("%s: Invalid vmstate size: %u", __func__, len);
            return -1;
        }

        if (dbus_load_state_proxy(proxy,
                g_buffered_input_stream_peek_buffer(G_BUFFERED_INPUT_STREAM(s),
                                                    NULL),
                len) < 0) {
            error_report("%s: Failed to restore Id '%s'", __func__, id);
            return -1;
        }

        if (!g_seekable_seek(G_SEEKABLE(s), len, G_SEEK_CUR, NULL, &err)) {
            goto error;
        }

        nelem -= 1;
    }

    return 0;

error:
    error_report("%s: Failed to read from stream: %s", __func__, err->message);
    return -1;
}

static void
dbus_save_state_proxy(gpointer key,
                      gpointer value,
                      gpointer user_data)
{
    GDataOutputStream *s = user_data;
    const char *id = key;
    GDBusProxy *proxy = value;
    g_autoptr(GVariant) result = NULL;
    g_autoptr(GVariant) child = NULL;
    g_autoptr(GError) err = NULL;
    const uint8_t *data;
    gsize size;

    trace_dbus_vmstate_saving(id);

    result = g_dbus_proxy_call_sync(proxy, "Save",
                                    NULL, G_DBUS_CALL_FLAGS_NO_AUTO_START,
                                    -1, NULL, &err);
    if (!result) {
        error_report("%s: Failed to Save: %s", __func__, err->message);
        return;
    }

    child = g_variant_get_child_value(result, 0);
    data = g_variant_get_fixed_array(child, &size, sizeof(char));
    if (!data) {
        error_report("%s: Failed to Save: not a byte array", __func__);
        return;
    }
    if (size > DBUS_VMSTATE_SIZE_LIMIT) {
        error_report("%s: Too large vmstate data to save: %zu",
                     __func__, (size_t)size);
        return;
    }

    if (!g_data_output_stream_put_uint32(s, strlen(id), NULL, &err) ||
        !g_data_output_stream_put_string(s, id, NULL, &err) ||
        !g_data_output_stream_put_uint32(s, size, NULL, &err) ||
        !g_output_stream_write_all(G_OUTPUT_STREAM(s),
                                   data, size, NULL, NULL, &err)) {
        error_report("%s: Failed to write to stream: %s",
                     __func__, err->message);
    }
}

static int dbus_vmstate_pre_save(void *opaque)
{
    DBusVMState *self = DBUS_VMSTATE(opaque);
    g_autoptr(GOutputStream) m = NULL;
    g_autoptr(GDataOutputStream) s = NULL;
    g_autoptr(GHashTable) proxies = NULL;
    g_autoptr(GError) err = NULL;

    trace_dbus_vmstate_pre_save();

    proxies = dbus_get_proxies(self, &err);
    if (!proxies) {
        error_report("%s: Failed to get proxies: %s", __func__, err->message);
        return -1;
    }

    m = g_memory_output_stream_new_resizable();
    s = g_data_output_stream_new(m);
    g_data_output_stream_set_byte_order(s, G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN);

    if (!g_data_output_stream_put_uint32(s, g_hash_table_size(proxies),
                                         NULL, &err)) {
        error_report("%s: Failed to write to stream: %s",
                     __func__, err->message);
        return -1;
    }

    g_hash_table_foreach(proxies, dbus_save_state_proxy, s);

    if (g_memory_output_stream_get_size(G_MEMORY_OUTPUT_STREAM(m))
        > UINT32_MAX) {
        error_report("%s: DBus vmstate buffer is too large", __func__);
        return -1;
    }

    if (!g_output_stream_close(G_OUTPUT_STREAM(m), NULL, &err)) {
        error_report("%s: Failed to close stream: %s", __func__, err->message);
        return -1;
    }

    g_free(self->data);
    self->data_size =
        g_memory_output_stream_get_size(G_MEMORY_OUTPUT_STREAM(m));
    self->data =
        g_memory_output_stream_steal_data(G_MEMORY_OUTPUT_STREAM(m));

    return 0;
}

static const VMStateDescription dbus_vmstate = {
    .name = TYPE_DBUS_VMSTATE,
    .version_id = 0,
    .pre_save = dbus_vmstate_pre_save,
    .post_load = dbus_vmstate_post_load,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32(data_size, DBusVMState),
        VMSTATE_VBUFFER_ALLOC_UINT32(data, DBusVMState, 0, 0, data_size),
        VMSTATE_END_OF_LIST()
    }
};

static void
dbus_vmstate_complete(UserCreatable *uc, Error **errp)
{
    DBusVMState *self = DBUS_VMSTATE(uc);
    g_autoptr(GError) err = NULL;

    if (!object_resolve_path_type("", TYPE_DBUS_VMSTATE, NULL)) {
        error_setg(errp, "There is already an instance of %s",
                   TYPE_DBUS_VMSTATE);
        return;
    }

    if (!self->dbus_addr) {
        error_setg(errp, QERR_MISSING_PARAMETER, "addr");
        return;
    }

    self->bus = g_dbus_connection_new_for_address_sync(self->dbus_addr,
                    G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT |
                    G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION,
                    NULL, NULL, &err);
    if (err) {
        error_setg(errp, "failed to connect to DBus: '%s'", err->message);
        return;
    }

    if (vmstate_register(VMSTATE_IF(self), VMSTATE_INSTANCE_ID_ANY,
                         &dbus_vmstate, self) < 0) {
        error_setg(errp, "Failed to register vmstate");
    }
}

static void
dbus_vmstate_finalize(Object *o)
{
    DBusVMState *self = DBUS_VMSTATE(o);

    vmstate_unregister(VMSTATE_IF(self), &dbus_vmstate, self);

    g_clear_object(&self->bus);
    g_free(self->dbus_addr);
    g_free(self->id_list);
    g_free(self->data);
}

static char *
get_dbus_addr(Object *o, Error **errp)
{
    DBusVMState *self = DBUS_VMSTATE(o);

    return g_strdup(self->dbus_addr);
}

static void
set_dbus_addr(Object *o, const char *str, Error **errp)
{
    DBusVMState *self = DBUS_VMSTATE(o);

    g_free(self->dbus_addr);
    self->dbus_addr = g_strdup(str);
}

static char *
get_id_list(Object *o, Error **errp)
{
    DBusVMState *self = DBUS_VMSTATE(o);

    return g_strdup(self->id_list);
}

static void
set_id_list(Object *o, const char *str, Error **errp)
{
    DBusVMState *self = DBUS_VMSTATE(o);

    g_free(self->id_list);
    self->id_list = g_strdup(str);
}

static char *
dbus_vmstate_get_id(VMStateIf *vmif)
{
    return g_strdup(TYPE_DBUS_VMSTATE);
}

static void
dbus_vmstate_class_init(ObjectClass *oc, void *data)
{
    UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
    VMStateIfClass *vc = VMSTATE_IF_CLASS(oc);

    ucc->complete = dbus_vmstate_complete;
    vc->get_id = dbus_vmstate_get_id;

    object_class_property_add_str(oc, "addr",
                                  get_dbus_addr, set_dbus_addr);
    object_class_property_add_str(oc, "id-list",
                                  get_id_list, set_id_list);
}

static const TypeInfo dbus_vmstate_info = {
    .name = TYPE_DBUS_VMSTATE,
    .parent = TYPE_OBJECT,
    .instance_size = sizeof(DBusVMState),
    .instance_finalize = dbus_vmstate_finalize,
    .class_init = dbus_vmstate_class_init,
    .interfaces = (InterfaceInfo[]) {
        { TYPE_USER_CREATABLE },
        { TYPE_VMSTATE_IF },
        { }
    }
};

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

type_init(register_types);
