#include "common.hpp"
#include "config.hpp"
#include "hooks.hpp"
#include <cppunit/CompilerOutputter.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <cppunit/TestResult.h>
#include <cppunit/TestResultCollector.h>
#include <cppunit/TestRunner.h>
#include <cppunit/BriefTestProgressListener.h>


bool cppunit_run() {
    // inform test-listener about results
    CPPUNIT_NS::TestResult testresult;

    // register listener for collecting results
    CPPUNIT_NS::TestResultCollector collectedresults;
    testresult.addListener(&collectedresults);

    // listener for printing results of the tests
    CPPUNIT_NS::BriefTestProgressListener progress;
    testresult.addListener(&progress);

    // add test-suite to test-runner's registry
    CPPUNIT_NS::TestRunner testrunner;
    testrunner.addTest(CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest());
    testrunner.run(testresult);

    // print results in compiler-format
    CPPUNIT_NS::CompilerOutputter compileroutputter(&collectedresults, std::cerr);
    compileroutputter.write();

    // report if successful
    return collectedresults.wasSuccessful();
}


int main (int argc, char* argv[]) {
    if (argc != 2) {
        STDERR("Usage: %s <config-file>", argv[0]);
        return 1;
    }
    Hooks::run(Hooks::INIT);
    Config* global_config = new Config(argv[1]);
    if (!global_config->load()) {
        log(error, "cannot load config '%s'", global_config->fn);
        delete global_config;
        Hooks::run(Hooks::DEINIT);
        return 1;
    }

    Hooks::run(Hooks::PRE_IO);

    bool rv = cppunit_run();
    STDERR("%stests %s" TERM_RESET, rv? TERM_GREEN: TERM_RED, rv? "successful": "failed");

    Hooks::run(Hooks::POST_IO);
    delete global_config;
    Hooks::run(Hooks::DEINIT);
    return rv? 0: 1;
}