/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define NOMINMAX
#include "logunit.h"

#include <log4cxx/loggerinstance.h>
#include <log4cxx/logmanager.h>
#include <log4cxx/simplelayout.h>
#include "vectorappender.h"
#include <log4cxx/asyncappender.h>
#include "appenderskeletontestcase.h"
#include <log4cxx/helpers/loglog.h>
#include <log4cxx/helpers/pool.h>
#include <log4cxx/helpers/transcoder.h>
#include <log4cxx/varia/fallbackerrorhandler.h>
#include <apr_strings.h>
#include "testchar.h"
#include <log4cxx/helpers/stringhelper.h>
#include <log4cxx/spi/location/locationinfo.h>
#include <log4cxx/xml/domconfigurator.h>
#include <log4cxx/propertyconfigurator.h>
#include <log4cxx/fileappender.h>
#include <log4cxx/file.h>
#include <ostream>
#include <thread>
#include <fstream>

#if LOG4CXX_ASYNC_BUFFER_SUPPORTS_FMT
#include <fmt/core.h>
#include <fmt/ostream.h>
#if LOG4CXX_WCHAR_T_API || LOG4CXX_LOGCHAR_IS_WCHAR
#include <fmt/xchar.h>
#endif
struct MyStruct
{
	int value;
};
using OutputStreamType = std::basic_ostream<LOG4CXX_NS::logchar>;
OutputStreamType& operator<<(OutputStreamType& stream, const MyStruct& data)
{
	stream << LOG4CXX_STR("[MyStruct value: ") << data.value << LOG4CXX_STR("]");
	return stream;
}

#if FMT_VERSION >= (9 * 10000)
template <> struct fmt::formatter<MyStruct, LOG4CXX_NS::logchar> : fmt::basic_ostream_formatter<LOG4CXX_NS::logchar> {};
#endif
#endif

using namespace LOG4CXX_NS;
using namespace LOG4CXX_NS::helpers;
using namespace LOG4CXX_NS::spi;

class NullPointerAppender : public AppenderSkeleton
{
	public:
		NullPointerAppender()
		{
		}


		/**
		 * @{inheritDoc}
		 */
		void append(const spi::LoggingEventPtr&, LOG4CXX_NS::helpers::Pool&) override
		{
			throw RuntimeException(LOG4CXX_STR("Intentional Exception"));
		}

		void close() override
		{
		}

		bool requiresLayout() const override
		{
			return false;
		}
};

/**
 * Vector appender that can be explicitly blocked.
 */
class BlockableVectorAppender : public VectorAppender
{
	private:
		std::mutex blocker;
	public:
		/**
		 * Create new instance.
		 */
		BlockableVectorAppender()
		{
		}

		/**
		 * {@inheritDoc}
		 */
		void append(const spi::LoggingEventPtr& event, LOG4CXX_NS::helpers::Pool& p) override
		{
			std::lock_guard<std::mutex> lock( blocker );
			VectorAppender::append(event, p);
		}

		std::mutex& getBlocker()
		{
			return blocker;
		}

};
LOG4CXX_PTR_DEF(BlockableVectorAppender);

/**
 * An appender that adds logging events
 */
class LoggingVectorAppender : public VectorAppender
{
	LoggerInstancePtr logger{ "LoggingVectorAppender" };
	void append(const spi::LoggingEventPtr& event, LOG4CXX_NS::helpers::Pool& p) override
	{
		auto& lsMsg = event->getRenderedMessage();
		VectorAppender::append(event, p);
		if (LogString::npos != lsMsg.find(LOG4CXX_STR("World")))
		{
			LOG4CXX_LOGLS(logger, Level::getError(), LOG4CXX_STR("Some appender error"));
			LOG4CXX_LOGLS(logger, Level::getWarn(), LOG4CXX_STR("Some appender warning"));
			LOG4CXX_LOGLS(logger, Level::getInfo(), LOG4CXX_STR("Some appender information"));
			LOG4CXX_LOGLS(logger, Level::getDebug(), LOG4CXX_STR("Some appender detailed data"));
		}
	}
};
LOG4CXX_PTR_DEF(LoggingVectorAppender);

/**
 * Tests of AsyncAppender.
 */
