#ifndef TUT_RESULT_H_GUARD
#define TUT_RESULT_H_GUARD

#if defined(TUT_USE_POSIX)
#include <sys/types.h>
#include <unistd.h>
#endif

#include <string>

namespace tut
{

#if defined(TUT_USE_POSIX)
struct test_result_posix
{
    test_result_posix() : pid(getpid())
    {
    }

    pid_t pid;
};
#else
struct test_result_posix
{
};
#endif

/**
 * Return type of ran test/test group.
 *
 * For test: contains result of test and, possible, message
 * for failure or exception.
 */
struct test_result : public test_result_posix
{
    /**
     * Test group name.
     */
    std::string group;

    /**
     * Test number in group.
     */
    int test;

    /**
     * Test name (optional)
     */
    std::string name;

    /**
     * ok - test finished successfully
     * fail - test failed with ensure() or fail() methods
     * ex - test thrown an exceptions
     * warn - test finished successfully, but test destructor thrown
     * term - test forced test application to terminate abnormally
     */
    enum result_type
    {
        ok,
        fail,
        ex,
        warn,
        term,
        ex_ctor,
        rethrown,
        dummy
    };

    result_type result;

    /**
     * Exception message for failed test.
     */
    std::string message;
    std::string exception_typeid;

    /**
     * Default constructor.
     */
    test_result() : test(0), result(ok)
    {
    }

    /**
     * Constructor.
     */
    test_result(const std::string &grp, int pos, const std::string &test_name,
                result_type res)
        : group(grp), test(pos), name(test_name), result(res)
    {
    }

    /**
     * Constructor with exception.
     */
    test_result(const std::string &grp, int pos, const std::string &test_name,
                result_type res, const std::exception &exIn)
        : group(grp), test(pos), name(test_name), result(res),
          message(exIn.what()), exception_typeid(typeid(exIn).name())
    {
    }

    /** Constructor with typeid.
     */
    test_result(const std::string &grp, int pos, const std::string &test_name,
                result_type res, const std::string &ex_typeid,
                const std::string &msg)
        : group(grp), test(pos), name(test_name), result(res), message(msg),
          exception_typeid(ex_typeid)
    {
    }
};

}  // namespace tut

#endif
