/*
 * QEMU yank feature
 *
 * Copyright (c) Lukas Straub <lukasstraub2@web.de>
 *
 * 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 "qemu/thread.h"
#include "qemu/queue.h"
#include "qemu/lockable.h"
#include "qapi/qapi-commands-yank.h"
#include "qapi/qapi-visit-yank.h"
#include "qapi/clone-visitor.h"
#include "io/channel.h"
#include "qemu/yank.h"

struct YankFuncAndParam {
    YankFn *func;
    void *opaque;
    QLIST_ENTRY(YankFuncAndParam) next;
};

struct YankInstanceEntry {
    YankInstance *instance;
    QLIST_HEAD(, YankFuncAndParam) yankfns;
    QLIST_ENTRY(YankInstanceEntry) next;
};

typedef struct YankFuncAndParam YankFuncAndParam;
typedef struct YankInstanceEntry YankInstanceEntry;

/*
 * This lock protects the yank_instance_list below. Because it's taken by
 * OOB-capable commands, it must be "fast", i.e. it may only be held for a
 * bounded, short time. See docs/devel/qapi-code-gen.txt for additional
 * information.
 */
static QemuMutex yank_lock;

static QLIST_HEAD(, YankInstanceEntry) yank_instance_list
    = QLIST_HEAD_INITIALIZER(yank_instance_list);

static bool yank_instance_equal(const YankInstance *a, const YankInstance *b)
{
    if (a->type != b->type) {
        return false;
    }

    switch (a->type) {
    case YANK_INSTANCE_TYPE_BLOCK_NODE:
        return g_str_equal(a->u.block_node.node_name,
                           b->u.block_node.node_name);

    case YANK_INSTANCE_TYPE_CHARDEV:
        return g_str_equal(a->u.chardev.id, b->u.chardev.id);

    case YANK_INSTANCE_TYPE_MIGRATION:
        return true;

    default:
        abort();
    }
}

static YankInstanceEntry *yank_find_entry(const YankInstance *instance)
{
    YankInstanceEntry *entry;

    QLIST_FOREACH(entry, &yank_instance_list, next) {
        if (yank_instance_equal(entry->instance, instance)) {
            return entry;
        }
    }
    return NULL;
}

bool yank_register_instance(const YankInstance *instance, Error **errp)
{
    YankInstanceEntry *entry;

    QEMU_LOCK_GUARD(&yank_lock);

    if (yank_find_entry(instance)) {
        error_setg(errp, "duplicate yank instance");
        return false;
    }

    entry = g_new0(YankInstanceEntry, 1);
    entry->instance = QAPI_CLONE(YankInstance, instance);
    QLIST_INIT(&entry->yankfns);
    QLIST_INSERT_HEAD(&yank_instance_list, entry, next);

    return true;
}

void yank_unregister_instance(const YankInstance *instance)
{
    YankInstanceEntry *entry;

    QEMU_LOCK_GUARD(&yank_lock);
    entry = yank_find_entry(instance);
    assert(entry);

    assert(QLIST_EMPTY(&entry->yankfns));
    QLIST_REMOVE(entry, next);
    qapi_free_YankInstance(entry->instance);
    g_free(entry);
}

void yank_register_function(const YankInstance *instance,
                            YankFn *func,
                            void *opaque)
{
    YankInstanceEntry *entry;
    YankFuncAndParam *func_entry;

    QEMU_LOCK_GUARD(&yank_lock);
    entry = yank_find_entry(instance);
    assert(entry);

    func_entry = g_new0(YankFuncAndParam, 1);
    func_entry->func = func;
    func_entry->opaque = opaque;

    QLIST_INSERT_HEAD(&entry->yankfns, func_entry, next);
}

void yank_unregister_function(const YankInstance *instance,
                              YankFn *func,
                              void *opaque)
{
    YankInstanceEntry *entry;
    YankFuncAndParam *func_entry;

    QEMU_LOCK_GUARD(&yank_lock);
    entry = yank_find_entry(instance);
    assert(entry);

    QLIST_FOREACH(func_entry, &entry->yankfns, next) {
        if (func_entry->func == func && func_entry->opaque == opaque) {
            QLIST_REMOVE(func_entry, next);
            g_free(func_entry);
            return;
        }
    }

    abort();
}

void yank_generic_iochannel(void *opaque)
{
    QIOChannel *ioc = QIO_CHANNEL(opaque);

    qio_channel_shutdown(ioc, QIO_CHANNEL_SHUTDOWN_BOTH, NULL);
}

void qmp_yank(YankInstanceList *instances,
              Error **errp)
{
    YankInstanceList *tail;
    YankInstanceEntry *entry;
    YankFuncAndParam *func_entry;

    QEMU_LOCK_GUARD(&yank_lock);
    for (tail = instances; tail; tail = tail->next) {
        entry = yank_find_entry(tail->value);
        if (!entry) {
            error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND, "Instance not found");
            return;
        }
    }
    for (tail = instances; tail; tail = tail->next) {
        entry = yank_find_entry(tail->value);
        assert(entry);
        QLIST_FOREACH(func_entry, &entry->yankfns, next) {
            func_entry->func(func_entry->opaque);
        }
    }
}

YankInstanceList *qmp_query_yank(Error **errp)
{
    YankInstanceEntry *entry;
    YankInstanceList *ret;

    ret = NULL;

    QEMU_LOCK_GUARD(&yank_lock);
    QLIST_FOREACH(entry, &yank_instance_list, next) {
        YankInstanceList *new_entry;
        new_entry = g_new0(YankInstanceList, 1);
        new_entry->value = QAPI_CLONE(YankInstance, entry->instance);
        new_entry->next = ret;
        ret = new_entry;
    }

    return ret;
}

static void __attribute__((__constructor__)) yank_init(void)
{
    qemu_mutex_init(&yank_lock);
}
