/* Miniature re-implementation of the "check" library.
 *
 * This is intended to support just enough of check to run the Expat
 * tests.  This interface is based entirely on the portion of the
 * check library being used.
 */

#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>
#include <assert.h>

#include "minicheck.h"

Suite *
suite_create(char *name)
{
    Suite *suite = (Suite *) calloc(1, sizeof(Suite));
    if (suite != NULL) {
        suite->name = name;
    }
    return suite;
}

TCase *
tcase_create(char *name)
{
    TCase *tc = (TCase *) calloc(1, sizeof(TCase));
    if (tc != NULL) {
        tc->name = name;
    }
    return tc;
}

void
suite_add_tcase(Suite *suite, TCase *tc) 
{
    assert(suite != NULL);
    assert(tc != NULL);
    assert(tc->next_tcase == NULL);

    tc->next_tcase = suite->tests;
    suite->tests = tc;
}

void
tcase_add_checked_fixture(TCase *tc,
                          tcase_setup_function setup,
                          tcase_teardown_function teardown)
{
    assert(tc != NULL);
    tc->setup = setup;
    tc->teardown = teardown;
}

void
tcase_add_test(TCase *tc, tcase_test_function test)
{
    assert(tc != NULL);
    if (tc->allocated == tc->ntests) {
        int nalloc = tc->allocated + 100;
        size_t new_size = sizeof(tcase_test_function) * nalloc;
        tcase_test_function *new_tests = realloc(tc->tests, new_size);
        assert(new_tests != NULL);
        if (new_tests != tc->tests) {
            free(tc->tests);
            tc->tests = new_tests;
        }
        tc->allocated = nalloc;
    }
    tc->tests[tc->ntests] = test;
    tc->ntests++;
}

SRunner *
srunner_create(Suite *suite)
{
    SRunner *runner = calloc(1, sizeof(SRunner));
    if (runner != NULL) {
        runner->suite = suite;
    }
    return runner;
}

static jmp_buf env;

static char const *_check_current_function = NULL;
static int _check_current_lineno = -1;
static char const *_check_current_filename = NULL;

void
_check_set_test_info(char const *function, char const *filename, int lineno)
{
    _check_current_function = function;
    _check_current_lineno = lineno;
    _check_current_filename = filename;
}


static void
add_failure(SRunner *runner, int verbosity)
{
    runner->nfailures++;
    if (verbosity >= CK_VERBOSE) {
        printf("%s:%d: %s\n", _check_current_filename,
               _check_current_lineno, _check_current_function);
    }
}

void
srunner_run_all(SRunner *runner, int verbosity)
{
    Suite *suite;
    TCase *tc;
    assert(runner != NULL);
    suite = runner->suite;
    tc = suite->tests;
    while (tc != NULL) {
        int i;
        for (i = 0; i < tc->ntests; ++i) {
            runner->nchecks++;

            if (tc->setup != NULL) {
                /* setup */
                if (setjmp(env)) {
                    add_failure(runner, verbosity);
                    continue;
                }
                tc->setup();
            }
            /* test */
            if (setjmp(env)) {
                add_failure(runner, verbosity);
                continue;
            }
            (tc->tests[i])();

            /* teardown */
            if (tc->teardown != NULL) {
                if (setjmp(env)) {
                    add_failure(runner, verbosity);
                    continue;
                }
                tc->teardown();
            }
        }
        tc = tc->next_tcase;
    }
    if (verbosity) {
        int passed = runner->nchecks - runner->nfailures;
        double percentage = ((double) passed) / runner->nchecks;
        int display = (int) (percentage * 100);
        printf("%d%%: Checks: %d, Failed: %d\n",
               display, runner->nchecks, runner->nfailures);
    }
}

void
_fail_unless(int condition, const char *file, int line, char *msg)
{
    /* Always print the error message so it isn't lost.  In this case,
       we have a failure, so there's no reason to be quiet about what
       it is.
    */
    if (msg != NULL)
        printf("%s", msg);
    longjmp(env, 1);
}

int
srunner_ntests_failed(SRunner *runner)
{
    assert(runner != NULL);
    return runner->nfailures;
}

void
srunner_free(SRunner *runner)
{
    free(runner->suite);
    free(runner);
}
