/*
 * 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 "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/keyval.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();
}
