#include <Core/HAL/DynLib/DynamicLibrary.h>
#include <Core/HAL/Win32.h>
#include <Core/Logging/LogManager.h>
#include <Core/Logging/LogTypes.h>

namespace Juliet
{
    DynamicLibrary* LoadDynamicLibrary(const char* filename)
    {
        if (!filename)
        {
            Log(LogLevel::Error, LogCategory::Core, "Library filename is invalid (empty)");
            return nullptr;
        }

        HMODULE handle = LoadLibraryA(filename);

        // Generate an error message if all loads failed
        if (!handle)
        {
            Log(LogLevel::Error, LogCategory::Core, "Failed loading %s", filename);
            return nullptr;
        }
        return reinterpret_cast<DynamicLibrary*>(handle);
    }

    FunctionPtr LoadFunction(NonNullPtr<DynamicLibrary> lib, const char* functionName)
    {
#pragma warning(push)
#pragma warning(disable: 4191) // Disable "unsafe conversion from FARPROC"
        auto function = reinterpret_cast<FunctionPtr>(GetProcAddress(reinterpret_cast<HMODULE>(lib.Get()), functionName));
        if (!function)
        {
            Log(LogLevel::Error, LogCategory::Core, "Failed loading %s", functionName);
        }
        return function;
#pragma warning(pop)
    }

    void UnloadDynamicLibrary(NonNullPtr<DynamicLibrary> lib)
    {
        FreeLibrary(reinterpret_cast<HMODULE>(lib.Get()));
    }
} // namespace Juliet
