/*
 * String Output Visitor unit-tests.
 *
 * Copyright (C) 2012 Red Hat Inc.
 *
 * Authors:
 *  Paolo Bonzini <pbonzini@redhat.com> (based on test-qobject-output-visitor)
 *
 * 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/error.h"
#include "qapi/string-output-visitor.h"
#include "test-qapi-visit.h"

typedef struct TestOutputVisitorData {
    Visitor *ov;
    char *str;
    bool human;
} TestOutputVisitorData;

static void visitor_output_setup_internal(TestOutputVisitorData *data,
                                          bool human)
{
    data->human = human;
    data->ov = string_output_visitor_new(human, &data->str);
    g_assert(data->ov);
}

static void visitor_output_setup(TestOutputVisitorData *data,
                                 const void *unused)
{
    return visitor_output_setup_internal(data, false);
}

static void visitor_output_setup_human(TestOutputVisitorData *data,
                                       const void *unused)
{
    return visitor_output_setup_internal(data, true);
}

static void visitor_output_teardown(TestOutputVisitorData *data,
                                    const void *unused)
{
    visit_free(data->ov);
    data->ov = NULL;
    g_free(data->str);
    data->str = NULL;
}

static char *visitor_get(TestOutputVisitorData *data)
{
    visit_complete(data->ov, &data->str);
    g_assert(data->str);
    return data->str;
}

static void visitor_reset(TestOutputVisitorData *data)
{
    bool human = data->human;

    visitor_output_teardown(data, NULL);
    visitor_output_setup_internal(data, human);
}

static void test_visitor_out_int(TestOutputVisitorData *data,
                                 const void *unused)
{
    int64_t value = 42;
    char *str;

    visit_type_int(data->ov, NULL, &value, &error_abort);

    str = visitor_get(data);
    if (data->human) {
        g_assert_cmpstr(str, ==, "42 (0x2a)");
    } else {
        g_assert_cmpstr(str, ==, "42");
    }
}

static void test_visitor_out_intList(TestOutputVisitorData *data,
                                     const void *unused)
{
    int64_t value[] = {0, 1, 9, 10, 16, 15, 14,
        3, 4, 5, 6, 11, 12, 13, 21, 22, INT64_MAX - 1, INT64_MAX};
    intList *list = NULL, **tmp = &list;
    int i;
    Error *err = NULL;
    char *str;

    for (i = 0; i < ARRAY_SIZE(value); i++) {
        *tmp = g_malloc0(sizeof(**tmp));
        (*tmp)->value = value[i];
        tmp = &(*tmp)->next;
    }

    visit_type_intList(data->ov, NULL, &list, &err);
    g_assert(err == NULL);

    str = visitor_get(data);
    if (data->human) {
        g_assert_cmpstr(str, ==,
            "0-1,3-6,9-16,21-22,9223372036854775806-9223372036854775807 "
            "(0x0-0x1,0x3-0x6,0x9-0x10,0x15-0x16,"
            "0x7ffffffffffffffe-0x7fffffffffffffff)");
    } else {
        g_assert_cmpstr(str, ==,
            "0-1,3-6,9-16,21-22,9223372036854775806-9223372036854775807");
    }
    qapi_free_intList(list);
}

static void test_visitor_out_bool(TestOutputVisitorData *data,
                                  const void *unused)
{
    bool value = true;
    char *str;

    visit_type_bool(data->ov, NULL, &value, &error_abort);

    str = visitor_get(data);
    g_assert_cmpstr(str, ==, "true");
}

static void test_visitor_out_number(TestOutputVisitorData *data,
                                    const void *unused)
{
    double value = 3.14;
    char *str;

    visit_type_number(data->ov, NULL, &value, &error_abort);

    str = visitor_get(data);
    g_assert_cmpstr(str, ==, "3.140000");
}

static void test_visitor_out_string(TestOutputVisitorData *data,
                                    const void *unused)
{
    char *string = (char *) "Q E M U";
    const char *string_human = "\"Q E M U\"";
    char *str;

    visit_type_str(data->ov, NULL, &string, &error_abort);

    str = visitor_get(data);
    if (data->human) {
        g_assert_cmpstr(str, ==, string_human);
    } else {
        g_assert_cmpstr(str, ==, string);
    }
}

static void test_visitor_out_no_string(TestOutputVisitorData *data,
                                       const void *unused)
{
    char *string = NULL;
    char *str;

    /* A null string should return "" */
    visit_type_str(data->ov, NULL, &string, &error_abort);

    str = visitor_get(data);
    if (data->human) {
        g_assert_cmpstr(str, ==, "<null>");
    } else {
        g_assert_cmpstr(str, ==, "");
    }
}

static void test_visitor_out_enum(TestOutputVisitorData *data,
                                  const void *unused)
{
    char *str;
    EnumOne i;

    for (i = 0; i < ENUM_ONE__MAX; i++) {
        visit_type_EnumOne(data->ov, "unused", &i, &error_abort);

        str = visitor_get(data);
        if (data->human) {
            char *str_human = g_strdup_printf("\"%s\"", EnumOne_str(i));

            g_assert_cmpstr(str, ==, str_human);
            g_free(str_human);
        } else {
            g_assert_cmpstr(str, ==, EnumOne_str(i));
        }
        visitor_reset(data);
    }
}

static void
output_visitor_test_add(const char *testpath,
                        TestOutputVisitorData *data,
                        void (*test_func)(TestOutputVisitorData *data,
                                          const void *user_data),
                        bool human)
{
    g_test_add(testpath, TestOutputVisitorData, data,
               human ? visitor_output_setup_human : visitor_output_setup,
               test_func, visitor_output_teardown);
}

int main(int argc, char **argv)
{
    TestOutputVisitorData out_visitor_data;

    g_test_init(&argc, &argv, NULL);

    output_visitor_test_add("/string-visitor/output/int",
                            &out_visitor_data, test_visitor_out_int, false);
    output_visitor_test_add("/string-visitor/output/int-human",
                            &out_visitor_data, test_visitor_out_int, true);
    output_visitor_test_add("/string-visitor/output/bool",
                            &out_visitor_data, test_visitor_out_bool, false);
    output_visitor_test_add("/string-visitor/output/bool-human",
                            &out_visitor_data, test_visitor_out_bool, true);
    output_visitor_test_add("/string-visitor/output/number",
                            &out_visitor_data, test_visitor_out_number, false);
    output_visitor_test_add("/string-visitor/output/number-human",
                            &out_visitor_data, test_visitor_out_number, true);
    output_visitor_test_add("/string-visitor/output/string",
                            &out_visitor_data, test_visitor_out_string, false);
    output_visitor_test_add("/string-visitor/output/string-human",
                            &out_visitor_data, test_visitor_out_string, true);
    output_visitor_test_add("/string-visitor/output/no-string",
                            &out_visitor_data, test_visitor_out_no_string,
                            false);
    output_visitor_test_add("/string-visitor/output/no-string-human",
                            &out_visitor_data, test_visitor_out_no_string,
                            true);
    output_visitor_test_add("/string-visitor/output/enum",
                            &out_visitor_data, test_visitor_out_enum, false);
    output_visitor_test_add("/string-visitor/output/enum-human",
                            &out_visitor_data, test_visitor_out_enum, true);
    output_visitor_test_add("/string-visitor/output/intList",
                            &out_visitor_data, test_visitor_out_intList, false);
    output_visitor_test_add("/string-visitor/output/intList-human",
                            &out_visitor_data, test_visitor_out_intList, true);

    g_test_run();

    return 0;
}
