/*
 * QAPI Forwarding Visitor unit-tests.
 *
 * Copyright (C) 2021 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 "qemu-common.h"
#include "qapi/forward-visitor.h"
#include "qapi/qobject-input-visitor.h"
#include "qapi/error.h"
#include "qapi/qmp/qobject.h"
#include "qapi/qmp/qdict.h"
#include "test-qapi-visit.h"
#include "qemu/option.h"

typedef bool GenericVisitor (Visitor *, const char *, void **, Error **);
#define CAST_VISIT_TYPE(fn) ((GenericVisitor *)(fn))

/*
 * Parse @srcstr and wrap it with a ForwardFieldVisitor converting "src" to
 * "dst". Check that visiting the result with "src" name fails, and return
 * the result of visiting "dst".
 */
static void *visit_with_forward(const char *srcstr, GenericVisitor *fn)
{
    bool help = false;
    QDict *src = keyval_parse(srcstr, NULL, &help, &error_abort);
    Visitor *v, *alias_v;
    Error *err = NULL;
    void *result = NULL;

    v = qobject_input_visitor_new_keyval(QOBJECT(src));
    visit_start_struct(v, NULL, NULL, 0, &error_abort);

    alias_v = visitor_forward_field(v, "dst", "src");
    fn(alias_v, "src", &result, &err);
    error_free_or_abort(&err);
    assert(!result);
    fn(alias_v, "dst", &result, &err);
    assert(err == NULL);
    visit_free(alias_v);

    visit_end_struct(v, NULL);
    visit_free(v);
    qobject_unref(QOBJECT(src));
    return result;
}

static void test_forward_any(void)
{
    QObject *src = visit_with_forward("src.integer=42,src.string=Hello,src.enum1=value2",
                                      CAST_VISIT_TYPE(visit_type_any));
    Visitor *v = qobject_input_visitor_new_keyval(src);
    Error *err = NULL;
    UserDefOne *dst;

    visit_type_UserDefOne(v, NULL, &dst, &err);
    assert(err == NULL);
    visit_free(v);

    g_assert_cmpint(dst->integer, ==, 42);
    g_assert_cmpstr(dst->string, ==, "Hello");
    g_assert_cmpint(dst->has_enum1, ==, true);
    g_assert_cmpint(dst->enum1, ==, ENUM_ONE_VALUE2);
    qapi_free_UserDefOne(dst);
    qobject_unref(QOBJECT(src));
}

static void test_forward_size(void)
{
    /*
     * visit_type_size does not return a pointer, so visit_with_forward
     * cannot be used.
     */
    bool help = false;
    QDict *src = keyval_parse("src=1.5M", NULL, &help, &error_abort);
    Visitor *v, *alias_v;
    Error *err = NULL;
    uint64_t result = 0;

    v = qobject_input_visitor_new_keyval(QOBJECT(src));
    visit_start_struct(v, NULL, NULL, 0, &error_abort);

    alias_v = visitor_forward_field(v, "dst", "src");
    visit_type_size(alias_v, "src", &result, &err);
    error_free_or_abort(&err);
    visit_type_size(alias_v, "dst", &result, &err);
    assert(result == 3 << 19);
    assert(err == NULL);
    visit_free(alias_v);

    visit_end_struct(v, NULL);
    visit_free(v);
    qobject_unref(QOBJECT(src));
}

static void test_forward_number(void)
{
    /*
     * visit_type_number does not return a pointer, so visit_with_forward
     * cannot be used.
     */
    bool help = false;
    QDict *src = keyval_parse("src=1.5", NULL, &help, &error_abort);
    Visitor *v, *alias_v;
    Error *err = NULL;
    double result = 0.0;

    v = qobject_input_visitor_new_keyval(QOBJECT(src));
    visit_start_struct(v, NULL, NULL, 0, &error_abort);

    alias_v = visitor_forward_field(v, "dst", "src");
    visit_type_number(alias_v, "src", &result, &err);
    error_free_or_abort(&err);
    visit_type_number(alias_v, "dst", &result, &err);
    assert(result == 1.5);
    assert(err == NULL);
    visit_free(alias_v);

    visit_end_struct(v, NULL);
    visit_free(v);
    qobject_unref(QOBJECT(src));
}

static void test_forward_string(void)
{
    char *dst = visit_with_forward("src=Hello",
                                   CAST_VISIT_TYPE(visit_type_str));

    g_assert_cmpstr(dst, ==, "Hello");
    g_free(dst);
}

static void test_forward_struct(void)
{
    UserDefOne *dst = visit_with_forward("src.integer=42,src.string=Hello",
                                         CAST_VISIT_TYPE(visit_type_UserDefOne));

    g_assert_cmpint(dst->integer, ==, 42);
    g_assert_cmpstr(dst->string, ==, "Hello");
    g_assert_cmpint(dst->has_enum1, ==, false);
    qapi_free_UserDefOne(dst);
}

static void test_forward_alternate(void)
{
    AltStrObj *s_dst = visit_with_forward("src=hello",
                                          CAST_VISIT_TYPE(visit_type_AltStrObj));
    AltStrObj *o_dst = visit_with_forward("src.integer=42,src.boolean=true,src.string=world",
                                          CAST_VISIT_TYPE(visit_type_AltStrObj));

    g_assert_cmpint(s_dst->type, ==, QTYPE_QSTRING);
    g_assert_cmpstr(s_dst->u.s, ==, "hello");
    g_assert_cmpint(o_dst->type, ==, QTYPE_QDICT);
    g_assert_cmpint(o_dst->u.o.integer, ==, 42);
    g_assert_cmpint(o_dst->u.o.boolean, ==, true);
    g_assert_cmpstr(o_dst->u.o.string, ==, "world");

    qapi_free_AltStrObj(s_dst);
    qapi_free_AltStrObj(o_dst);
}

static void test_forward_list(void)
{
    uint8List *dst = visit_with_forward("src.0=1,src.1=2,src.2=3,src.3=4",
                                        CAST_VISIT_TYPE(visit_type_uint8List));
    uint8List *tmp;
    int i;

    for (tmp = dst, i = 1; i <= 4; i++) {
        g_assert(tmp);
        g_assert_cmpint(tmp->value, ==, i);
        tmp = tmp->next;
    }
    g_assert(!tmp);
    qapi_free_uint8List(dst);
}

int main(int argc, char **argv)
{
    g_test_init(&argc, &argv, NULL);

    g_test_add_func("/visitor/forward/struct", test_forward_struct);
    g_test_add_func("/visitor/forward/alternate", test_forward_alternate);
    g_test_add_func("/visitor/forward/string", test_forward_string);
    g_test_add_func("/visitor/forward/size", test_forward_size);
    g_test_add_func("/visitor/forward/number", test_forward_number);
    g_test_add_func("/visitor/forward/any", test_forward_any);
    g_test_add_func("/visitor/forward/list", test_forward_list);

    return g_test_run();
}
