/*
 * Persistent reservation manager abstract class
 *
 * Copyright (c) 2017 Red Hat, Inc.
 *
 * Author: Paolo Bonzini <pbonzini@redhat.com>
 *
 * This code is licensed under the LGPL.
 *
 */

#include "qemu/osdep.h"
#include <scsi/sg.h>

#include "qapi/error.h"
#include "block/aio.h"
#include "block/thread-pool.h"
#include "scsi/pr-manager.h"
#include "trace.h"
#include "qapi/qapi-types-block.h"
#include "qemu/module.h"
#include "qapi/qapi-commands-block.h"

#define PR_MANAGER_PATH     "/objects"

typedef struct PRManagerData {
    PRManager *pr_mgr;
    struct sg_io_hdr *hdr;
    int fd;
} PRManagerData;

static int pr_manager_worker(void *opaque)
{
    PRManagerData *data = opaque;
    PRManager *pr_mgr = data->pr_mgr;
    PRManagerClass *pr_mgr_class =
        PR_MANAGER_GET_CLASS(pr_mgr);
    struct sg_io_hdr *hdr = data->hdr;
    int fd = data->fd;
    int r;

    trace_pr_manager_run(fd, hdr->cmdp[0], hdr->cmdp[1]);

    /* The reference was taken in pr_manager_execute.  */
    r = pr_mgr_class->run(pr_mgr, fd, hdr);
    object_unref(OBJECT(pr_mgr));
    return r;
}


int coroutine_fn pr_manager_execute(PRManager *pr_mgr, AioContext *ctx, int fd,
                                    struct sg_io_hdr *hdr)
{
    PRManagerData data = {
        .pr_mgr = pr_mgr,
        .fd     = fd,
        .hdr    = hdr,
    };

    trace_pr_manager_execute(fd, hdr->cmdp[0], hdr->cmdp[1]);

    /* The matching object_unref is in pr_manager_worker.  */
    object_ref(OBJECT(pr_mgr));
    return thread_pool_submit_co(pr_manager_worker, &data);
}

bool pr_manager_is_connected(PRManager *pr_mgr)
{
    PRManagerClass *pr_mgr_class =
        PR_MANAGER_GET_CLASS(pr_mgr);

    return !pr_mgr_class->is_connected || pr_mgr_class->is_connected(pr_mgr);
}

static const TypeInfo pr_manager_info = {
    .parent = TYPE_OBJECT,
    .name = TYPE_PR_MANAGER,
    .class_size = sizeof(PRManagerClass),
    .abstract = true,
    .interfaces = (InterfaceInfo[]) {
        { TYPE_USER_CREATABLE },
        { }
    }
};

PRManager *pr_manager_lookup(const char *id, Error **errp)
{
    Object *obj;
    PRManager *pr_mgr;

    obj = object_resolve_path_component(object_get_objects_root(), id);
    if (!obj) {
        error_setg(errp, "No persistent reservation manager with id '%s'", id);
        return NULL;
    }

    pr_mgr = (PRManager *)
        object_dynamic_cast(obj,
                            TYPE_PR_MANAGER);
    if (!pr_mgr) {
        error_setg(errp,
                   "Object with id '%s' is not a persistent reservation manager",
                   id);
        return NULL;
    }

    return pr_mgr;
}

static void
pr_manager_register_types(void)
{
    type_register_static(&pr_manager_info);
}

static int query_one_pr_manager(Object *object, void *opaque)
{
    PRManagerInfoList ***tail = opaque;
    PRManagerInfo *info;
    PRManager *pr_mgr;

    pr_mgr = (PRManager *)object_dynamic_cast(object, TYPE_PR_MANAGER);
    if (!pr_mgr) {
        return 0;
    }

    info = g_new0(PRManagerInfo, 1);
    info->id = g_strdup(object_get_canonical_path_component(object));
    info->connected = pr_manager_is_connected(pr_mgr);
    QAPI_LIST_APPEND(*tail, info);
    return 0;
}

PRManagerInfoList *qmp_query_pr_managers(Error **errp)
{
    PRManagerInfoList *head = NULL;
    PRManagerInfoList **prev = &head;
    Object *container = container_get(object_get_root(), PR_MANAGER_PATH);

    object_child_foreach(container, query_one_pr_manager, &prev);
    return head;
}

type_init(pr_manager_register_types);
