/* 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 "internal.h"  /* for UNUSED_P only */
#include "minicheck.h"

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

TCase *
tcase_create(const 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 UNUSED_P(condition), const char *UNUSED_P(file), int UNUSED_P(line), const 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);
}
