#include <Core/Logging/LogManager.h>
#include <Core/Logging/LogTypes.h>
#include <Core/Memory/Allocator.h>

#include <comdef.h> // For _com_error to decode HRESULTs
#include <intrin.h> // For __debugbreak

namespace Juliet
{
    void JulietAssert(const char* expression, const char* message, std::source_location location, long handleResult)
    {
        Log(LogLevel::Error, LogCategory::Core, "--- ASSERTION FAILED ---");
        Log(LogLevel::Error, LogCategory::Core, "Expression: %s", expression);
        Log(LogLevel::Error, LogCategory::Core, "Message:    %s", message);
        Log(LogLevel::Error, LogCategory::Core, "Location:   %s(%u): %s", location.file_name(), location.line(),
            location.function_name());

        if (handleResult < 0)
        {
            _com_error err(handleResult);
            // Using %ls because ErrorMessage() returns a wide string (wchar_t*)
            Log(LogLevel::Error, LogCategory::Graphics, "HRESULT:    0x%08X (%ls)", handleResult, err.ErrorMessage());
        }

        Log(LogLevel::Error, LogCategory::Core, "-------------------------");

        JULIET_PLATFORM_BREAK();
    }

    void Free(ByteBuffer& buffer)
    {
        if (buffer.Data)
        {
            Free(buffer.Data);
        }
        buffer = {};
    }
} // namespace Juliet