class AsyncAppenderTestCase : public AppenderSkeletonTestCase
{
		LOGUNIT_TEST_SUITE(AsyncAppenderTestCase);
		//
		// tests inherited from AppenderSkeletonTestCase
		//
		LOGUNIT_TEST(testDefaultThreshold);
		LOGUNIT_TEST(testSetOptionThreshold);

		LOGUNIT_TEST(closeTest);
		LOGUNIT_TEST(testAutoMessageBufferSelection);
		LOGUNIT_TEST(testEventFlush);
		LOGUNIT_TEST(testMultiThread);
		LOGUNIT_TEST(testBadAppender);
		LOGUNIT_TEST(testBufferOverflowBehavior);
		LOGUNIT_TEST(testLoggingAppender);
#if LOG4CXX_HAS_DOMCONFIGURATOR
		LOGUNIT_TEST(testXMLConfiguration);
		LOGUNIT_TEST(testAsyncLoggerXML);
		LOGUNIT_TEST(testRecursiveConfiguration);
#endif
#if ENABLE_FAILING_APPENDER_SIMULATION_TESTING
		LOGUNIT_TEST(testAsyncAppenderFallback);
#endif
		LOGUNIT_TEST(testAsyncLoggerProperties);
#if LOG4CXX_ASYNC_BUFFER_SUPPORTS_FMT
		LOGUNIT_TEST(testAsyncFmtLogging);
#endif // LOG4CXX_ASYNC_BUFFER_SUPPORTS_FMT
		LOGUNIT_TEST_SUITE_END();

#ifdef _DEBUG
	struct Fixture
	{
		Fixture() {
			helpers::LogLog::setInternalDebugging(true);
		}
	} suiteFixture;
#endif

	public:
		void setUp() override
		{
			AppenderSkeletonTestCase::setUp();
		}

		void tearDown() override
		{
			LogManager::shutdown();
			AppenderSkeletonTestCase::tearDown();
		}

		AppenderSkeleton* createAppenderSkeleton() const override
		{
			return new AsyncAppender();
		}

		// Check it is not possible to write to a closed AsyncAppender
		void closeTest()
		{
			AsyncAppenderPtr asyncAppender;
			auto r = LogManager::getLoggerRepository();
			r->ensureIsConfigured([r, &asyncAppender]()
			{
				asyncAppender = std::make_shared<AsyncAppender>();
				asyncAppender->setName(LOG4CXX_STR("async-CloseTest"));
				r->getRootLogger()->addAppender(asyncAppender);
				r->setConfigured(true);
			});
			LOGUNIT_ASSERT(asyncAppender);
			auto vectorAppender = std::make_shared<VectorAppender>();
			asyncAppender->addAppender(vectorAppender);

			auto root = r->getRootLogger();
			root->debug(LOG4CXX_TEST_STR("m1"));
			asyncAppender->close();
			root->debug(LOG4CXX_TEST_STR("m2"));

			// Check one message was received
			auto& v = vectorAppender->getVector();
			LOGUNIT_ASSERT_EQUAL(1, int(v.size()));
			// Check appender embedded within an AsyncAppender is also closed
			LOGUNIT_ASSERT(vectorAppender->isClosed());
		}

