/*
 * 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.
 */

#include <log4cxx/logger.h>
#include <log4cxx/propertyconfigurator.h>
#include <log4cxx/mdc.h>
#include <log4cxx/patternlayout.h>
#include <log4cxx/fileappender.h>

#include "util/compare.h"
#include "util/transformer.h"
#include "util/absolutedateandtimefilter.h"
#include "util/iso8601filter.h"
#include "util/absolutetimefilter.h"
#include "util/relativetimefilter.h"
#include "util/controlfilter.h"
#include "util/threadfilter.h"
#include "util/linenumberfilter.h"
#include "util/filenamefilter.h"
#include <iostream>
#include <log4cxx/helpers/transcoder.h>
#include <log4cxx/helpers/pool.h>
#include <apr_strings.h>
#include <log4cxx/helpers/loglog.h>
#include "testchar.h"
#include "logunit.h"
#include <log4cxx/spi/loggerrepository.h>
#include <log4cxx/spi/loggingevent.h>
#include <log4cxx/helpers/stringhelper.h>


#define REGEX_STR(x) x
#define PAT0 REGEX_STR("\\[[0-9A-FXx]*]\\ (DEBUG|INFO|WARN|ERROR|FATAL) .* - Message [0-9]\\{1,2\\}")
#define PAT1 ISO8601_PAT REGEX_STR(" ") PAT0
#define PAT2 ABSOLUTE_DATE_AND_TIME_PAT REGEX_STR(" ") PAT0
#define PAT3 ABSOLUTE_TIME_PAT REGEX_STR(" ") PAT0
#define PAT4 RELATIVE_TIME_PAT REGEX_STR(" ") PAT0
#define PAT5 REGEX_STR("\\[[0-9A-FXx]*]\\ (DEBUG|INFO|WARN|ERROR|FATAL) .* : Message [0-9]\\{1,2\\}")
#define PAT6 REGEX_STR("\\[[0-9A-FXx]*]\\ (DEBUG|INFO |WARN |ERROR|FATAL) .*patternlayouttest.cpp\\([0-9]\\{1,4\\}\\): Message [0-9]\\{1,3\\}")
#define PAT11a REGEX_STR("^(DEBUG|INFO |WARN |ERROR|FATAL) \\[[0-9A-FXx]*]\\ log4j.PatternLayoutTest: Message [0-9]\\{1,2\\}")
#define PAT11b REGEX_STR("^(DEBUG|INFO |WARN |ERROR|FATAL) \\[[0-9A-FXx]*]\\ root: Message [0-9]\\{1,2\\}")
#define PAT12 REGEX_STR("^\\[[0-9A-FXx]*]\\ (DEBUG|INFO |WARN |ERROR|FATAL) ")\
	REGEX_STR(".*patternlayouttest.cpp([0-9]\\{1,4\\}): ")\
	REGEX_STR("Message [0-9]\\{1,2\\}")
#define PAT_MDC_1 REGEX_STR("")

using namespace log4cxx;
using namespace log4cxx::helpers;

