/*
 * Validate -readconfig
 *
 * Copyright (c) 2022 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 "libqtest.h"
#include "qapi/error.h"
#include "qapi/qapi-visit-machine.h"
#include "qapi/qapi-visit-qom.h"
#include "qapi/qapi-visit-ui.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qlist.h"
#include "qapi/qobject-input-visitor.h"
#include "qapi/qmp/qstring.h"
#include "qemu/units.h"

static QTestState *qtest_init_with_config(const char *cfgdata)
{
    GError *error = NULL;
    g_autofree char *args = NULL;
    int cfgfd = -1;
    g_autofree char *cfgpath = NULL;
    QTestState *qts;
    ssize_t ret;

    cfgfd = g_file_open_tmp("readconfig-test-XXXXXX", &cfgpath, &error);
    g_assert_no_error(error);
    g_assert_cmpint(cfgfd, >=, 0);

    ret = qemu_write_full(cfgfd, cfgdata, strlen(cfgdata));
    close(cfgfd);
    if (ret < 0) {
        unlink(cfgpath);
    }
    g_assert_cmpint(ret, ==, strlen(cfgdata));

    args = g_strdup_printf("-nodefaults -machine none -readconfig %s", cfgpath);

    qts = qtest_init(args);

    unlink(cfgpath);

    return qts;
}

static void test_x86_memdev_resp(QObject *res)
{
    Visitor *v;
    g_autoptr(MemdevList) memdevs = NULL;
    Memdev *memdev;

    g_assert(res);
    v = qobject_input_visitor_new(res);
    visit_type_MemdevList(v, NULL, &memdevs, &error_abort);

    g_assert(memdevs);
    g_assert(memdevs->value);
    g_assert(!memdevs->next);

    memdev = memdevs->value;
    g_assert_cmpstr(memdev->id, ==, "ram");
    g_assert_cmpint(memdev->size, ==, 200 * MiB);

    visit_free(v);
}

static void test_x86_memdev(void)
{
    QDict *resp;
    QTestState *qts;
    const char *cfgdata =
        "[memory]\n"
        "size = \"200\"";

    qts = qtest_init_with_config(cfgdata);
    /* Test valid command */
    resp = qtest_qmp(qts, "{ 'execute': 'query-memdev' }");
    test_x86_memdev_resp(qdict_get(resp, "return"));
    qobject_unref(resp);

    qtest_quit(qts);
}

/* FIXME: The test is currently broken on FreeBSD */
#if defined(CONFIG_SPICE) && !defined(__FreeBSD__)
static void test_spice_resp(QObject *res)
{
    Visitor *v;
    g_autoptr(SpiceInfo) spice = NULL;

    g_assert(res);
    v = qobject_input_visitor_new(res);
    visit_type_SpiceInfo(v, "spice", &spice, &error_abort);

    g_assert(spice);
    g_assert(spice->enabled);

    visit_free(v);
}

static void test_spice(void)
{
    QDict *resp;
    QTestState *qts;
    const char *cfgdata =
        "[spice]\n"
#ifndef WIN32
        "unix = \"on\"\n"
#endif
        "disable-ticketing = \"on\"\n";

    qts = qtest_init_with_config(cfgdata);
    /* Test valid command */
    resp = qtest_qmp(qts, "{ 'execute': 'query-spice' }");
    test_spice_resp(qdict_get(resp, "return"));
    qobject_unref(resp);

    qtest_quit(qts);
}
#endif

static void test_object_available(QObject *res, const char *name,
                                  const char *type)
{
    Visitor *v;
    g_autoptr(ObjectPropertyInfoList) objs = NULL;
    ObjectPropertyInfoList *tmp;
    ObjectPropertyInfo *obj;
    bool object_available = false;
    g_autofree char *childtype = g_strdup_printf("child<%s>", type);

    g_assert(res);
    v = qobject_input_visitor_new(res);
    visit_type_ObjectPropertyInfoList(v, NULL, &objs, &error_abort);

    g_assert(objs);
    tmp = objs;
    while (tmp) {
        g_assert(tmp->value);

        obj = tmp->value;
        if (g_str_equal(obj->name, name) && g_str_equal(obj->type, childtype)) {
            object_available = true;
            break;
        }

        tmp = tmp->next;
    }

    g_assert(object_available);

    visit_free(v);
}

static void test_object_rng(void)
{
    QDict *resp;
    QTestState *qts;
    const char *cfgdata =
        "[object]\n"
        "qom-type = \"rng-builtin\"\n"
        "id = \"rng0\"\n";

    qts = qtest_init_with_config(cfgdata);
    /* Test valid command */
    resp = qtest_qmp(qts,
                     "{ 'execute': 'qom-list',"
                     "  'arguments': {'path': '/objects' }}");
    test_object_available(qdict_get(resp, "return"), "rng0", "rng-builtin");
    qobject_unref(resp);

    qtest_quit(qts);
}

static void test_docs_config_ich9(void)
{
    QTestState *qts;
    QDict *resp;
    QObject *qobj;

    qts = qtest_initf("-nodefaults -readconfig docs/config/ich9-ehci-uhci.cfg");

    resp = qtest_qmp(qts, "{ 'execute': 'qom-list',"
                          "  'arguments': {'path': '/machine/peripheral' }}");
    qobj = qdict_get(resp, "return");
    test_object_available(qobj, "ehci", "ich9-usb-ehci1");
    test_object_available(qobj, "uhci-1", "ich9-usb-uhci1");
    test_object_available(qobj, "uhci-2", "ich9-usb-uhci2");
    test_object_available(qobj, "uhci-3", "ich9-usb-uhci3");
    qobject_unref(resp);

    qtest_quit(qts);
}

int main(int argc, char *argv[])
{
    const char *arch;
    g_test_init(&argc, &argv, NULL);

    arch = qtest_get_arch();

    if (g_str_equal(arch, "i386") ||
        g_str_equal(arch, "x86_64")) {
        qtest_add_func("readconfig/x86/memdev", test_x86_memdev);
        if (qtest_has_device("ich9-usb-ehci1") &&
            qtest_has_device("ich9-usb-uhci1")) {
            qtest_add_func("readconfig/x86/ich9-ehci-uhci", test_docs_config_ich9);
        }
    }
#if defined(CONFIG_SPICE) && !defined(__FreeBSD__)
    qtest_add_func("readconfig/spice", test_spice);
#endif

    qtest_add_func("readconfig/object-rng", test_object_rng);

    return g_test_run();
}