		// Test behaviour when logging with a char type that is not logchar
		void testAutoMessageBufferSelection()
		{
			// Configure Log4cxx
			VectorAppenderPtr vectorAppender;
			auto r = LogManager::getLoggerRepository();
			r->ensureIsConfigured([r, &vectorAppender]()
			{
				vectorAppender = std::make_shared<VectorAppender>();
				r->getRootLogger()->addAppender(vectorAppender);
				r->setConfigured(true);
			});
			LogString logStr = LOG4CXX_STR("Some logchar string ");
#if LOG4CXX_LOGCHAR_IS_UTF8
			std::wstring otherStr(L"Some non-logchar string ");
#else // !LOG4CXX_LOGCHAR_IS_UTF8
			std::string otherStr("Some non-logchar string ");
#endif // !LOG4CXX_LOGCHAR_IS_UTF8

			// Log some messages
			auto root = r->getRootLogger();
			LOG4CXX_INFO(root, logStr << 42);
			LOG4CXX_INFO_ASYNC(root, logStr << 42);
			int expectedEventCount = 2;
#if !LOG4CXX_LOGCHAR_IS_UTF8 || LOG4CXX_WCHAR_T_API
			LOG4CXX_INFO(root, otherStr << 42);
			++expectedEventCount;
#if LOG4CXX_CONCEPTS
			LOG4CXX_INFO_ASYNC(root, otherStr << 42);
			++expectedEventCount;
#endif // LOG4CXX_CONCEPTS
#endif // !LOG4CXX_LOGCHAR_IS_UTF8 || LOG4CXX_WCHAR_T_API

			// Check all messages were received
			auto& v = vectorAppender->getVector();
			for (auto& pEvent : v)
				LogLog::debug(pEvent->getRenderedMessage());
			LOGUNIT_ASSERT_EQUAL(expectedEventCount, int(v.size()));
			LOGUNIT_ASSERT_EQUAL(v[0]->getRenderedMessage(), v[1]->getRenderedMessage());
			if (4 <= expectedEventCount)
				LOGUNIT_ASSERT_EQUAL(v[2]->getRenderedMessage(), v[3]->getRenderedMessage());
#ifdef GENERATE_THE_STATIC_ASSERT_COMPILATION_ERROR
			struct AStruct
			{
				int value;
			} data{ 43 };
			LOG4CXX_INFO_ASYNC(root, "data.value=" << data);
#endif
		}

		// this test checks all messages are delivered when an AsyncAppender is closed
		void testEventFlush()
		{
			// Configure Log4cxx
			auto r = LogManager::getLoggerRepository();
			AsyncAppenderPtr asyncAppender;
			r->ensureIsConfigured([r, &asyncAppender]()
			{
				asyncAppender = std::make_shared<AsyncAppender>();
				asyncAppender->setName(LOG4CXX_STR("async-testEventFlush"));
				r->getRootLogger()->addAppender(asyncAppender);
				r->setConfigured(true);
			});
			LOGUNIT_ASSERT(asyncAppender);
			auto vectorAppender = std::make_shared<VectorAppender>();
			vectorAppender->setMillisecondDelay(1);
			asyncAppender->addAppender(vectorAppender);

			// Log some messages
			auto root = r->getRootLogger();
			size_t LEN = 200; // Larger than default buffer size (128)
			for (size_t i = 0; i < LEN; i++)
			{
				LOG4CXX_DEBUG_ASYNC(root, "message" << i);
			}
			asyncAppender->close();
			root->debug(LOG4CXX_STR("m2"));

			const std::vector<spi::LoggingEventPtr>& v = vectorAppender->getVector();
			LOGUNIT_ASSERT_EQUAL(LEN, v.size());
			Pool p;
			int i{ 0 };
			for (auto e : v)
			{
				LogString m(LOG4CXX_STR("message"));
				StringHelper::toString(i, p, m);
				LOGUNIT_ASSERT_EQUAL(m, e->getRenderedMessage());
				++i;
			}
			LOGUNIT_ASSERT_EQUAL(true, vectorAppender->isClosed());
		}


		// this test checks all messages are delivered from multiple threads
		void testMultiThread()
		{
			// Configure Log4cxx
			AsyncAppenderPtr asyncAppender;
			auto r = LogManager::getLoggerRepository();
			r->ensureIsConfigured([r, &asyncAppender]()
			{
				asyncAppender = std::make_shared<AsyncAppender>();
				asyncAppender->setName(LOG4CXX_STR("async-testMultiThread"));
				r->getRootLogger()->addAppender(asyncAppender);
				r->setConfigured(true);
			});
			LOGUNIT_ASSERT(asyncAppender);
			auto vectorAppender = std::make_shared<VectorAppender>();
			asyncAppender->addAppender(vectorAppender);

			// Log some messages
			int LEN = 2000; // Larger than default buffer size (128)
			auto threadCount = std::max(static_cast<int>(std::thread::hardware_concurrency() - 1), 2);
			auto root = r->getRootLogger();
			std::vector<std::thread> threads;
			for ( int x = 0; x < threadCount; x++ )
			{
				threads.emplace_back([root, LEN]()
				{
					for (int i = 0; i < LEN; i++)
					{
						LOG4CXX_DEBUG_ASYNC(root, "message" << i);
					}
				});
			}

			for ( auto& thr : threads )
			{
				if ( thr.joinable() )
				{
					thr.join();
				}
			}
			asyncAppender->close();

			// Check all message were received
			auto& v = vectorAppender->getVector();
			LOGUNIT_ASSERT_EQUAL(LEN*threadCount, (int)v.size());
			std::map<LogString, int> perThreadCount;
			std::vector<int> msgCount(LEN, 0);
			for (auto m : v)
			{
				auto i = StringHelper::toInt(m->getRenderedMessage().substr(7));
				LOGUNIT_ASSERT(0 <= i);
				LOGUNIT_ASSERT(i < LEN);
				++msgCount[i];
				++perThreadCount[m->getThreadName()];
			}
			LOGUNIT_ASSERT_EQUAL(threadCount, (int)perThreadCount.size());
			for (auto& item : perThreadCount)
			{
				LOGUNIT_ASSERT_EQUAL(item.second, LEN);
			}
			for (size_t i = 0; i < LEN; i++)
				LOGUNIT_ASSERT_EQUAL(msgCount[i], threadCount);
		}

