/*
 * 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 "../logunit.h"
#include <log4cxx/logger.h>
#include <log4cxx/xml/xmllayout.h>
#include <log4cxx/fileappender.h>
#include <log4cxx/mdc.h>

#include "../util/transformer.h"
#include "../util/compare.h"
#include "../util/xmltimestampfilter.h"
#include "../util/xmllineattributefilter.h"
#include "../util/xmlthreadfilter.h"
#include "../util/filenamefilter.h"
#include <iostream>
#include <log4cxx/helpers/stringhelper.h>
#include "../testchar.h"
#include <log4cxx/spi/loggerrepository.h>
#include <apr_xml.h>
#include <log4cxx/ndc.h>
#include <log4cxx/mdc.h>
#include "../xml/xlevel.h"
#include <log4cxx/helpers/bytebuffer.h>
#include <log4cxx/helpers/transcoder.h>


using namespace log4cxx;
using namespace log4cxx::helpers;
using namespace log4cxx::xml;
using namespace log4cxx::spi;

#if defined(__LOG4CXX_FUNC__)
	#undef __LOG4CXX_FUNC__
	#define __LOG4CXX_FUNC__ "X::X()"
#else
	#error __LOG4CXX_FUNC__ expected to be defined
#endif
/**
 * Test for XMLLayout.
 *
 */
