/*
 * qapi event unit-tests.
 *
 * Copyright (c) 2014 Wenchao Xia
 *
 * Authors:
 *  Wenchao Xia   <wenchaoqemu@gmail.com>
 *
 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
 * See the COPYING.LIB file in the top-level directory.
 *
 */

#include "qemu/osdep.h"

#include "qapi/compat-policy.h"
#include "qapi/error.h"
#include "qapi/qmp/qbool.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qjson.h"
#include "qapi/qmp/qnum.h"
#include "qapi/qmp/qstring.h"
#include "qapi/qmp-event.h"
#include "test-qapi-events.h"
#include "test-qapi-emit-events.h"

typedef struct TestEventData {
    QDict *expect;
    bool emitted;
} TestEventData;

TestEventData *test_event_data;
static GMutex test_event_lock;

void test_qapi_event_emit(test_QAPIEvent event, QDict *d)
{
    QDict *t;
    int64_t s, ms;

    /* Verify that we have timestamp, then remove it to compare other fields */
    t = qdict_get_qdict(d, "timestamp");
    g_assert(t);
    s = qdict_get_try_int(t, "seconds", -2);
    ms = qdict_get_try_int(t, "microseconds", -2);
    if (s == -1) {
        g_assert(ms == -1);
    } else {
        g_assert(s >= 0);
        g_assert(ms >= 0 && ms <= 999999);
    }
    g_assert(qdict_size(t) == 2);

    qdict_del(d, "timestamp");

    g_assert(qobject_is_equal(QOBJECT(d), QOBJECT(test_event_data->expect)));
    test_event_data->emitted = true;
}

static void event_prepare(TestEventData *data,
                          const void *unused)
{
    /* Global variable test_event_data was used to pass the expectation, so
       test cases can't be executed at same time. */
    g_mutex_lock(&test_event_lock);
    test_event_data = data;
}

static void event_teardown(TestEventData *data,
                           const void *unused)
{
    test_event_data = NULL;
    g_mutex_unlock(&test_event_lock);
}

static void event_test_add(const char *testpath,
                           void (*test_func)(TestEventData *data,
                                             const void *user_data))
{
    g_test_add(testpath, TestEventData, NULL, event_prepare, test_func,
               event_teardown);
}


/* Test cases */

static void test_event_a(TestEventData *data,
                         const void *unused)
{
    data->expect = qdict_from_jsonf_nofail("{ 'event': 'EVENT_A' }");
    qapi_event_send_event_a();
    g_assert(data->emitted);
    qobject_unref(data->expect);
}

static void test_event_b(TestEventData *data,
                         const void *unused)
{
    data->expect = qdict_from_jsonf_nofail("{ 'event': 'EVENT_B' }");
    qapi_event_send_event_b();
    g_assert(data->emitted);
    qobject_unref(data->expect);
}

static void test_event_c(TestEventData *data,
                         const void *unused)
{
    UserDefOne b = { .integer = 2, .string = (char *)"test1" };

    data->expect = qdict_from_jsonf_nofail(
        "{ 'event': 'EVENT_C', 'data': {"
        " 'a': 1, 'b': { 'integer': 2, 'string': 'test1' }, 'c': 'test2' } }");
    qapi_event_send_event_c(true, 1, true, &b, "test2");
    g_assert(data->emitted);
    qobject_unref(data->expect);
}

/* Complex type */
static void test_event_d(TestEventData *data,
                         const void *unused)
{
    UserDefOne struct1 = {
        .integer = 2, .string = (char *)"test1",
        .has_enum1 = true, .enum1 = ENUM_ONE_VALUE1,
    };
    EventStructOne a = {
        .struct1 = &struct1,
        .string = (char *)"test2",
        .has_enum2 = true,
        .enum2 = ENUM_ONE_VALUE2,
    };

    data->expect = qdict_from_jsonf_nofail(
        "{ 'event': 'EVENT_D', 'data': {"
        " 'a': {"
        "  'struct1': { 'integer': 2, 'string': 'test1', 'enum1': 'value1' },"
        "  'string': 'test2', 'enum2': 'value2' },"
        " 'b': 'test3', 'enum3': 'value3' } }");
    qapi_event_send_event_d(&a, "test3", false, NULL, true, ENUM_ONE_VALUE3);
    g_assert(data->emitted);
    qobject_unref(data->expect);
}

static void test_event_deprecated(TestEventData *data, const void *unused)
{
    data->expect = qdict_from_jsonf_nofail("{ 'event': 'TEST_EVENT_FEATURES1' }");

    memset(&compat_policy, 0, sizeof(compat_policy));

    qapi_event_send_test_event_features1();
    g_assert(data->emitted);

    compat_policy.has_deprecated_output = true;
    compat_policy.deprecated_output = COMPAT_POLICY_OUTPUT_HIDE;
    data->emitted = false;
    qapi_event_send_test_event_features1();
    g_assert(!data->emitted);

    qobject_unref(data->expect);
}

static void test_event_deprecated_data(TestEventData *data, const void *unused)
{
    memset(&compat_policy, 0, sizeof(compat_policy));

    data->expect = qdict_from_jsonf_nofail("{ 'event': 'TEST_EVENT_FEATURES0',"
                                           " 'data': { 'foo': 42 } }");
    qapi_event_send_test_event_features0(42);
    g_assert(data->emitted);

    qobject_unref(data->expect);

    compat_policy.has_deprecated_output = true;
    compat_policy.deprecated_output = COMPAT_POLICY_OUTPUT_HIDE;
    data->expect = qdict_from_jsonf_nofail("{ 'event': 'TEST_EVENT_FEATURES0' }");
    qapi_event_send_test_event_features0(42);
    g_assert(data->emitted);

    qobject_unref(data->expect);
}

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

    event_test_add("/event/event_a", test_event_a);
    event_test_add("/event/event_b", test_event_b);
    event_test_add("/event/event_c", test_event_c);
    event_test_add("/event/event_d", test_event_d);
    event_test_add("/event/deprecated", test_event_deprecated);
    event_test_add("/event/deprecated_data", test_event_deprecated_data);
    g_test_run();

    return 0;
}