		/**
		 * Checks that async will switch a bad appender to another appender.
		 */
		void testBadAppender()
		{
			// Configure Log4cxx
			AsyncAppenderPtr asyncAppender;
			auto r = LogManager::getLoggerRepository();
			r->ensureIsConfigured([r, &asyncAppender]()
			{
				asyncAppender = std::make_shared<AsyncAppender>();
				asyncAppender->setName(LOG4CXX_STR("async-testBadAppender"));
				asyncAppender->addAppender(std::make_shared<NullPointerAppender>());
				Pool p;
				asyncAppender->activateOptions(p);
				r->getRootLogger()->addAppender(asyncAppender);
				r->setConfigured(true);
			});
			LOGUNIT_ASSERT(asyncAppender);
			auto vectorAppender = std::make_shared<VectorAppender>();
			vectorAppender->setName(LOG4CXX_STR("async-memoryAppender"));
			auto root = r->getRootLogger();
			auto errorHandler = std::make_shared<varia::FallbackErrorHandler>();
			errorHandler->setAppender(asyncAppender);
			errorHandler->setBackupAppender(vectorAppender);
			errorHandler->setLogger(root);
			asyncAppender->setErrorHandler(errorHandler);

			// Log some messages
			LOG4CXX_INFO(root, "Message");
			std::this_thread::sleep_for( std::chrono::milliseconds( 30 ) );
			LOGUNIT_ASSERT(errorHandler->errorReported());
			LOG4CXX_INFO(root, "Message");

			// Check a message was received
			auto& v = vectorAppender->getVector();
			LOGUNIT_ASSERT(0 < v.size());
		}

