/*
 * Copyright (c) 2018  Citrix Systems Inc.
 *
 * 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/error-report.h"
#include "qapi/error.h"
#include "hw/xen/xen-backend.h"
#include "hw/xen/xen-bus.h"

typedef struct XenBackendImpl {
    const char *type;
    XenBackendDeviceCreate create;
    XenBackendDeviceDestroy destroy;
} XenBackendImpl;

struct XenBackendInstance {
    QLIST_ENTRY(XenBackendInstance) entry;
    const XenBackendImpl *impl;
    XenBus *xenbus;
    char *name;
    XenDevice *xendev;
};

static GHashTable *xen_backend_table_get(void)
{
    static GHashTable *table;

    if (table == NULL) {
        table = g_hash_table_new(g_str_hash, g_str_equal);
    }

    return table;
}

static void xen_backend_table_add(XenBackendImpl *impl)
{
    g_hash_table_insert(xen_backend_table_get(), (void *)impl->type, impl);
}

static const XenBackendImpl *xen_backend_table_lookup(const char *type)
{
    return g_hash_table_lookup(xen_backend_table_get(), type);
}

void xen_backend_register(const XenBackendInfo *info)
{
    XenBackendImpl *impl = g_new0(XenBackendImpl, 1);

    g_assert(info->type);

    if (xen_backend_table_lookup(info->type)) {
        error_report("attempt to register duplicate Xen backend type '%s'",
                     info->type);
        abort();
    }

    if (!info->create) {
        error_report("backend type '%s' has no creator", info->type);
        abort();
    }

    impl->type = info->type;
    impl->create = info->create;
    impl->destroy = info->destroy;

    xen_backend_table_add(impl);
}

static QLIST_HEAD(, XenBackendInstance) backend_list;

static void xen_backend_list_add(XenBackendInstance *backend)
{
    QLIST_INSERT_HEAD(&backend_list, backend, entry);
}

static XenBackendInstance *xen_backend_list_find(XenDevice *xendev)
{
    XenBackendInstance *backend;

    QLIST_FOREACH(backend, &backend_list, entry) {
        if (backend->xendev == xendev) {
            return backend;
        }
    }

    return NULL;
}

static void xen_backend_list_remove(XenBackendInstance *backend)
{
    QLIST_REMOVE(backend, entry);
}

void xen_backend_device_create(XenBus *xenbus, const char *type,
                               const char *name, QDict *opts, Error **errp)
{
    const XenBackendImpl *impl = xen_backend_table_lookup(type);
    XenBackendInstance *backend;
    Error *local_error = NULL;

    if (!impl) {
        return;
    }

    backend = g_new0(XenBackendInstance, 1);
    backend->xenbus = xenbus;
    backend->name = g_strdup(name);

    impl->create(backend, opts, &local_error);
    if (local_error) {
        error_propagate(errp, local_error);
        g_free(backend->name);
        g_free(backend);
        return;
    }

    backend->impl = impl;
    xen_backend_list_add(backend);
}

XenBus *xen_backend_get_bus(XenBackendInstance *backend)
{
    return backend->xenbus;
}

const char *xen_backend_get_name(XenBackendInstance *backend)
{
    return backend->name;
}

void xen_backend_set_device(XenBackendInstance *backend,
                            XenDevice *xendev)
{
    g_assert(!backend->xendev);
    backend->xendev = xendev;
}

XenDevice *xen_backend_get_device(XenBackendInstance *backend)
{
    return backend->xendev;
}


bool xen_backend_try_device_destroy(XenDevice *xendev, Error **errp)
{
    XenBackendInstance *backend = xen_backend_list_find(xendev);
    const XenBackendImpl *impl;

    if (!backend) {
        return false;
    }

    impl = backend->impl;
    impl->destroy(backend, errp);

    xen_backend_list_remove(backend);
    g_free(backend->name);
    g_free(backend);

    return true;
}
