#include "tests/ThreadTests.hpp"

#include "test/Test.hpp"
#include "thread/Thread.hpp"

static int runDone = 0;

struct IntHolder {
    int value;
};

static int run(void*) {
    runDone = 1;
    return 7;
}

static void testStart() {
    runDone = 0;
    Core::Thread t;
    CORE_TEST_ERROR(t.start(run, nullptr));
    int returnValue = 0;
    CORE_TEST_ERROR(t.join(&returnValue));
    CORE_TEST_EQUAL(1, runDone);
    CORE_TEST_EQUAL(7, returnValue);
}

static void testLambda() {
    IntHolder i(0);
    Core::Thread t;
    CORE_TEST_ERROR(t.start(
        [](void* p) {
            IntHolder* ip = static_cast<IntHolder*>(p);
            ip->value = 2;
            return 0;
        },
        &i));
    CORE_TEST_ERROR(t.join(nullptr));
    CORE_TEST_EQUAL(2, i.value);
}

static void testJoinWithoutStart() {
    Core::Thread t;
    CORE_TEST_EQUAL(Core::Error::THREAD_ERROR, t.join(nullptr));
}

void Core::ThreadTests::test() {
    testStart();
    testLambda();
    testJoinWithoutStart();
}