		/**
		 * Tests behavior when the the async buffer overflows.
		 */
		void testBufferOverflowBehavior()
		{
			// Configure Log4cxx
			AsyncAppenderPtr async;
			auto r = LogManager::getLoggerRepository();
			r->ensureIsConfigured([r, &async]()
			{
				async = std::make_shared<AsyncAppender>();
				async->setName(LOG4CXX_STR("async-testBufferOverflowBehavior"));
				async->setBufferSize(5);
				async->setBlocking(false);
				Pool p;
				async->activateOptions(p);
				r->getRootLogger()->addAppender(async);
				r->setConfigured(true);
			});
			LOGUNIT_ASSERT(async);
			auto blockableAppender = std::make_shared<BlockableVectorAppender>();
			blockableAppender->setName(LOG4CXX_STR("async-blockableVector"));
			async->addAppender(blockableAppender);

			// Log some messages
			auto rootLogger = r->getRootLogger();
			LOG4CXX_INFO_ASYNC(rootLogger, "Hello, World"); // This causes the dispatch thread creation
			std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) ); // Wait for the dispatch thread  to be ready
			{
				std::lock_guard<std::mutex> sync(blockableAppender->getBlocker());

				for (int i = 0; i < 140; i++)
				{
					LOG4CXX_INFO_ASYNC(rootLogger, "Hello, World " << i);
				}

				LOG4CXX_ERROR_ASYNC(rootLogger, "That's all folks.");
			}
			async->close();

			// Check which messages were output
			auto& events = blockableAppender->getVector();
			LOGUNIT_ASSERT(!events.empty());
			LOGUNIT_ASSERT(events.size() <= 142);
			LoggingEventPtr initialEvent = events.front();
			LOGUNIT_ASSERT(initialEvent->getRenderedMessage() == LOG4CXX_STR("Hello, World"));
			std::map<LevelPtr, int> levelCount;
			int discardMessageCount{ 0 };
			LoggingEventPtr discardEvent;
			for (auto& e : events)
			{
				auto message = e->getRenderedMessage();
				LogLog::debug(message);
				++levelCount[e->getLevel()];
				if (message.substr(0, 10) == LOG4CXX_STR("Discarded "))
				{
					++discardMessageCount;
					discardEvent = e;
				}
			}
			if (helpers::LogLog::isDebugEnabled())
			{
				Pool p;
				LogString msg{ LOG4CXX_STR("messageCounts:") };
				for (auto& item : levelCount)
				{
					msg += LOG4CXX_STR(" ");
					msg += item.first->toString();
					msg += LOG4CXX_STR(" ");
					StringHelper::toString(item.second, p, msg);
				}
				msg += LOG4CXX_STR(" ");
				msg += LOG4CXX_STR("Discarded ");
				StringHelper::toString(discardMessageCount, p, msg);
				helpers::LogLog::debug(msg);
			}
			// Check this test has activated the discard logic
			LOGUNIT_ASSERT(1 <= discardMessageCount);
			LOGUNIT_ASSERT(5 < levelCount[Level::getInfo()]);
			// Check the discard message is the logging event of the highest level
			LOGUNIT_ASSERT_EQUAL(levelCount[Level::getError()], 1);
			LOGUNIT_ASSERT_EQUAL(discardEvent->getLevel(), Level::getError());
			// Check the discard message does not have location info
			LOGUNIT_ASSERT_EQUAL(LOG4CXX_NS::spi::LocationInfo::getLocationUnavailable().getClassName(),
				discardEvent->getLocationInformation().getClassName());
		}

		/**
		 * Tests behavior when the appender attached to a AsyncAppender adds logging events
		 */
		void testLoggingAppender()
		{
			// Configure Log4cxx
			AsyncAppenderPtr async;
			auto r = LogManager::getLoggerRepository();
			r->ensureIsConfigured([r, &async]()
			{
				async = std::make_shared<AsyncAppender>();
				async->setName(LOG4CXX_STR("withLoggingAppender"));
				async->setBufferSize(5);
				Pool p;
				async->activateOptions(p);
				r->getRootLogger()->addAppender(async);
				r->setConfigured(true);
			});
			LOGUNIT_ASSERT(async);
			auto loggingAppender = std::make_shared<LoggingVectorAppender>();
			loggingAppender->setName(LOG4CXX_STR("loggingAppender"));
			async->addAppender(loggingAppender);

			// Log some messages
			auto rootLogger = r->getRootLogger();
			LOG4CXX_INFO_ASYNC(rootLogger, "Hello, World"); // This causes the dispatch thread creation
			std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) ); // Wait for the dispatch thread  to be ready
			for (int i = 0; i < 10; i++)
			{
				LOG4CXX_INFO_ASYNC(rootLogger, "Hello, World " << i);
			}
			LOG4CXX_INFO_ASYNC(rootLogger, "Bye bye World");
			std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) ); // Wait for the dispatch thread take the above events
			async->close();

			// Check which messages were received
			auto& events = loggingAppender->getVector();
			std::map<LevelPtr, int> levelCount;
			int discardMessageCount{ 0 };
			int eventCount[] = { 0, 0 };
			for (auto& e : events)
			{
				++levelCount[e->getLevel()];
				auto message = e->getRenderedMessage();
				LogLog::debug(message);
				auto isAppenderMessage = (message.npos == message.find(LOG4CXX_STR("World")));
				++eventCount[isAppenderMessage];
				if (message.substr(0, 10) == LOG4CXX_STR("Discarded "))
				{
					++discardMessageCount;
					LOGUNIT_ASSERT(isAppenderMessage);
				}
			}
			if (helpers::LogLog::isDebugEnabled())
			{
				Pool p;
				LogString msg{ LOG4CXX_STR("messageCounts:") };
				msg += LOG4CXX_STR(" nonAppender ");
				StringHelper::toString(eventCount[0], p, msg);
				msg += LOG4CXX_STR(" appender ");
				StringHelper::toString(eventCount[1], p, msg);
				msg += LOG4CXX_STR(" discard ");
				StringHelper::toString(discardMessageCount, p, msg);
				LogLog::debug(msg);
			}
			LOGUNIT_ASSERT(12 < events.size());
			LOGUNIT_ASSERT_EQUAL(12, eventCount[0]);
		}

