/*
 * QDict unit-tests.
 *
 * Copyright (C) 2009 Red Hat Inc.
 *
 * Authors:
 *  Luiz Capitulino <lcapitulino@redhat.com>
 */
#include <check.h>

#include "qint.h"
#include "qdict.h"
#include "qstring.h"
#include "qemu-common.h"

/*
 * Public Interface test-cases
 *
 * (with some violations to access 'private' data)
 */

START_TEST(qdict_new_test)
{
    QDict *qdict;

    qdict = qdict_new();
    fail_unless(qdict != NULL);
    fail_unless(qdict_size(qdict) == 0);
    fail_unless(qdict->base.refcnt == 1);
    fail_unless(qobject_type(QOBJECT(qdict)) == QTYPE_QDICT);

    // destroy doesn't exit yet
    free(qdict);
}
END_TEST

START_TEST(qdict_put_obj_test)
{
    QInt *qi;
    QDict *qdict;
    QDictEntry *ent;
    const int num = 42;

    qdict = qdict_new();

    // key "" will have tdb hash 12345
    qdict_put_obj(qdict, "", QOBJECT(qint_from_int(num)));

    fail_unless(qdict_size(qdict) == 1);
    ent = QLIST_FIRST(&qdict->table[12345 % QDICT_HASH_SIZE]);
    qi = qobject_to_qint(ent->value);
    fail_unless(qint_get_int(qi) == num);

    // destroy doesn't exit yet
    QDECREF(qi);
    qemu_free(ent->key);
    qemu_free(ent);
    qemu_free(qdict);
}
END_TEST

START_TEST(qdict_destroy_simple_test)
{
    QDict *qdict;

    qdict = qdict_new();
    qdict_put_obj(qdict, "num", QOBJECT(qint_from_int(0)));
    qdict_put_obj(qdict, "str", QOBJECT(qstring_from_str("foo")));

    QDECREF(qdict);
}
END_TEST

static QDict *tests_dict = NULL;

static void qdict_setup(void)
{
    tests_dict = qdict_new();
    fail_unless(tests_dict != NULL);
}

static void qdict_teardown(void)
{
    QDECREF(tests_dict);
    tests_dict = NULL;
}

START_TEST(qdict_get_test)
{
    QInt *qi;
    QObject *obj;
    const int value = -42;
    const char *key = "test";

    qdict_put(tests_dict, key, qint_from_int(value));

    obj = qdict_get(tests_dict, key);
    fail_unless(obj != NULL);

    qi = qobject_to_qint(obj);
    fail_unless(qint_get_int(qi) == value);
}
END_TEST

START_TEST(qdict_get_int_test)
{
    int ret;
    const int value = 100;
    const char *key = "int";

    qdict_put(tests_dict, key, qint_from_int(value));

    ret = qdict_get_int(tests_dict, key);
    fail_unless(ret == value);
}
END_TEST

START_TEST(qdict_get_try_int_test)
{
    int ret;
    const int value = 100;
    const char *key = "int";

    qdict_put(tests_dict, key, qint_from_int(value));

    ret = qdict_get_try_int(tests_dict, key, 0);
    fail_unless(ret == value);
}
END_TEST

START_TEST(qdict_get_str_test)
{
    const char *p;
    const char *key = "key";
    const char *str = "string";

    qdict_put(tests_dict, key, qstring_from_str(str));

    p = qdict_get_str(tests_dict, key);
    fail_unless(p != NULL);
    fail_unless(strcmp(p, str) == 0);
}
END_TEST

START_TEST(qdict_get_try_str_test)
{
    const char *p;
    const char *key = "key";
    const char *str = "string";

    qdict_put(tests_dict, key, qstring_from_str(str));

    p = qdict_get_try_str(tests_dict, key);
    fail_unless(p != NULL);
    fail_unless(strcmp(p, str) == 0);
}
END_TEST

START_TEST(qdict_haskey_not_test)
{
    fail_unless(qdict_haskey(tests_dict, "test") == 0);
}
END_TEST

START_TEST(qdict_haskey_test)
{
    const char *key = "test";

    qdict_put(tests_dict, key, qint_from_int(0));
    fail_unless(qdict_haskey(tests_dict, key) == 1);
}
END_TEST

START_TEST(qdict_del_test)
{
    const char *key = "key test";

    qdict_put(tests_dict, key, qstring_from_str("foo"));
    fail_unless(qdict_size(tests_dict) == 1);

    qdict_del(tests_dict, key);

    fail_unless(qdict_size(tests_dict) == 0);
    fail_unless(qdict_haskey(tests_dict, key) == 0);
}
END_TEST

START_TEST(qobject_to_qdict_test)
{
    fail_unless(qobject_to_qdict(QOBJECT(tests_dict)) == tests_dict);
}
END_TEST

/*
 * Errors test-cases
 */