LOGUNIT_CLASS(XMLLayoutTest)
{
	LOGUNIT_TEST_SUITE(XMLLayoutTest);
	LOGUNIT_TEST(testGetContentType);
	LOGUNIT_TEST(testIgnoresThrowable);
	LOGUNIT_TEST(testGetHeader);
	LOGUNIT_TEST(testGetFooter);
	LOGUNIT_TEST(testFormat);
	LOGUNIT_TEST(testFormatWithNDC);
	LOGUNIT_TEST(testGetSetLocationInfo);
	LOGUNIT_TEST(testActivateOptions);
	LOGUNIT_TEST(testProblemCharacters);
	LOGUNIT_TEST(testNDCWithCDATA);
	LOGUNIT_TEST_SUITE_END();


public:
	/**
	 * Clear MDC and NDC before test.
	 */
	void setUp()
	{
		NDC::clear();
		MDC::clear();
	}

	/**
	 * Clear MDC and NDC after test.
	 */
	void tearDown()
	{
		setUp();
	}


public:
	/**
	 * Tests getContentType.
	 */
	void testGetContentType()
	{
		LogString expected(LOG4CXX_STR("text/plain"));
		LogString actual(XMLLayout().getContentType());
		LOGUNIT_ASSERT(expected == actual);
	}

	/**
	 * Tests ignoresThrowable.
	 */
	void testIgnoresThrowable()
	{
		LOGUNIT_ASSERT_EQUAL(false, XMLLayout().ignoresThrowable());
	}

	/**
	 * Tests getHeader.
	 */
	void testGetHeader()
	{
		Pool p;
		LogString header;
		XMLLayout().appendHeader(header, p);
		LOGUNIT_ASSERT_EQUAL((size_t) 0, header.size());
	}

	/**
	 * Tests getFooter.
	 */
	void testGetFooter()
	{
		Pool p;
		LogString footer;
		XMLLayout().appendFooter(footer, p);
		LOGUNIT_ASSERT_EQUAL((size_t) 0, footer.size());
	}

private:
	/**
	 * Parses the string as the body of an XML document and returns the document element.
	 * @param source source string.
	 * @return document element.
	 * @throws Exception if parser can not be constructed or source is not a valid XML document.
	 */
	static apr_xml_elem* parse(const LogString & source, Pool & p)
	{
		char backing[3000];
		ByteBuffer buf(backing, sizeof(backing));
		CharsetEncoderPtr encoder(CharsetEncoder::getUTF8Encoder());
		LogString header(LOG4CXX_STR("<log4j:eventSet xmlns:log4j='http://jakarta.apache.org/log4j/'>"));
		LogString::const_iterator iter(header.begin());
		encoder->encode(header, iter, buf);
		LOGUNIT_ASSERT(iter == header.end());
		iter = source.begin();
		encoder->encode(source, iter, buf);
		LOGUNIT_ASSERT(iter == source.end());
		LogString footer(LOG4CXX_STR("</log4j:eventSet>"));
		iter = footer.begin();
		encoder->encode(footer, iter, buf);
		buf.flip();
		apr_pool_t* apr_pool = p.getAPRPool();
		apr_xml_parser* parser = apr_xml_parser_create(apr_pool);
		LOGUNIT_ASSERT(parser != 0);
		apr_status_t stat = apr_xml_parser_feed(parser, buf.data(), buf.remaining());
		LOGUNIT_ASSERT(stat == APR_SUCCESS);
		apr_xml_doc* doc = 0;
		stat = apr_xml_parser_done(parser, &doc);
		LOGUNIT_ASSERT(doc != 0);
		apr_xml_elem* eventSet = doc->root;
		LOGUNIT_ASSERT(eventSet != 0);
		apr_xml_elem* event = eventSet->first_child;
		LOGUNIT_ASSERT(event != 0);
		return event;
	}

	std::string getAttribute(apr_xml_elem * elem, const char* attrName)
	{
		for (apr_xml_attr* attr = elem->attr;
			attr != NULL;
			attr = attr->next)
		{
			if (strcmp(attr->name, attrName) == 0)
			{
				return attr->value;
			}
		}

		return "";
	}

	std::string getText(apr_xml_elem * elem)
	{
		std::string dMessage;

		for (apr_text* t = elem->first_cdata.first;
			t != NULL;
			t = t->next)
		{
			dMessage.append(t->text);
		}

		return dMessage;
	}
	/**
	 * Checks a log4j:event element against expectations.
	 * @param element element, may not be null.
	 * @param event event, may not be null.
	 */
	void checkEventElement(
		apr_xml_elem * element, LoggingEventPtr & event)
	{
		std::string tagName("event");
		LOGUNIT_ASSERT_EQUAL(tagName, (std::string) element->name);
		LOG4CXX_ENCODE_CHAR(cLoggerName, event->getLoggerName());
		LOGUNIT_ASSERT_EQUAL(cLoggerName, getAttribute(element, "logger"));
		LOG4CXX_ENCODE_CHAR(cLevelName, event->getLevel()->toString());
		LOGUNIT_ASSERT_EQUAL(cLevelName, getAttribute(element, "level"));
	}

	/**
	 * Checks a log4j:message element against expectations.
	 * @param element element, may not be null.
	 * @param message expected message.
	 */
	void checkMessageElement(
		apr_xml_elem * element, std::string message)
	{
		std::string tagName = "message";
		LOGUNIT_ASSERT_EQUAL(tagName, (std::string) element->name);
		LOGUNIT_ASSERT_EQUAL(message, getText(element));
	}

	/**
	 * Checks a log4j:message element against expectations.
	 * @param element element, may not be null.
	 * @param message expected message.
	 */
	void checkNDCElement(apr_xml_elem * element, std::string message)
	{
		std::string tagName = "NDC";
		LOGUNIT_ASSERT_EQUAL(tagName, (std::string) element->name);
		std::string dMessage = getText(element);
		LOGUNIT_ASSERT_EQUAL(message, dMessage);
	}


	/**
	 * Checks a log4j:properties element against expectations.
	 * @param element element, may not be null.
	 * @param key key.
	 * @param value value.
	 */
	void checkPropertiesElement(
		apr_xml_elem * element, std::string key, std::string value)
	{
		std::string tagName = "properties";
		std::string dataTag = "data";
		int childNodeCount = 0;
		LOGUNIT_ASSERT_EQUAL(tagName, (std::string) element->name);

		for (apr_xml_elem* child = element->first_child;
			child != NULL;
			child = child->next)
		{
			LOGUNIT_ASSERT_EQUAL(dataTag, (std::string) child->name);
			LOGUNIT_ASSERT_EQUAL(key, getAttribute(child, "name"));
			LOGUNIT_ASSERT_EQUAL(value, getAttribute(child, "value"));
			childNodeCount++;
		}

		LOGUNIT_ASSERT_EQUAL(1, childNodeCount);
	}

public:
	/**
	 * Tests formatted results.
	 * @throws Exception if parser can not be constructed or source is not a valid XML document.
	 */
	void testFormat()
	{
		LogString logger = LOG4CXX_STR("org.apache.log4j.xml.XMLLayoutTest");
		LoggingEventPtr event = LoggingEventPtr(
				new LoggingEvent(
					logger, Level::getInfo(), LOG4CXX_STR("Hello, World"), LOG4CXX_LOCATION));
		Pool p;
		XMLLayout layout;
		LogString result;
		layout.format(result, event, p);
		apr_xml_elem* parsedResult = parse(result, p);
		checkEventElement(parsedResult, event);

		int childElementCount = 0;

		for (
			apr_xml_elem* node = parsedResult->first_child;
			node != NULL;
			node = node->next)
		{
			childElementCount++;
			checkMessageElement(node, "Hello, World");
		}

		LOGUNIT_ASSERT_EQUAL(1, childElementCount);
	}


	/**
	 * Tests formatted results with an exception.
	 * @throws Exception if parser can not be constructed or source is not a valid XML document.
	 */
	void testFormatWithNDC()
	{
		LogString logger = LOG4CXX_STR("org.apache.log4j.xml.XMLLayoutTest");
		NDC::push("NDC goes here");

		LoggingEventPtr event = LoggingEventPtr(
				new LoggingEvent(
					logger, Level::getInfo(), LOG4CXX_STR("Hello, World"), LOG4CXX_LOCATION));
		Pool p;
		XMLLayout layout;
		LogString result;
		layout.format(result, event, p);
		NDC::pop();

		apr_xml_elem* parsedResult = parse(result, p);
		checkEventElement(parsedResult, event);

		int childElementCount = 0;

		for (
			apr_xml_elem* node = parsedResult->first_child; node != NULL;
			node = node->next)
		{
			childElementCount++;

			if (childElementCount == 1)
			{
				checkMessageElement(node, "Hello, World");
			}
			else
			{
				checkNDCElement(node, "NDC goes here");
			}
		}

		LOGUNIT_ASSERT_EQUAL(2, childElementCount);
	}

	/**
	 * Tests getLocationInfo and setLocationInfo.
	 */
	void testGetSetLocationInfo()
	{
		XMLLayout layout;
		LOGUNIT_ASSERT_EQUAL(false, layout.getLocationInfo());
		layout.setLocationInfo(true);
		LOGUNIT_ASSERT_EQUAL(true, layout.getLocationInfo());
		layout.setLocationInfo(false);
		LOGUNIT_ASSERT_EQUAL(false, layout.getLocationInfo());
	}

	/**
	 * Tests activateOptions().
	 */
	void testActivateOptions()
	{
		Pool p;
		XMLLayout layout;
		layout.activateOptions(p);
	}

	/**
	 * Tests problematic characters in multiple fields.
	 * @throws Exception if parser can not be constructed or source is not a valid XML document.
	 */
	void testProblemCharacters()
	{
		std::string problemName = "com.example.bar<>&\"'";
		LogString problemNameLS = LOG4CXX_STR("com.example.bar<>&\"'");
		LevelPtr level = LevelPtr(new XLevel(6000, problemNameLS, 7));
		NDC::push(problemName);
		MDC::clear();
		MDC::put(problemName, problemName);
		LoggingEventPtr event = LoggingEventPtr(
				new LoggingEvent(problemNameLS, level, problemNameLS, LOG4CXX_LOCATION));
		XMLLayout layout;
		layout.setProperties(true);
		Pool p;
		LogString result;
		layout.format(result, event, p);
		MDC::clear();

		apr_xml_elem* parsedResult = parse(result, p);
		checkEventElement(parsedResult, event);

		int childElementCount = 0;

		for (
			apr_xml_elem* node = parsedResult->first_child; node != NULL;
			node = node->next)
		{
			childElementCount++;

			switch (childElementCount)
			{
				case 1:
					checkMessageElement(node, problemName);
					break;

				case 2:
					checkNDCElement(node, problemName);
					break;

				case 3:
					checkPropertiesElement(node, problemName.c_str(), problemName.c_str());
					break;

				default:
					break;
			}

		}

		LOGUNIT_ASSERT_EQUAL(3, childElementCount);
	}

	/**
	  * Tests CDATA element within NDC content.  See bug 37560.
	  */
	void testNDCWithCDATA()
	{
		LogString logger = LOG4CXX_STR("com.example.bar");
		LevelPtr level = Level::getInfo();
		std::string ndcMessage = "<envelope><faultstring><![CDATA[The EffectiveDate]]></faultstring><envelope>";
		NDC::push(ndcMessage);
		LoggingEventPtr event = LoggingEventPtr(
				new LoggingEvent(
					logger, level, LOG4CXX_STR("Hello, World"), LOG4CXX_LOCATION));
		XMLLayout layout;
		Pool p;
		LogString result;
		layout.format(result, event, p);
		NDC::clear();
		apr_xml_elem* parsedResult = parse(result, p);
		int ndcCount = 0;

		for (apr_xml_elem* node = parsedResult->first_child;
			node != NULL;
			node = node->next)
		{
			if (strcmp(node->name, "NDC") == 0)
			{
				ndcCount++;
				LOGUNIT_ASSERT_EQUAL(ndcMessage, getText(node));
			}
		}

		LOGUNIT_ASSERT_EQUAL(1, ndcCount);
	}

};


LOGUNIT_TEST_SUITE_REGISTRATION(XMLLayoutTest);