#if LOG4CXX_HAS_DOMCONFIGURATOR
		void testXMLConfiguration()
		{
			// Configure Log4cxx
			auto status = xml::DOMConfigurator::configure("input/xml/asyncAppender1.xml");
			LOGUNIT_ASSERT_EQUAL(status, spi::ConfigurationStatus::Configured);

			// Check configuration is as expected
			auto  root = Logger::getRootLogger();
			auto asyncAppender = LOG4CXX_NS::cast<AsyncAppender>(root->getAppender(LOG4CXX_STR("ASYNC")));
			LOGUNIT_ASSERT(asyncAppender);
			LOGUNIT_ASSERT_EQUAL(100, asyncAppender->getBufferSize());
			LOGUNIT_ASSERT_EQUAL(false, asyncAppender->getBlocking());
			LOGUNIT_ASSERT_EQUAL(true, asyncAppender->getLocationInfo());
			auto nestedAppenders = asyncAppender->getAllAppenders();
			LOGUNIT_ASSERT_EQUAL(1, int(nestedAppenders.size()));

			// Log some messages
			size_t LEN = 20;
			for (size_t i = 0; i < LEN; i++)
			{
				LOG4CXX_DEBUG_ASYNC(root, "message" << i);
			}
			asyncAppender->close();

			// Check all message were received
			auto vectorAppender = LOG4CXX_NS::cast<VectorAppender>(asyncAppender->getAppender(LOG4CXX_STR("VECTOR")));
			LOGUNIT_ASSERT(vectorAppender);
			auto& v = vectorAppender->getVector();
			LOGUNIT_ASSERT_EQUAL(LEN, v.size());
			LOGUNIT_ASSERT(vectorAppender->isClosed());
		}

		void testAsyncLoggerXML()
		{
			// Configure Log4cxx
			auto status = xml::DOMConfigurator::configure("input/xml/asyncLogger.xml");
			LOGUNIT_ASSERT_EQUAL(status, spi::ConfigurationStatus::Configured);

			// Check configuration is as expected
			auto  root = Logger::getRootLogger();
			auto appenders = root->getAllAppenders();
			LOGUNIT_ASSERT_EQUAL(1, int(appenders.size()));
			auto asyncAppender = LOG4CXX_NS::cast<AsyncAppender>(appenders.front());
			LOGUNIT_ASSERT(asyncAppender);

			// Log some messages
			size_t LEN = 20;
			for (size_t i = 0; i < LEN; i++)
			{
				LOG4CXX_INFO_ASYNC(root, "message" << i);
			}
			asyncAppender->close();

			// Check all message were received
			auto vectorAppender = LOG4CXX_NS::cast<VectorAppender>(asyncAppender->getAppender(LOG4CXX_STR("VECTOR")));
			LOGUNIT_ASSERT(vectorAppender);
			auto& v = vectorAppender->getVector();
			LOGUNIT_ASSERT_EQUAL(LEN, v.size());
			LOGUNIT_ASSERT(vectorAppender->isClosed());
		}

		void testRecursiveConfiguration()
		{
			// Configure Log4cxx
			auto status = xml::DOMConfigurator::configure("input/xml/recursiveConfig.xml");
			LOGUNIT_ASSERT_EQUAL(status, spi::ConfigurationStatus::Configured);

			// Check configuration is as expected
			auto  root = Logger::getRootLogger();
			auto appenders = root->getAllAppenders();
			LOGUNIT_ASSERT_EQUAL(1, int(appenders.size()));
			auto asyncAppender = LOG4CXX_NS::cast<AsyncAppender>(appenders.front());
			LOGUNIT_ASSERT(asyncAppender);
			VectorAppenderPtr vectorAppender;
			for (auto attachedAppender : asyncAppender->getAllAppenders())
			{
				if (auto async2 = LOG4CXX_NS::cast<AsyncAppender>(attachedAppender))
				{
					for (auto appender : async2->getAllAppenders())
					{
						vectorAppender = LOG4CXX_NS::cast<VectorAppender>(appender);
						if (vectorAppender)
							break;
					}
				}
			}
			LOGUNIT_ASSERT(vectorAppender);

			// Log some messages
			size_t LEN = 20;
			for (size_t i = 0; i < LEN; i++)
			{
				LOG4CXX_INFO_ASYNC(root, "message" << i);
			}
			std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) );
			asyncAppender->close();

			// Check all message were received
			auto& v = vectorAppender->getVector();
			LOGUNIT_ASSERT_EQUAL(LEN, v.size());
			LOGUNIT_ASSERT(vectorAppender->isClosed());
		}
