/*
 * 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 "qobject/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);
}

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;
}

Visitor *qapi_clone_members_visitor_new(void)
{
    Visitor *v = qapi_clone_visitor_new();
    to_qcv(v)->depth++;
    return v;
}
