/*
 * QEMU event-loop base
 *
 * Copyright (C) 2022 Red Hat Inc
 *
 * Authors:
 *  Stefan Hajnoczi <stefanha@redhat.com>
 *  Nicolas Saenz Julienne <nsaenzju@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 "qom/object_interfaces.h"
#include "qapi/error.h"
#include "block/thread-pool.h"
#include "system/event-loop-base.h"

typedef struct {
    const char *name;
    ptrdiff_t offset; /* field's byte offset in EventLoopBase struct */
} EventLoopBaseParamInfo;

static void event_loop_base_instance_init(Object *obj)
{
    EventLoopBase *base = EVENT_LOOP_BASE(obj);

    base->thread_pool_max = THREAD_POOL_MAX_THREADS_DEFAULT;
}

static EventLoopBaseParamInfo aio_max_batch_info = {
    "aio-max-batch", offsetof(EventLoopBase, aio_max_batch),
};
static EventLoopBaseParamInfo thread_pool_min_info = {
    "thread-pool-min", offsetof(EventLoopBase, thread_pool_min),
};
static EventLoopBaseParamInfo thread_pool_max_info = {
    "thread-pool-max", offsetof(EventLoopBase, thread_pool_max),
};

static void event_loop_base_get_param(Object *obj, Visitor *v,
        const char *name, void *opaque, Error **errp)
{
    EventLoopBase *event_loop_base = EVENT_LOOP_BASE(obj);
    EventLoopBaseParamInfo *info = opaque;
    int64_t *field = (void *)event_loop_base + info->offset;

    visit_type_int64(v, name, field, errp);
}

static void event_loop_base_set_param(Object *obj, Visitor *v,
        const char *name, void *opaque, Error **errp)
{
    EventLoopBaseClass *bc = EVENT_LOOP_BASE_GET_CLASS(obj);
    EventLoopBase *base = EVENT_LOOP_BASE(obj);
    EventLoopBaseParamInfo *info = opaque;
    int64_t *field = (void *)base + info->offset;
    int64_t value;

    if (!visit_type_int64(v, name, &value, errp)) {
        return;
    }

    if (value < 0) {
        error_setg(errp, "%s value must be in range [0, %" PRId64 "]",
                   info->name, INT64_MAX);
        return;
    }

    *field = value;

    if (bc->update_params) {
        bc->update_params(base, errp);
    }
}

static void event_loop_base_complete(UserCreatable *uc, Error **errp)
{
    EventLoopBaseClass *bc = EVENT_LOOP_BASE_GET_CLASS(uc);
    EventLoopBase *base = EVENT_LOOP_BASE(uc);

    if (bc->init) {
        bc->init(base, errp);
    }
}

static bool event_loop_base_prepare_delete(UserCreatable *uc, Error **errp)
{
    EventLoopBaseClass *bc = EVENT_LOOP_BASE_GET_CLASS(uc);
    EventLoopBase *backend = EVENT_LOOP_BASE(uc);

    if (bc->prepare_delete) {
        return bc->prepare_delete(backend, errp);
    }

    return true;
}

static void event_loop_base_class_init(ObjectClass *klass,
                                       const void *class_data)
{
    UserCreatableClass *ucc = USER_CREATABLE_CLASS(klass);
    ucc->complete = event_loop_base_complete;
    ucc->prepare_delete = event_loop_base_prepare_delete;

    object_class_property_add(klass, "aio-max-batch", "int",
                              event_loop_base_get_param,
                              event_loop_base_set_param,
                              NULL, &aio_max_batch_info);
    object_class_property_add(klass, "thread-pool-min", "int",
                              event_loop_base_get_param,
                              event_loop_base_set_param,
                              NULL, &thread_pool_min_info);
    object_class_property_add(klass, "thread-pool-max", "int",
                              event_loop_base_get_param,
                              event_loop_base_set_param,
                              NULL, &thread_pool_max_info);
}

static const TypeInfo event_loop_base_info = {
    .name = TYPE_EVENT_LOOP_BASE,
    .parent = TYPE_OBJECT,
    .instance_size = sizeof(EventLoopBase),
    .instance_init = event_loop_base_instance_init,
    .class_size = sizeof(EventLoopBaseClass),
    .class_init = event_loop_base_class_init,
    .abstract = true,
    .interfaces = (const InterfaceInfo[]) {
        { TYPE_USER_CREATABLE },
        { }
    }
};

static void register_types(void)
{
    type_register_static(&event_loop_base_info);
}
type_init(register_types);