#endif

#if ENABLE_FAILING_APPENDER_SIMULATION_TESTING
		void testAsyncAppenderFallback()
		{
			// Configure Log4cxx
			auto status = xml::DOMConfigurator::configure("input/xml/asyncWithFallback.xml");
			LOGUNIT_ASSERT_EQUAL(status, spi::ConfigurationStatus::Configured);

			// Check configuration is as expected
			auto  root = Logger::getRootLogger();
			auto appenders = root->getAllAppenders();
			LOGUNIT_ASSERT_EQUAL(1, int(appenders.size()));
			auto asyncAppender = LOG4CXX_NS::cast<AsyncAppender>(appenders.front());
			LOGUNIT_ASSERT(asyncAppender);
			auto asyncAppenders = asyncAppender->getAllAppenders();
			LOGUNIT_ASSERT_EQUAL(1, int(asyncAppenders.size()));
			auto primaryAppender = LOG4CXX_NS::cast<FileAppender>(asyncAppenders.front());
			LOGUNIT_ASSERT(primaryAppender);
			auto primaryFileName = primaryAppender->getFile();
			LOGUNIT_ASSERT(11 < primaryFileName.size());
			LOGUNIT_ASSERT_EQUAL(LOG4CXX_STR("Primary.log"), primaryFileName.substr(primaryFileName.size() - 11));

			// Log some messages
			size_t LEN = 2000;
			for (size_t i = 0; i < LEN; i++)
			{
				LOG4CXX_INFO_ASYNC(root, "message " << i);
			}
			std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) );
			asyncAppenders = asyncAppender->getAllAppenders();
			LOGUNIT_ASSERT_EQUAL(1, int(asyncAppenders.size()));
			auto backupAppender = LOG4CXX_NS::cast<FileAppender>(asyncAppenders.front());
			LOGUNIT_ASSERT(backupAppender);
			auto backupFileName = backupAppender->getFile();
			LOGUNIT_ASSERT(10 < backupFileName.size());
			LOGUNIT_ASSERT_EQUAL(LOG4CXX_STR("Backup.log"), backupFileName.substr(backupFileName.size() - 10));

			// Check all messages were written
			std::vector<int> messageCount;
			for (auto const& filePathLS : {primaryFileName, backupFileName})
			{
				LOG4CXX_ENCODE_CHAR(filePath, filePathLS);
				std::ifstream input(filePath);
				for (std::string line; std::getline(input, line);)
				{
					 auto pos = line.rfind(' ');
					 if (line.npos != pos && pos + 1 < line.size())
					 {
						try
						{
							auto msgNumber = std::stoull(line.substr(pos));
							if (messageCount.size() <= msgNumber)
								messageCount.resize(msgNumber + 1);
							++messageCount[msgNumber];
						}
						catch (std::exception const& ex)
						{
							LogString msg;
							helpers::Transcoder::decode(ex.what(), msg);
							msg += LOG4CXX_STR(" processing\n");
							helpers::Transcoder::decode(line, msg);
							helpers::LogLog::warn(msg);
						}
					 }
				}
			}
			for (auto& count : messageCount)
				LOGUNIT_ASSERT_EQUAL(1, count);
		}
