/*
 * Copy one QAPI object to another
 *
 * Copyright (C) 2016 Red Hat, 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 "qapi/clone-visitor.h"
#include "qapi/visitor-impl.h"
#include "qapi/error.h"
#include "qapi/qmp/qnull.h"

struct QapiCloneVisitor {
    Visitor visitor;
    size_t depth;
};

static QapiCloneVisitor *to_qcv(Visitor *v)
{
    return container_of(v, QapiCloneVisitor, visitor);
}

static bool qapi_clone_start_struct(Visitor *v, const char *name, void **obj,
                                    size_t size, Error **errp)
{
    QapiCloneVisitor *qcv = to_qcv(v);

    if (!obj) {
        assert(qcv->depth);
        /* Only possible when visiting an alternate's object
         * branch. Nothing further to do here, since the earlier
         * visit_start_alternate() already copied memory. */
        return true;
    }

    *obj = g_memdup(*obj, size);
    qcv->depth++;
    return true;
}

static void qapi_clone_end(Visitor *v, void **obj)
{
    QapiCloneVisitor *qcv = to_qcv(v);

    assert(qcv->depth);
    if (obj) {
        qcv->depth--;
    }
}

static bool qapi_clone_start_list(Visitor *v, const char *name,
                                  GenericList **listp, size_t size,
                                  Error **errp)
{
    return qapi_clone_start_struct(v, name, (void **)listp, size, errp);
}

static GenericList *qapi_clone_next_list(Visitor *v, GenericList *tail,
                                         size_t size)
{
    QapiCloneVisitor *qcv = to_qcv(v);

    assert(qcv->depth);
    /* Unshare the tail of the list cloned by g_memdup() */
    tail->next = g_memdup(tail->next, size);
    return tail->next;
}

static bool qapi_clone_start_alternate(Visitor *v, const char *name,
                                       GenericAlternate **obj, size_t size,
                                       Error **errp)
{
    return qapi_clone_start_struct(v, name, (void **)obj, size, errp);
}

static bool qapi_clone_type_int64(Visitor *v, const char *name, int64_t *obj,
                                  Error **errp)
{
    QapiCloneVisitor *qcv = to_qcv(v);

    assert(qcv->depth);
    /* Value was already cloned by g_memdup() */
    return true;
}

static bool qapi_clone_type_uint64(Visitor *v, const char *name,
                                   uint64_t *obj, Error **errp)
{
    QapiCloneVisitor *qcv = to_qcv(v);

    assert(qcv->depth);
    /* Value was already cloned by g_memdup() */
    return true;
}

static bool qapi_clone_type_bool(Visitor *v, const char *name, bool *obj,
                                 Error **errp)
{
    QapiCloneVisitor *qcv = to_qcv(v);

    assert(qcv->depth);
    /* Value was already cloned by g_memdup() */
    return true;
}

static bool qapi_clone_type_str(Visitor *v, const char *name, char **obj,
                                Error **errp)
{
    QapiCloneVisitor *qcv = to_qcv(v);

    assert(qcv->depth);
    /*
     * Pointer was already cloned by g_memdup; create fresh copy.
     * Note that as long as qobject-output-visitor accepts NULL instead of
     * "", then we must do likewise. However, we want to obey the
     * input visitor semantics of never producing NULL when the empty
     * string is intended.
     */
    *obj = g_strdup(*obj ?: "");
    return true;
}

static bool qapi_clone_type_number(Visitor *v, const char *name, double *obj,
                                   Error **errp)
{
    QapiCloneVisitor *qcv = to_qcv(v);

    assert(qcv->depth);
    /* Value was already cloned by g_memdup() */
    return true;
}

static bool qapi_clone_type_null(Visitor *v, const char *name, QNull **obj,
                                 Error **errp)
{
    QapiCloneVisitor *qcv = to_qcv(v);

    assert(qcv->depth);
    *obj = qnull();
    return true;
}

static void qapi_clone_free(Visitor *v)
{
    g_free(v);
}

static Visitor *qapi_clone_visitor_new(void)
{
    QapiCloneVisitor *v;

    v = g_malloc0(sizeof(*v));

    v->visitor.type = VISITOR_CLONE;
    v->visitor.start_struct = qapi_clone_start_struct;
    v->visitor.end_struct = qapi_clone_end;
    v->visitor.start_list = qapi_clone_start_list;
    v->visitor.next_list = qapi_clone_next_list;
    v->visitor.end_list = qapi_clone_end;
    v->visitor.start_alternate = qapi_clone_start_alternate;
    v->visitor.end_alternate = qapi_clone_end;
    v->visitor.type_int64 = qapi_clone_type_int64;
    v->visitor.type_uint64 = qapi_clone_type_uint64;
    v->visitor.type_bool = qapi_clone_type_bool;
    v->visitor.type_str = qapi_clone_type_str;
    v->visitor.type_number = qapi_clone_type_number;
    v->visitor.type_null = qapi_clone_type_null;
    v->visitor.free = qapi_clone_free;

    return &v->visitor;
}

void *qapi_clone(const void *src, bool (*visit_type)(Visitor *, const char *,
                                                     void **, Error **))
{
    Visitor *v;
    void *dst = (void *) src; /* Cast away const */

    if (!src) {
        return NULL;
    }

    v = qapi_clone_visitor_new();
    visit_type(v, NULL, &dst, &error_abort);
    visit_free(v);
    return dst;
}

void qapi_clone_members(void *dst, const void *src, size_t sz,
                        bool (*visit_type_members)(Visitor *, void *,
                                                   Error **))
{
    Visitor *v;

    v = qapi_clone_visitor_new();
    memcpy(dst, src, sz);
    to_qcv(v)->depth++;
    visit_type_members(v, dst, &error_abort);
    visit_free(v);
}