LOGUNIT_CLASS(PatternLayoutTest)
{
	LOGUNIT_TEST_SUITE(PatternLayoutTest);
#if ENABLE_2GB_STRING_TESTING
	LOGUNIT_TEST(test2GbMessageFormatting);
#endif
	LOGUNIT_TEST(test1);
	LOGUNIT_TEST(test2);
	LOGUNIT_TEST(test3);
	LOGUNIT_TEST(test4);
	LOGUNIT_TEST(test5);
	LOGUNIT_TEST(test6);
	LOGUNIT_TEST(test7);
	LOGUNIT_TEST(test8);
	LOGUNIT_TEST(test9);
	LOGUNIT_TEST(test10);
	LOGUNIT_TEST(test11);
	LOGUNIT_TEST(test12);
	LOGUNIT_TEST(test13);
	LOGUNIT_TEST(test14);
	LOGUNIT_TEST(testMDC1);
	LOGUNIT_TEST(testMDC2);
	LOGUNIT_TEST(testAbbreviateNoDots);
	LOGUNIT_TEST(testAbbreviatePrecisionExceedsSegments);
	LOGUNIT_TEST(testAbbreviateKeepLastTwoSegments);
	LOGUNIT_TEST(testAbbreviateKeepLastSegmentOnly);
	LOGUNIT_TEST(testAbbreviatePrecisionZero);
	LOGUNIT_TEST(testAbbreviateEachSegmentToOneChar);
	LOGUNIT_TEST(testAbbreviateEachSegmentToTwoChars);
	LOGUNIT_TEST(testAbbreviateShortSegmentUnchanged);
	LOGUNIT_TEST(testAbbreviateConsecutiveDots);
	LOGUNIT_TEST(testAbbreviateLeadingDot);
	LOGUNIT_TEST(testAbbreviateTrailingDot);
	LOGUNIT_TEST(testAbbreviateEmptyName);
	LOGUNIT_TEST(testAbbreviateDegenerateName);
	LOGUNIT_TEST(testAbbreviateSegmentEqualToCharCountBoundary);
	LOGUNIT_TEST(testAbbreviateSegmentOneCharOverBoundary);
	LOGUNIT_TEST(testAbbreviateManySegmentsDeepHierarchy);
	LOGUNIT_TEST(testAbbreviateLongFinalSegmentPreserved);
	LOGUNIT_TEST(testAbbreviateIdempotentOnAlreadyAbbreviated);
	LOGUNIT_TEST_SUITE_END();

	LoggerPtr root;
	LoggerPtr logger;

public:
	void setUp()
	{
		root = Logger::getRootLogger();
		MDC::clear();
		logger = Logger::getLogger(LOG4CXX_TEST_STR("java.org.apache.log4j.PatternLayoutTest"));
	}

	void tearDown()
	{
		MDC::clear();
		auto rep = root->getLoggerRepository();

		if (rep)
		{
			rep->resetConfiguration();
		}
	}

	void test2GbMessageFormatting()
	{
		LogString msg;
		try
		{
			msg.append(size_t(INT_MAX) + 1000, 'E');
		}
		catch (const std::exception& ex)
		{
			LOGLOG_DEBUG(logger, ex.what() << " - skipping 2Gb message formatting test");
			return;
		}
		msg[msg.length() - 1] = 'X';
		LogString output1;
		PatternLayout l1{ LOG4CXX_STR("%-5p %c{2} - %.30m") };
		l1.format(output1, std::make_shared<spi::LoggingEvent>(logger->getName(), Level::getInfo(), msg, spi::LocationInfo::getLocationUnavailable()));
		LOGUNIT_ASSERT_EQUAL(LOG4CXX_STR("INFO  log4j.PatternLayoutTest - EEEEEEEEEEEEEEEEEEEEEEEEEEEEEX"), output1);

		PatternLayout l2{ LOG4CXX_STR("%p %.30m %p") };
		LogString output2;
		l2.format(output2, std::make_shared<spi::LoggingEvent>(logger->getName(), Level::getDebug(), msg, spi::LocationInfo::getLocationUnavailable()));
		LOGUNIT_ASSERT_EQUAL(LOG4CXX_STR("DEBUG EEEEEEEEEEEEEEEEEEEEEEEEEEEEEX DEBUG"), output2);
	}

	void test1()
	{
		auto status = PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout1.properties"));
		LOGUNIT_ASSERT_EQUAL(status, spi::ConfigurationStatus::Configured);
		common();
		LOGUNIT_ASSERT(Compare::compare(TEMP, LOG4CXX_FILE("witness/patternLayout.1")));
	}

	void test2()
	{
		auto status = PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout2.properties"));
		LOGUNIT_ASSERT_EQUAL(status, spi::ConfigurationStatus::Configured);
		common();

		ControlFilter filter1;
		filter1 << PAT1;
		ISO8601Filter filter2;
		ThreadFilter filter3;

		std::vector<Filter*> filters;
		filters.push_back(&filter1);
		filters.push_back(&filter2);
		filters.push_back(&filter3);

		try
		{
			Transformer::transform(TEMP, FILTERED, filters);
		}
		catch (UnexpectedFormatException& e)
		{
			std::cout << "UnexpectedFormatException :" << e.what() << std::endl;
			throw;
		}

		LOGUNIT_ASSERT(Compare::compare(FILTERED, LOG4CXX_FILE("witness/patternLayout.2")));
	}

	void test3()
	{
		auto status = PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout3.properties"));
		LOGUNIT_ASSERT_EQUAL(status, spi::ConfigurationStatus::Configured);
		common();

		ControlFilter filter1;
		filter1 << PAT1;
		ISO8601Filter filter2;
		ThreadFilter filter3;

		std::vector<Filter*> filters;
		filters.push_back(&filter1);
		filters.push_back(&filter2);
		filters.push_back(&filter3);

		try
		{
			Transformer::transform(TEMP, FILTERED, filters);
		}
		catch (UnexpectedFormatException& e)
		{
			std::cout << "UnexpectedFormatException :" << e.what() << std::endl;
			throw;
		}

		LOGUNIT_ASSERT(Compare::compare(FILTERED, LOG4CXX_FILE("witness/patternLayout.3")));
	}

	// Output format:
	// 06 avr. 2002 18:30:58,937 [12345] DEBUG atternLayoutTest - Message 0
	void test4()
	{
		auto status = PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout4.properties"));
		LOGUNIT_ASSERT_EQUAL(status, spi::ConfigurationStatus::Configured);
		common();

		ControlFilter filter1;
		filter1 << PAT2;
		AbsoluteDateAndTimeFilter filter2;
		ThreadFilter filter3;

		std::vector<Filter*> filters;
		filters.push_back(&filter1);
		filters.push_back(&filter2);
		filters.push_back(&filter3);

		try
		{
			Transformer::transform(TEMP, FILTERED, filters);
		}
		catch (UnexpectedFormatException& e)
		{
			std::cout << "UnexpectedFormatException :" << e.what() << std::endl;
			throw;
		}

		LOGUNIT_ASSERT(Compare::compare(FILTERED, LOG4CXX_FILE("witness/patternLayout.4")));
	}

	void test5()
	{
		auto status = PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout5.properties"));
		LOGUNIT_ASSERT_EQUAL(status, spi::ConfigurationStatus::Configured);
		common();

		ControlFilter filter1;
		filter1 << PAT2;
		AbsoluteDateAndTimeFilter filter2;
		ThreadFilter filter3;

		std::vector<Filter*> filters;
		filters.push_back(&filter1);
		filters.push_back(&filter2);
		filters.push_back(&filter3);

		try
		{
			Transformer::transform(TEMP, FILTERED, filters);
		}
		catch (UnexpectedFormatException& e)
		{
			std::cout << "UnexpectedFormatException :" << e.what() << std::endl;
			throw;
		}

		LOGUNIT_ASSERT(Compare::compare(FILTERED, LOG4CXX_FILE("witness/patternLayout.5")));
	}

	void test6()
	{
		auto status = PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout6.properties"));
		LOGUNIT_ASSERT_EQUAL(status, spi::ConfigurationStatus::Configured);
		common();

		ControlFilter filter1;
		filter1 << PAT3;
		AbsoluteTimeFilter filter2;
		ThreadFilter filter3;

		std::vector<Filter*> filters;
		filters.push_back(&filter1);
		filters.push_back(&filter2);
		filters.push_back(&filter3);

		try
		{
			Transformer::transform(TEMP, FILTERED, filters);
		}
		catch (UnexpectedFormatException& e)
		{
			std::cout << "UnexpectedFormatException :" << e.what() << std::endl;
			throw;
		}

		LOGUNIT_ASSERT(Compare::compare(FILTERED, LOG4CXX_FILE("witness/patternLayout.6")));
	}

	void test7()
	{
		auto status = PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout7.properties"));
		LOGUNIT_ASSERT_EQUAL(status, spi::ConfigurationStatus::Configured);
		common();

		ControlFilter filter1;
		filter1 << PAT3;
		AbsoluteTimeFilter filter2;
		ThreadFilter filter3;

		std::vector<Filter*> filters;
		filters.push_back(&filter1);
		filters.push_back(&filter2);
		filters.push_back(&filter3);

		try
		{
			Transformer::transform(TEMP, FILTERED, filters);
		}
		catch (UnexpectedFormatException& e)
		{
			std::cout << "UnexpectedFormatException :" << e.what() << std::endl;
			throw;
		}

		LOGUNIT_ASSERT(Compare::compare(FILTERED, LOG4CXX_FILE("witness/patternLayout.7")));
	}

	void test8()
	{
		auto status = PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout8.properties"));
		LOGUNIT_ASSERT_EQUAL(status, spi::ConfigurationStatus::Configured);
		common();


		ControlFilter filter1;
		filter1 << PAT4;
		//
		//   combo of relative time and thread identifier
		//     (the \\\\1 preserve a leading space)
		Filter filter2(".*]", "[main]");

		std::vector<Filter*> filters;

		filters.push_back(&filter1);
		filters.push_back(&filter2);

		try
		{
			Transformer::transform(TEMP, FILTERED, filters);
		}
		catch (UnexpectedFormatException& e)
		{
			std::cout << "UnexpectedFormatException :" << e.what() << std::endl;
			throw;
		}

		LOGUNIT_ASSERT(Compare::compare(FILTERED, LOG4CXX_FILE("witness/patternLayout.8")));
	}

	void test9()
	{
		auto status = PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout9.properties"));
		LOGUNIT_ASSERT_EQUAL(status, spi::ConfigurationStatus::Configured);
		common();

		ControlFilter filter1;
		filter1 << PAT5;
		ThreadFilter filter2;

		std::vector<Filter*> filters;
		filters.push_back(&filter1);
		filters.push_back(&filter2);

		try
		{
			Transformer::transform(TEMP, FILTERED, filters);
		}
		catch (UnexpectedFormatException& e)
		{
			std::cout << "UnexpectedFormatException :" << e.what() << std::endl;
			throw;
		}

		LOGUNIT_ASSERT(Compare::compare(FILTERED, LOG4CXX_FILE("witness/patternLayout.9")));
	}

	void test10()
	{
		auto status = PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout10.properties"));
		LOGUNIT_ASSERT_EQUAL(status, spi::ConfigurationStatus::Configured);
		common();

		ControlFilter filter1;
		filter1 << PAT6;
		ThreadFilter filter2;
		LineNumberFilter filter3;
		FilenameFilter filenameFilter(__FILE__, "patternlayouttest.cpp");


		std::vector<Filter*> filters;
		filters.push_back(&filenameFilter);
		filters.push_back(&filter1);
		filters.push_back(&filter2);
		filters.push_back(&filter3);


		try
		{
			Transformer::transform(TEMP, FILTERED, filters);
		}
		catch (UnexpectedFormatException& e)
		{
			std::cout << "UnexpectedFormatException :" << e.what() << std::endl;
			throw;
		}

		LOGUNIT_ASSERT(Compare::compare(FILTERED, LOG4CXX_FILE("witness/patternLayout.10")));
	}

	void test11()
	{
		auto status = PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout11.properties"));
		LOGUNIT_ASSERT_EQUAL(status, spi::ConfigurationStatus::Configured);
		common();

		ControlFilter filter1;
		filter1 << PAT11a << PAT11b;
		ThreadFilter filter2;

		std::vector<Filter*> filters;
		filters.push_back(&filter1);
		filters.push_back(&filter2);

		try
		{
			Transformer::transform(TEMP, FILTERED, filters);
		}
		catch (UnexpectedFormatException& e)
		{
			std::cout << "UnexpectedFormatException :" << e.what() << std::endl;
			throw;
		}

		LOGUNIT_ASSERT(Compare::compare(FILTERED, LOG4CXX_FILE("witness/patternLayout.11")));
	}

	void test12()
	{
		auto status = PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout12.properties"));
		LOGUNIT_ASSERT_EQUAL(status, spi::ConfigurationStatus::Configured);
		common();

		ControlFilter filter1;
		filter1 << PAT12;
		ThreadFilter filter2;
		LineNumberFilter filter3;
		FilenameFilter filenameFilter(__FILE__, "patternlayouttest.cpp");

		std::vector<Filter*> filters;
		filters.push_back(&filenameFilter);
		filters.push_back(&filter1);
		filters.push_back(&filter2);
		filters.push_back(&filter3);

		try
		{
			Transformer::transform(TEMP, FILTERED, filters);
		}
		catch (UnexpectedFormatException& e)
		{
			std::cout << "UnexpectedFormatException :" << e.what() << std::endl;
			throw;
		}

		LOGUNIT_ASSERT(Compare::compare(FILTERED, LOG4CXX_FILE("witness/patternLayout.12")));
	}

	void test13()
	{
		auto status = PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout13.properties"));
		LOGUNIT_ASSERT_EQUAL(status, spi::ConfigurationStatus::Configured);
		common();
		LOGUNIT_ASSERT(Compare::compare(TEMP, LOG4CXX_FILE("witness/patternLayout.13")));
	}

	void test14()
	{
		auto status = PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout14.properties"));
		LOGUNIT_ASSERT_EQUAL(status, spi::ConfigurationStatus::Configured);
		common();
		LOGUNIT_ASSERT(Compare::compare(TEMP, LOG4CXX_FILE("witness/patternLayout.14")));
	}

	void testMDC1()
	{
		auto status = PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout.mdc.1.properties"));
		LOGUNIT_ASSERT_EQUAL(status, spi::ConfigurationStatus::Configured);
		MDC::put(LOG4CXX_TEST_STR("key1"), LOG4CXX_TEST_STR("va11"));
		MDC::put(LOG4CXX_TEST_STR("key2"), LOG4CXX_TEST_STR("va12"));
		logger->debug(LOG4CXX_TEST_STR("Hello World"));
		MDC::clear();

		LOGUNIT_ASSERT(Compare::compare(TEMP, LOG4CXX_FILE("witness/patternLayout.mdc.1")));
	}

	void testMDC2()
	{
		LogString OUTPUT_FILE   = LOG4CXX_STR("output/patternLayout.mdc.2");
		File WITNESS_FILE  = LOG4CXX_FILE("witness/patternLayout.mdc.2");

		LogString mdcMsgPattern1 = LOG4CXX_STR("%m : %X%n");
		LogString mdcMsgPattern2 = LOG4CXX_STR("%m : %X{key1}%n");
		LogString mdcMsgPattern3 = LOG4CXX_STR("%m : %X{key2}%n");
		LogString mdcMsgPattern4 = LOG4CXX_STR("%m : %X{key3}%n");
		LogString mdcMsgPattern5 = LOG4CXX_STR("%m : %X{key1},%X{key2},%X{key3}%n");

		// set up appender
		PatternLayoutPtr layout = PatternLayoutPtr(new PatternLayout(LOG4CXX_STR("%m%n")));
		AppenderPtr appender = FileAppenderPtr(new FileAppender(layout, OUTPUT_FILE, false));

		// set appender on root and set level to debug
		root->addAppender(appender);
		root->setLevel(Level::getDebug());

		// output starting message
		root->debug(LOG4CXX_TEST_STR("starting mdc pattern test"));

		layout->setConversionPattern(mdcMsgPattern1);
		layout->activateOptions();
		root->debug(LOG4CXX_TEST_STR("empty mdc, no key specified in pattern"));

		layout->setConversionPattern(mdcMsgPattern2);
		layout->activateOptions();
		root->debug(LOG4CXX_TEST_STR("empty mdc, key1 in pattern"));

		layout->setConversionPattern(mdcMsgPattern3);
		layout->activateOptions();
		root->debug(LOG4CXX_TEST_STR("empty mdc, key2 in pattern"));

		layout->setConversionPattern(mdcMsgPattern4);
		layout->activateOptions();
		root->debug(LOG4CXX_TEST_STR("empty mdc, key3 in pattern"));

		layout->setConversionPattern(mdcMsgPattern5);
		layout->activateOptions();
		root->debug(LOG4CXX_TEST_STR("empty mdc, key1, key2, and key3 in pattern"));

		MDC::put(LOG4CXX_TEST_STR("key1"), LOG4CXX_TEST_STR("value1"));
		MDC::put(LOG4CXX_TEST_STR("key2"), LOG4CXX_TEST_STR("value2"));

		layout->setConversionPattern(mdcMsgPattern1);
		layout->activateOptions();
		root->debug(LOG4CXX_TEST_STR("filled mdc, no key specified in pattern"));

		layout->setConversionPattern(mdcMsgPattern2);
		layout->activateOptions();
		root->debug(LOG4CXX_TEST_STR("filled mdc, key1 in pattern"));

		layout->setConversionPattern(mdcMsgPattern3);
		layout->activateOptions();
		root->debug(LOG4CXX_TEST_STR("filled mdc, key2 in pattern"));

		layout->setConversionPattern(mdcMsgPattern4);
		layout->activateOptions();
		root->debug(LOG4CXX_TEST_STR("filled mdc, key3 in pattern"));

		layout->setConversionPattern(mdcMsgPattern5);
		layout->activateOptions();
		root->debug(LOG4CXX_TEST_STR("filled mdc, key1, key2, and key3 in pattern"));

		MDC::remove(LOG4CXX_TEST_STR("key1"));
		MDC::remove(LOG4CXX_TEST_STR("key2"));

		layout->setConversionPattern(LOG4CXX_STR("%m%n"));
		layout->activateOptions();
		root->debug(LOG4CXX_TEST_STR("finished mdc pattern test"));

		LOGUNIT_ASSERT(Compare::compare(OUTPUT_FILE, WITNESS_FILE));
	}

	/*
	 * Tests for logger-name abbreviation, exercised via %c{precision} in PatternLayout.
	 */

	/**
	 * No dots at all: name shorter than or equal to any precision should be
	 * returned unchanged (nextDot == npos path, no truncation possible).
	 */
	void testAbbreviateNoDots()
	{
		PatternLayout layout(LOG4CXX_STR("%c{2}"));
		auto event = std::make_shared<spi::LoggingEvent>
			( LOG4CXX_STR("NoDotsHere")
			, Level::getInfo()
			, LOG4CXX_STR("msg")
			, LOG4CXX_LOCATION
			);
		LogString result;
		layout.format(result, event);
		LOGUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR("NoDotsHere")), result);
	}

	/**
	 * Precision larger than number of segments: entire name is preserved,
	 * exercising the "keep trailing/last element(s) whole" path.
	 */
	void testAbbreviatePrecisionExceedsSegments()
	{
		PatternLayout layout(LOG4CXX_STR("%c{5}"));
		auto event = std::make_shared<spi::LoggingEvent>
			( LOG4CXX_STR("org.apache.log4cxx")
			, Level::getInfo()
			, LOG4CXX_STR("msg")
			, LOG4CXX_LOCATION
			);
		LogString result;
		layout.format(result, event);
		LOGUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR("org.apache.log4cxx")), result);
	}

	/**
	 * Standard case: precision 2 keeps the last two dotted segments and
	 * drops the leading ones entirely (no ellipsis involved at this level).
	 */
	void testAbbreviateKeepLastTwoSegments()
	{
		PatternLayout layout(LOG4CXX_STR("%c{2}"));
		auto event = std::make_shared<spi::LoggingEvent>
			( LOG4CXX_STR("org.apache.log4cxx.PatternLayout")
			, Level::getInfo()
			, LOG4CXX_STR("msg")
			, LOG4CXX_LOCATION
			);
		LogString result;
		layout.format(result, event);
		LOGUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR("log4cxx.PatternLayout")), result);
	}

	/**
	 * Precision 1 keeps only the final segment; every prior segment,
	 * however long, must be dropped by abbreviate()'s erase/rewrite step.
	 */
	void testAbbreviateKeepLastSegmentOnly()
	{
		PatternLayout layout(LOG4CXX_STR("%c{1}"));
		auto event = std::make_shared<spi::LoggingEvent>
			( LOG4CXX_STR("com.example.verylongcompany.module.ClassName")
			, Level::getInfo()
			, LOG4CXX_STR("msg")
			, LOG4CXX_LOCATION
			);
		LogString result;
		layout.format(result, event);
		LOGUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR("ClassName")), result);
	}

	/**
	 * Precision 0: degenerate case, only the final element remains
	 * (mirrors log4j semantics where 0 behaves like 1 for the last element).
	 */
	void testAbbreviatePrecisionZero()
	{
		PatternLayout layout(LOG4CXX_STR("%c{0}"));
		auto event = std::make_shared<spi::LoggingEvent>
			( LOG4CXX_STR("a.b.c.d.Ending")
			, Level::getInfo()
			, LOG4CXX_STR("msg")
			, LOG4CXX_LOCATION
			);
		LogString result;
		layout.format(result, event);
		LOGUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR("Ending")), result);
	}

	/**
	 * Fractional / dotted-count abbreviator ("%c{1.}" family): each retained
	 * leading segment is itself truncated to 1 character plus a trailing dot,
	 * directly exercising the charCount/erase/insert logic inside abbreviate().
	 */
	void testAbbreviateEachSegmentToOneChar()
	{
		PatternLayout layout(LOG4CXX_STR("%c{1.}"));
		auto event = std::make_shared<spi::LoggingEvent>
			( LOG4CXX_STR("org.apache.log4cxx.PatternLayout")
			, Level::getInfo()
			, LOG4CXX_STR("msg")
			, LOG4CXX_LOCATION
			);
		LogString result;
		layout.format(result, event);
		LOGUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR("o.a.l.PatternLayout")), result);
	}

	/**
	 * Segment truncated to 2 characters ("%c{2.}"): checks charCount > 1
	 * truncation path (nextDot - startPos > charCount) rather than the
	 * charCount == 1 special case.
	 */
	void testAbbreviateEachSegmentToTwoChars()
	{
		PatternLayout layout(LOG4CXX_STR("%c{2.}"));
		auto event = std::make_shared<spi::LoggingEvent>
			( LOG4CXX_STR("org.apache.log4cxx.PatternLayout")
			, Level::getInfo()
			, LOG4CXX_STR("msg")
			, LOG4CXX_LOCATION
			);
		LogString result;
		layout.format(result, event);
		LOGUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR("or.ap.lo.PatternLayout")), result);
	}

	/**
	 * Segment shorter than or equal to charCount is left untouched
	 * (the "(nextDot - startPos) > charCount" guard should skip erase/insert).
	 */
	void testAbbreviateShortSegmentUnchanged()
	{
		PatternLayout layout(LOG4CXX_STR("%c{3.}"));
		auto event = std::make_shared<spi::LoggingEvent>
			( LOG4CXX_STR("a.bb.ccc.LongFinalSegment")
			, Level::getInfo()
			, LOG4CXX_STR("msg")
			, LOG4CXX_LOCATION
			);
		LogString result;
		layout.format(result, event);
		// "a" (1<=3), "bb" (2<=3), "ccc" (3<=3) all pass through unabbreviated
		LOGUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR("a.bb.ccc.LongFinalSegment")), result);
	}

	/**
	 * Consecutive dots produce a zero-length segment; abbreviate() must
	 * not throw or corrupt the buffer, and should leave the empty
	 * segment as-is (nextDot - startPos == 0, not > charCount).
	 */
	void testAbbreviateConsecutiveDots()
	{
		PatternLayout layout(LOG4CXX_STR("%c{1.}"));
		auto event = std::make_shared<spi::LoggingEvent>
			( LOG4CXX_STR("org..apache.Logger")
			, Level::getInfo()
			, LOG4CXX_STR("msg")
			, LOG4CXX_LOCATION
			);
		LogString result;
		layout.format(result, event);
		LOGUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR("o..a.Logger")), result);
	}

	/**
	 * Leading dot creates an empty first segment; verifies startPos handling
	 * at position 0 doesn't underflow or mis-index into the buffer.
	 */
	void testAbbreviateLeadingDot()
	{
		PatternLayout layout(LOG4CXX_STR("%c{1.}"));
		auto event = std::make_shared<spi::LoggingEvent>
			( LOG4CXX_STR(".apache.Logger")
			, Level::getInfo()
			, LOG4CXX_STR("msg")
			, LOG4CXX_LOCATION
			);
		LogString result;
		layout.format(result, event);
		LOGUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR(".a.Logger")), result);
	}

	/**
	 * Trailing dot with nothing after it: the final "segment" after the
	 * last dot is empty, and nextDot == npos is never reached for that
	 * position, so the loop must still terminate correctly.
	 */
	void testAbbreviateTrailingDot()
	{
		auto event = std::make_shared<spi::LoggingEvent>
			( LOG4CXX_STR("org.apache.")
			, Level::getInfo()
			, LOG4CXX_STR("msg")
			, LOG4CXX_LOCATION
			);
		LogString maxElementCharCountResult;
		PatternLayout(LOG4CXX_STR("%c{1.}")).format(maxElementCharCountResult, event);
		LOGUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR("o.a.")), maxElementCharCountResult);
		LogString maxElementCountResult;
		PatternLayout(LOG4CXX_STR("%c{2}")).format(maxElementCountResult, event);
		LOGUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR("apache.")), maxElementCountResult);
	}

	/**
	 * Empty logger name: startPos == buf.size() from the start, find()
	 * immediately returns npos, function must be a no-op.
	 */
	void testAbbreviateEmptyName()
	{
		auto event = std::make_shared<spi::LoggingEvent>
			( LOG4CXX_STR("")
			, Level::getInfo()
			, LOG4CXX_STR("msg")
			, LOG4CXX_LOCATION
			);
		LogString maxElementCountResult;
		PatternLayout(LOG4CXX_STR("%c{2}")).format(maxElementCountResult, event);
		LOGUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR("")), maxElementCountResult);
		LogString maxElementCharCountResult;
		PatternLayout(LOG4CXX_STR("%c{1.}")).format(maxElementCharCountResult, event);
		LOGUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR("")), maxElementCharCountResult);
	}

	/**
	 * Degenerate logger name.
	 */
	void testAbbreviateDegenerateName()
	{
		auto event = std::make_shared<spi::LoggingEvent>
			( LOG4CXX_STR(".")
			, Level::getInfo()
			, LOG4CXX_STR("msg")
			, LOG4CXX_LOCATION
			);
		LogString maxElementCountResult;
		PatternLayout(LOG4CXX_STR("%c{1}")).format(maxElementCountResult, event);
		LOGUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR(".")), maxElementCountResult);
		LogString maxElementCharCountResult;
		PatternLayout(LOG4CXX_STR("%c{1.}")).format(maxElementCharCountResult, event);
		LOGUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR(".")), maxElementCharCountResult);
	}

	/**
	 * Single-character segments equal to charCount exactly: boundary check
	 * on "> charCount" vs ">= charCount" (should NOT truncate when equal,
	 * since the guard is strictly "(nextDot - startPos) > charCount").
	 */
	void testAbbreviateSegmentEqualToCharCountBoundary()
	{
		PatternLayout layout(LOG4CXX_STR("%c{2.}"));
		auto event = std::make_shared<spi::LoggingEvent>
			( LOG4CXX_STR("ab.cd.RestOfName")
			, Level::getInfo()
			, LOG4CXX_STR("msg")
			, LOG4CXX_LOCATION
			);
		LogString result;
		layout.format(result, event);
		// "ab" (len 2 == charCount 2) and "cd" (len 2 == charCount 2) both
		// pass through untouched; only the final segment is never abbreviated.
		LOGUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR("ab.cd.RestOfName")), result);
	}

	/**
	 * Segment exactly one character longer than charCount: smallest case
	 * that must actually trigger the erase/insert (or rewrite) path.
	 */
	void testAbbreviateSegmentOneCharOverBoundary()
	{
		PatternLayout layout(LOG4CXX_STR("%c{2.}"));
		auto event = std::make_shared<spi::LoggingEvent>
			( LOG4CXX_STR("abc.de.RestOfName")
			, Level::getInfo()
			, LOG4CXX_STR("msg")
			, LOG4CXX_LOCATION
			);
		LogString result;
		layout.format(result, event);
		// "abc" (len 3 > 2) truncates to "ab"; "de" (len 2 == 2) stays whole.
		LOGUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR("ab.de.RestOfName")), result);
	}

	/**
	 * Many short segments (deep package hierarchy): the classic case that
	 * exposes O(n*k) blowup in an erase/insert-per-segment implementation.
	 */
	void testAbbreviateManySegmentsDeepHierarchy()
	{
		PatternLayout layout(LOG4CXX_STR("%c{1.}"));
		auto event = std::make_shared<spi::LoggingEvent>
			( LOG4CXX_STR("a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.FinalClass")
			, Level::getInfo()
			, LOG4CXX_STR("msg")
			, LOG4CXX_LOCATION
			);
		LogString result;
		layout.format(result, event);
		LOGUNIT_ASSERT_EQUAL
			( LogString(LOG4CXX_STR("a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.FinalClass"))
			, result
			);
	}

	/**
	 * Very long single final segment combined with many short leading ones:
	 * ensures the tail (unabbreviated, no trailing dot) is copied intact
	 * even when it is far longer than charCount, since the last element is
	 * never subject to truncation regardless of length.
	 */
	void testAbbreviateLongFinalSegmentPreserved()
	{
		PatternLayout layout(LOG4CXX_STR("%c{1.}"));
		auto event = std::make_shared<spi::LoggingEvent>
			( LOG4CXX_STR("x.y.z.ThisIsAVeryLongFinalClassNameThatShouldNotBeTruncatedAtAll")
			, Level::getInfo()
			, LOG4CXX_STR("msg")
			, LOG4CXX_LOCATION
			);
		LogString result;
		layout.format(result, event);
		LOGUNIT_ASSERT_EQUAL
			( LogString(LOG4CXX_STR("x.y.z.ThisIsAVeryLongFinalClassNameThatShouldNotBeTruncatedAtAll"))
			, result
			);
	}

	/**
	 * Idempotency / stability check: running the same abbreviation pattern
	 * against an already-abbreviated name should be a no-op, since every
	 * remaining segment is already <= charCount.
	 */
	void testAbbreviateIdempotentOnAlreadyAbbreviated()
	{
		PatternLayout layout(LOG4CXX_STR("%c{1.}"));
		auto event = std::make_shared<spi::LoggingEvent>
			( LOG4CXX_STR("o.a.l.PatternLayout")
			, Level::getInfo()
			, LOG4CXX_STR("msg")
			, LOG4CXX_LOCATION
			);
		LogString result;
		layout.format(result, event);
		LOGUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR("o.a.l.PatternLayout")), result);
	}

	std::string createMessage(Pool & pool, int i)
	{
		std::string msg("Message ");
		msg.append(pool.itoa(i));
		return msg;
	}

	void common()
	{
		int i = -1;

		Pool pool;


		LOG4CXX_DEBUG(logger, createMessage(pool, ++i));
		LOG4CXX_DEBUG(root, createMessage(pool, i));

		LOG4CXX_INFO(logger, createMessage(pool, ++i));
		LOG4CXX_INFO(root, createMessage(pool, i));

		LOG4CXX_WARN(logger, createMessage(pool, ++i));
		LOG4CXX_WARN(root, createMessage(pool, i));

		LOG4CXX_ERROR(logger, createMessage(pool, ++i));
		LOG4CXX_ERROR(root, createMessage(pool, i));

		LOG4CXX_FATAL(logger, createMessage(pool, ++i));
		LOG4CXX_FATAL(root, createMessage(pool, i));
	}

private:
	static const LogString FILTERED;
	static const LogString TEMP;

};

const LogString PatternLayoutTest::TEMP(LOG4CXX_STR("output/patternlayout"));
const LogString PatternLayoutTest::FILTERED(LOG4CXX_STR("output/patternlayoutfiltered"));


LOGUNIT_TEST_SUITE_REGISTRATION(PatternLayoutTest);
