#include "../../src/ErrorSimulator.hpp"
#include "../Tests.hpp"
#include "core/utils/Utility.hpp"

static void testPopCount() {
    CORE_TEST_EQUAL(4, Core::popCount(0xF));
    CORE_TEST_EQUAL(0, Core::popCount(0x0));
    CORE_TEST_EQUAL(2, Core::popCount(0x6));
    CORE_TEST_EQUAL(7, Core::popCount(0x7F));
    CORE_TEST_EQUAL(3, Core::popCount(0x2A));
    CORE_TEST_EQUAL(32, Core::popCount(0xFFFFFFFF));
    CORE_TEST_EQUAL(64, Core::popCount(0xFFFFFFFFFFFFFFFFL));
    CORE_TEST_EQUAL(44, Core::popCount(0xFFFF0FFFFFFF));
    CORE_TEST_EQUAL(32, Core::popCount(-1));
}

static void testIf() {
    CORE_TEST_TRUE((Core::IsSame<Core::If<true, int, double>, int>));
    CORE_TEST_TRUE((Core::IsSame<Core::If<false, int, double>, double>));
}

static void testNegativeArguments() {
    char from[16];
    Core::memorySet(from, 1, sizeof(from));
    Core::memorySet(from, 0, -1);
    char to[16];
    Core::memorySet(to, 1, sizeof(to));
    Core::memoryCopy(to, from, -1);
    CORE_TEST_TRUE(Core::memoryCompare(from, to, sizeof(from)));
}

static void testNegativeRellocate() {
    char* buffer = nullptr;
    CORE_TEST_ERROR(Core::reallocate(buffer, 16));
    CORE_TEST_TRUE(buffer != nullptr);
    CORE_TEST_ERROR(Core::reallocate(buffer, -1));
    CORE_TEST_TRUE(buffer == nullptr);
}

static void testReallocateFail() {
    char* buffer = nullptr;
    Core::Fail::realloc = true;
    CORE_TEST_EQUAL(Core::Error::OUT_OF_MEMORY, Core::reallocate(buffer, 16));
    CORE_TEST_TRUE(buffer == nullptr);
    Core::Fail::realloc = false;
}

void Core::testUtility() {
    testPopCount();
    testIf();
    testNegativeArguments();
    testNegativeRellocate();
    testReallocateFail();
}