/*********************************************************************
 * \file   Log.cpp
 *
 * \author Romain BOULLARD
 * \date   December 2022
 *********************************************************************/
#include <Utils/Log/Log.hpp>

#include <Utils/Singleton.hpp>

#include <UtilsTests/UtilsTestsLogger_generated.hpp>

#if defined BIGFOOT_NOT_OPTIMIZED

#include <gtest/gtest.h>

namespace Bigfoot
{
class LogFixture: public ::testing::Test
{
  protected:
    static constexpr Flat::LogLevel QuillLogLevelToLogLevel(const quill::LogLevel p_level)
    {
        switch (p_level)
        {
        case quill::LogLevel::Debug:
            return Flat::LogLevel::Debug;
        case quill::LogLevel::TraceL3:
            return Flat::LogLevel::Trace;
        case quill::LogLevel::Info:
            return Flat::LogLevel::Info;
        case quill::LogLevel::Warning:
            return Flat::LogLevel::Warn;
        case quill::LogLevel::Error:
            return Flat::LogLevel::Error;
        case quill::LogLevel::Critical:
            return Flat::LogLevel::Critical;
        default:
            break;
        }

        return Flat::LogLevel::Trace;
    }
};

/****************************************************************************************/

TEST_F(LogFixture, RegisterLogger_ShouldRegisterTheLogger)
{
    const quill::Logger* logger = Singleton<Log>::GetInstance().RegisterLogger(UTILSTESTS_LOGGER);
    EXPECT_TRUE(logger);
    EXPECT_EQ(logger, Singleton<Log>::GetInstance().GetLogger(UTILSTESTS_LOGGER));
    EXPECT_EQ(logger->get_logger_name(), UTILSTESTS_LOGGER.m_name);
    EXPECT_EQ(QuillLogLevelToLogLevel(logger->get_log_level()), UTILSTESTS_LOGGER.m_level);
}

/****************************************************************************************/

TEST_F(LogFixture, UnregisterLogger_ShouldUnregisterTheLogger)
{
    std::ignore = Singleton<Log>::GetInstance().RegisterLogger(UTILSTESTS_LOGGER);
    Singleton<Log>::GetInstance().UnregisterLogger(UTILSTESTS_LOGGER);

    EXPECT_EQ(Singleton<Log>::GetInstance().GetLogger(UTILSTESTS_LOGGER), nullptr);
}

/****************************************************************************************/

TEST_F(LogFixture, GetLogger_ShouldReturnNullptrIfTheLoggerDoesNotExist)
{
    EXPECT_FALSE(Singleton<Log>::GetInstance().GetLogger(UTILSTESTS_LOGGER));
}

/****************************************************************************************/

TEST_F(LogFixture, GetLoger_ShouldReturnTheLoggerIfItExists)
{
    [[maybe_unused]]
    const quill::Logger* logger = Singleton<Log>::GetInstance().RegisterLogger(UTILSTESTS_LOGGER);
    EXPECT_TRUE(Singleton<Log>::GetInstance().GetLogger(UTILSTESTS_LOGGER));
}

/****************************************************************************************/

TEST_F(LogFixture, ChangeLoggerLogLevel_ShouldChangeTheLoggerLogLevel)
{
    const Flat::LogLevel previous = UTILSTESTS_LOGGER.m_level;

    const quill::Logger* logger = Singleton<Log>::GetInstance().RegisterLogger(UTILSTESTS_LOGGER);

    Singleton<Log>::GetInstance().ChangeLoggerLogLevel(UTILSTESTS_LOGGER, Flat::LogLevel::Critical);
    EXPECT_EQ(QuillLogLevelToLogLevel(logger->get_log_level()), Flat::LogLevel::Critical);
    Singleton<Log>::GetInstance().ChangeLoggerLogLevel(UTILSTESTS_LOGGER, previous);
    EXPECT_EQ(QuillLogLevelToLogLevel(logger->get_log_level()), previous);
}
}   // namespace Bigfoot
#endif