START_TEST(qdict_put_exists_test)
{
    int value;
    const char *key = "exists";

    qdict_put(tests_dict, key, qint_from_int(1));
    qdict_put(tests_dict, key, qint_from_int(2));

    value = qdict_get_int(tests_dict, key);
    fail_unless(value == 2);

    fail_unless(qdict_size(tests_dict) == 1);
}
END_TEST

START_TEST(qdict_get_not_exists_test)
{
    fail_unless(qdict_get(tests_dict, "foo") == NULL);
}
END_TEST

/*
 * Stress test-case
 *
 * This is a lot big for a unit-test, but there is no other place
 * to have it.
 */

static void remove_dots(char *string)
{
    char *p = strchr(string, ':');
    if (p)
        *p = '\0';
}

static QString *read_line(FILE *file, char *key)
{
    char value[128];

    if (fscanf(file, "%s%s", key, value) == EOF)
        return NULL;
    remove_dots(key);
    return qstring_from_str(value);
}

#define reset_file(file)    fseek(file, 0L, SEEK_SET)

START_TEST(qdict_stress_test)
{
    size_t lines;
    char key[128];
    FILE *test_file;
    QDict *qdict;
    QString *value;
    const char *test_file_path = "qdict-test-data.txt";

    test_file = fopen(test_file_path, "r");
    fail_unless(test_file != NULL);

    // Create the dict
    qdict = qdict_new();
    fail_unless(qdict != NULL);

    // Add everything from the test file
    for (lines = 0;; lines++) {
        value = read_line(test_file, key);
        if (!value)
            break;

        qdict_put(qdict, key, value);
    }
    fail_unless(qdict_size(qdict) == lines);

    // Check if everything is really in there
    reset_file(test_file);
    for (;;) {
        const char *str1, *str2;

        value = read_line(test_file, key);
        if (!value)
            break;

        str1 = qstring_get_str(value);

        str2 = qdict_get_str(qdict, key);
        fail_unless(str2 != NULL);

        fail_unless(strcmp(str1, str2) == 0);

        QDECREF(value);
    }

    // Delete everything
    reset_file(test_file);
    for (;;) {
        value = read_line(test_file, key);
        if (!value)
            break;

        qdict_del(qdict, key);
        QDECREF(value);

        fail_unless(qdict_haskey(qdict, key) == 0);
    }
    fclose(test_file);

    fail_unless(qdict_size(qdict) == 0);
    QDECREF(qdict);
}
END_TEST

static Suite *qdict_suite(void)
{
    Suite *s;
    TCase *qdict_public_tcase;
    TCase *qdict_public2_tcase;
    TCase *qdict_stress_tcase;
    TCase *qdict_errors_tcase;

    s = suite_create("QDict test-suite");

    qdict_public_tcase = tcase_create("Public Interface");
    suite_add_tcase(s, qdict_public_tcase);
    tcase_add_test(qdict_public_tcase, qdict_new_test);
    tcase_add_test(qdict_public_tcase, qdict_put_obj_test);
    tcase_add_test(qdict_public_tcase, qdict_destroy_simple_test);

    /* Continue, but now with fixtures */
    qdict_public2_tcase = tcase_create("Public Interface (2)");
    suite_add_tcase(s, qdict_public2_tcase);
    tcase_add_checked_fixture(qdict_public2_tcase, qdict_setup, qdict_teardown);
    tcase_add_test(qdict_public2_tcase, qdict_get_test);
    tcase_add_test(qdict_public2_tcase, qdict_get_int_test);
    tcase_add_test(qdict_public2_tcase, qdict_get_try_int_test);
    tcase_add_test(qdict_public2_tcase, qdict_get_str_test);
    tcase_add_test(qdict_public2_tcase, qdict_get_try_str_test);
    tcase_add_test(qdict_public2_tcase, qdict_haskey_not_test);
    tcase_add_test(qdict_public2_tcase, qdict_haskey_test);
    tcase_add_test(qdict_public2_tcase, qdict_del_test);
    tcase_add_test(qdict_public2_tcase, qobject_to_qdict_test);

    qdict_errors_tcase = tcase_create("Errors");
    suite_add_tcase(s, qdict_errors_tcase);
    tcase_add_checked_fixture(qdict_errors_tcase, qdict_setup, qdict_teardown);
    tcase_add_test(qdict_errors_tcase, qdict_put_exists_test);
    tcase_add_test(qdict_errors_tcase, qdict_get_not_exists_test);

    /* The Big one */
    qdict_stress_tcase = tcase_create("Stress Test");
    suite_add_tcase(s, qdict_stress_tcase);
    tcase_add_test(qdict_stress_tcase, qdict_stress_test);

    return s;
}

int main(void)
{
	int nf;
	Suite *s;
	SRunner *sr;

	s = qdict_suite();
	sr = srunner_create(s);

	srunner_run_all(sr, CK_NORMAL);
	nf = srunner_ntests_failed(sr);
	srunner_free(sr);

	return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}