#endif

		void testAsyncLoggerProperties()
		{
			// Configure Log4cxx
			auto status = PropertyConfigurator::configure("input/asyncLogger.properties");
			LOGUNIT_ASSERT_EQUAL(status, spi::ConfigurationStatus::Configured);

			// Check configuration is as expected
			auto  root = Logger::getRootLogger();
			auto appenders = root->getAllAppenders();
			LOGUNIT_ASSERT_EQUAL(1, int(appenders.size()));
			auto asyncAppender = LOG4CXX_NS::cast<AsyncAppender>(appenders.front());
			LOGUNIT_ASSERT(asyncAppender);

			// Log some messages
			size_t LEN = 20;
			for (size_t i = 0; i < LEN; i++)
			{
				LOG4CXX_INFO_ASYNC(root, "message" << i);
			}
			asyncAppender->close();

			// Check all message were received
			auto vectorAppender = LOG4CXX_NS::cast<VectorAppender>(asyncAppender->getAppender(LOG4CXX_STR("VECTOR")));
			LOGUNIT_ASSERT(vectorAppender);
			auto& v = vectorAppender->getVector();
			LOGUNIT_ASSERT_EQUAL(LEN, v.size());
			LOGUNIT_ASSERT(vectorAppender->isClosed());
		}

#if LOG4CXX_ASYNC_BUFFER_SUPPORTS_FMT
		/**
		 * Tests asynchronous logging using FMT
		 */
		void testAsyncFmtLogging()
		{
			// Configure Log4cxx
			AsyncAppenderPtr async;
			auto r = LogManager::getLoggerRepository();
			r->ensureIsConfigured([r, &async]()
			{
				async = std::make_shared<AsyncAppender>();
				async->setName(LOG4CXX_STR("withAsyncFmtLogging"));
				r->getRootLogger()->addAppender(async);
				r->setConfigured(true);
			});
			LOGUNIT_ASSERT(async);
			auto eventStore = std::make_shared<VectorAppender>();
			eventStore->setName(LOG4CXX_STR("VectorAppender"));
			async->addAppender(eventStore);

			// Log some messages
			auto rootLogger = r->getRootLogger();
			LOG4CXX_INFO_FMT_ASYNC(rootLogger, LOG4CXX_STR("Hello, {}"), LOG4CXX_STR("World"));
			for (MyStruct i = {0}; i.value < 10; ++i.value)
			{
				LOG4CXX_INFO_FMT_ASYNC(rootLogger, LOG4CXX_STR("Hello, {}"), i);
			}
			LOG4CXX_INFO_FMT_ASYNC(rootLogger, "Bye bye {}", "World");
			async->close();

			// Check all parts of all messages were received
			auto& events = eventStore->getVector();
			std::vector<int> messageCount;
			int eventCount[] = { 0, 0 };
			for (auto& e : events)
			{
				auto message = e->getRenderedMessage();
				//LogLog::debug(message);
				auto isNumberedMessage = (message.npos == message.find(LOG4CXX_STR("World")));
				++eventCount[isNumberedMessage];
				if (isNumberedMessage)
				{
					 auto pos = message.rfind(' ');
					 if (message.npos != pos && pos + 1 < message.size())
					 {
						try
						{
							auto msgNumber = StringHelper::toInt(message.substr(pos));
							if (messageCount.size() <= msgNumber)
								messageCount.resize(msgNumber + 1);
							++messageCount[msgNumber];
						}
						catch (std::exception const& ex)
						{
							LogString msg;
							helpers::Transcoder::decode(ex.what(), msg);
							msg += LOG4CXX_STR(" processing\n");
							helpers::Transcoder::decode(message, msg);
							helpers::LogLog::warn(msg);
						}
					 }
				}
			}
			LOGUNIT_ASSERT_EQUAL(int(messageCount.size()), eventCount[1]);
			for (auto& count : messageCount)
				LOGUNIT_ASSERT_EQUAL(count, messageCount.front());
			LOGUNIT_ASSERT_EQUAL(2, eventCount[0]);
		}
#endif // LOG4CXX_ASYNC_BUFFER_SUPPORTS_FMT

};

LOGUNIT_TEST_SUITE_REGISTRATION(AsyncAppenderTestCase);
