/*
 * 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/jsonlayout.h>
#include <log4cxx/ndc.h>
#include <log4cxx/mdc.h>

#include <iostream>
#include <log4cxx/helpers/stringhelper.h>
#include <log4cxx/helpers/transcoder.h>


using namespace log4cxx;
using namespace log4cxx::helpers;
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

static LogString ppIndentL1(LOG4CXX_STR("  "));
static LogString ppIndentL2(LOG4CXX_STR("    "));

/**
 * Test for JSONLayout.
 *
 */
LOGUNIT_CLASS(JSONLayoutTest), public JSONLayout
{
	LOGUNIT_TEST_SUITE(JSONLayoutTest);
	LOGUNIT_TEST(testGetContentType);
	LOGUNIT_TEST(testIgnoresThrowable);
	LOGUNIT_TEST(testAppendQuotedEscapedStringWithPrintableChars);
	LOGUNIT_TEST(testAppendQuotedEscapedStringWithControlChars);
	LOGUNIT_TEST(testAppendSerializedMDC);
	LOGUNIT_TEST(testAppendSerializedMDCWithPrettyPrint);
	LOGUNIT_TEST(testAppendSerializedNDC);
	LOGUNIT_TEST(testAppendSerializedNDCWithPrettyPrint);
	LOGUNIT_TEST(testAppendSerializedLocationInfo);
	LOGUNIT_TEST(testAppendSerializedLocationInfoWithPrettyPrint);
	LOGUNIT_TEST(testFormat);
	LOGUNIT_TEST(testFormatWithPrettyPrint);
	LOGUNIT_TEST(testGetSetLocationInfo);
	LOGUNIT_TEST(testAppendQuotedEscapedString);
	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("application/json"));
		LogString actual(JSONLayout().getContentType());
		LOGUNIT_ASSERT(expected == actual);
	}

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

	/**
	 * Tests appendQuotedEscapedString with printable characters.
	 */
	void testAppendQuotedEscapedStringWithPrintableChars()
	{
		LogString s1(LOG4CXX_STR("foo"));   /*  foo */
		LogString s2;
		appendQuotedEscapedString(s2, s1);  /*  "foo"  */
		LOGUNIT_ASSERT_EQUAL(LOG4CXX_STR("\"foo\""), s2);

		LogString s3;
		appendQuotedEscapedString(s3, s2);  /*  "\"foo\""  */
		LOGUNIT_ASSERT_EQUAL(LOG4CXX_STR("\"\\\"foo\\\"\""), s3);

		LogString t1(LOG4CXX_STR("bar\"baz"));  /*  bar"baz */
		LogString t2;
		appendQuotedEscapedString(t2, t1);      /*  "bar\"baz"  */
		LOGUNIT_ASSERT_EQUAL(LOG4CXX_STR("\"bar\\\"baz\""), t2);

		LogString t3;
		appendQuotedEscapedString(t3, t2);      /*  "\"bar\\\"baz\""    */
		LOGUNIT_ASSERT_EQUAL(LOG4CXX_STR("\"\\\"bar\\\\\\\"baz\\\"\""), t3);
	}

	/**
	 * Tests appendQuotedEscapedString with control characters.
	 */
	void testAppendQuotedEscapedStringWithControlChars()
	{
		logchar bs[] = {0x08, 0x00};
		logchar bs_expected[] = {0x22, 0x5c, 'b', 0x22, 0x00};      /* "\b" */
		LogString bs_escaped;

		appendQuotedEscapedString(bs_escaped, bs);
		LOGUNIT_ASSERT_EQUAL(bs_expected, bs_escaped);

		logchar tab[] = {0x09, 0x00};
		logchar tab_expected[] = {0x22, 0x5c, 't', 0x22, 0x00};     /* "\t" */
		LogString tab_escaped;

		appendQuotedEscapedString(tab_escaped, tab);
		LOGUNIT_ASSERT_EQUAL(tab_expected, tab_escaped);

		logchar newline[] = {0x0a, 0x00};
		logchar newline_expected[] = {0x22, 0x5c, 'n', 0x22, 0x00}; /* "\n" */
		LogString newline_escaped;

		appendQuotedEscapedString(newline_escaped, newline);
		LOGUNIT_ASSERT_EQUAL(newline_expected, newline_escaped);

		logchar ff[] = {0x0c, 0x00};
		logchar ff_expected[] = {0x22, 0x5c, 'f', 0x22, 0x00};      /* "\f" */
		LogString ff_escaped;

		appendQuotedEscapedString(ff_escaped, ff);
		LOGUNIT_ASSERT_EQUAL(ff_expected, ff_escaped);

		logchar cr[] = {0x0d, 0x00};
		logchar cr_expected[] = {0x22, 0x5c, 'r', 0x22, 0x00};      /* "\r" */
		LogString cr_escaped;

		appendQuotedEscapedString(cr_escaped, cr);
		LOGUNIT_ASSERT_EQUAL(cr_expected, cr_escaped);

		logchar sub[] = {0x1a, 0x00};
		logchar sub_expected[] = {0x22, 0x5c, 'u', 0x30, 0x30, 0x31, 0x61, 0x22, 0x00};      /* SUB */
		LogString sub_escaped;

		appendQuotedEscapedString(sub_escaped, sub);
		LOGUNIT_ASSERT_EQUAL(sub_expected, sub_escaped);

		logchar esc[] = {0x1e, 0x00};
		logchar esc_expected[] = {0x22, 0x5c, 'u', 0x30, 0x30, 0x31, 0x65, 0x22, 0x00};      /* ESC */
		LogString esc_escaped;

		appendQuotedEscapedString(esc_escaped, esc);
		LOGUNIT_ASSERT_EQUAL(esc_expected, esc_escaped);
	}

	/**
	 * Tests appendSerializedMDC.
	 */
	void testAppendSerializedMDC()
	{
		LoggingEventPtr event1 = LoggingEventPtr(new LoggingEvent(LOG4CXX_STR("Logger"),
					Level::getInfo(),
					LOG4CXX_STR("A message goes here."),
					LOG4CXX_LOCATION));

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

		LogString output1;
		LogString expected1 = LOG4CXX_STR(", \"context_map\": { "
				"\"key1\": \"value1\", \"key2\": \"value2\" }");

		appendSerializedMDC(output1, event1);
		LOGUNIT_ASSERT_EQUAL(expected1, output1);
	}

	/**
	 * Tests appendSerializedMDC with prettyPrint set to true.
	 */
	void testAppendSerializedMDCWithPrettyPrint()
	{
		LoggingEventPtr event1 = LoggingEventPtr(new LoggingEvent(LOG4CXX_STR("Logger"),
					Level::getInfo(),
					LOG4CXX_STR("A message goes here."),
					LOG4CXX_LOCATION));

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

		LogString output1;
		LogString expected1;

		expected1
		.append(LOG4CXX_STR(","))
		.append(LOG4CXX_EOL)
		.append(ppIndentL1)
		.append(LOG4CXX_STR("\"context_map\": {"))
		.append(LOG4CXX_EOL)
		.append(ppIndentL2)
		.append(LOG4CXX_STR("\"key1\": \"value1\","))
		.append(LOG4CXX_EOL)
		.append(ppIndentL2)
		.append(LOG4CXX_STR("\"key2\": \"value2\""))
		.append(LOG4CXX_EOL)
		.append(ppIndentL1)
		.append(LOG4CXX_STR("}"));

		setPrettyPrint(true);
		appendSerializedMDC(output1, event1);

		LOGUNIT_ASSERT_EQUAL(expected1, output1);
	}

	/**
	 * Tests appendSerializedNDC.
	 */
	void testAppendSerializedNDC()
	{
		LoggingEventPtr event1 = LoggingEventPtr(new LoggingEvent(LOG4CXX_STR("Logger"),
					Level::getInfo(),
					LOG4CXX_STR("A message goes here."),
					LOG4CXX_LOCATION));

		NDC::push("one");
		NDC::push("two");
		NDC::push("three");

		LogString output1;
		LogString expected1 = LOG4CXX_STR(", \"context_stack\": [ \"one two three\" ]");

		appendSerializedNDC(output1, event1);
		LOGUNIT_ASSERT_EQUAL(expected1, output1);
	}

	/**
	 * Tests appendSerializedNDC with prettyPrint set to true.
	 */
	void testAppendSerializedNDCWithPrettyPrint()
	{
		LoggingEventPtr event1 = LoggingEventPtr(new LoggingEvent(LOG4CXX_STR("Logger"),
					Level::getInfo(),
					LOG4CXX_STR("A message goes here."),
					LOG4CXX_LOCATION));

		NDC::push("one");
		NDC::push("two");
		NDC::push("three");

		LogString output1;
		LogString expected1;

		expected1
		.append(LOG4CXX_STR(","))
		.append(LOG4CXX_EOL)
		.append(ppIndentL1)
		.append(LOG4CXX_STR("\"context_stack\": ["))
		.append(LOG4CXX_EOL)
		.append(ppIndentL2)
		.append(LOG4CXX_STR("\"one two three\""))
		.append(LOG4CXX_EOL)
		.append(ppIndentL1)
		.append(LOG4CXX_STR("]"));

		setPrettyPrint(true);
		appendSerializedNDC(output1, event1);

		LOGUNIT_ASSERT_EQUAL(expected1, output1);
	}

	/**
	 * Tests appendSerializedLocationInfo.
	 */
	void testAppendSerializedLocationInfo()
	{
		Pool p;

		LoggingEventPtr event1 = LoggingEventPtr(new LoggingEvent(LOG4CXX_STR("Logger"),
					Level::getInfo(),
					LOG4CXX_STR("A message goes here."),
					spi::LocationInfo("FooFile", "FooFile", "BarFunc", 42)));

		LogString output1;
		LogString expected1;

		expected1
		.append(LOG4CXX_STR("\"location_info\": { "))
		.append(LOG4CXX_STR("\"file\": \"FooFile\", "))
		.append(LOG4CXX_STR("\"line\": \"42\", "))
		.append(LOG4CXX_STR("\"class\": \"\", "))
		.append(LOG4CXX_STR("\"method\": \"BarFunc\" }"));

		appendSerializedLocationInfo(output1, event1, p);
		LOGUNIT_ASSERT_EQUAL(expected1, output1);
	}

	/**
	 * Tests appendSerializedLocationInfo with prettyPrint set to true.
	 */
	void testAppendSerializedLocationInfoWithPrettyPrint()
	{
		Pool p;

		LoggingEventPtr event1 = LoggingEventPtr(new LoggingEvent(LOG4CXX_STR("Logger"),
					Level::getInfo(),
					LOG4CXX_STR("A message goes here."),
					spi::LocationInfo("FooFile", "FooFile", "BarFunc", 42)));

		LogString output1;
		LogString expected1;

		expected1
		.append(ppIndentL1)
		.append(LOG4CXX_STR("\"location_info\": {"))
		.append(LOG4CXX_EOL)
		.append(ppIndentL2)
		.append(LOG4CXX_STR("\"file\": \"FooFile\","))
		.append(LOG4CXX_EOL)
		.append(ppIndentL2)
		.append(LOG4CXX_STR("\"line\": \"42\","))
		.append(LOG4CXX_EOL)
		.append(ppIndentL2)
		.append(LOG4CXX_STR("\"class\": \"\","))
		.append(LOG4CXX_EOL)
		.append(ppIndentL2)
		.append(LOG4CXX_STR("\"method\": \"BarFunc\""))
		.append(LOG4CXX_EOL)
		.append(ppIndentL1)
		.append(LOG4CXX_STR("}"));

		setPrettyPrint(true);
		appendSerializedLocationInfo(output1, event1, p);

		LOGUNIT_ASSERT_EQUAL(expected1, output1);
	}

	/**
	 * Tests format.
	 */
	void testFormat()
	{
		Pool p;

		LoggingEventPtr event1 = LoggingEventPtr(new LoggingEvent(LOG4CXX_STR("Logger"),
					Level::getInfo(),
					LOG4CXX_STR("A message goes here."),
					spi::LocationInfo("FooFile", "FooFile", "BarFunc", 42)));

		LogString timestamp;
		helpers::ISO8601DateFormat dateFormat;
		dateFormat.format(timestamp, event1->getTimeStamp(), p);

		NDC::push("one");
		NDC::push("two");
		NDC::push("three");

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

		LogString output1;
		LogString expected1;

		expected1
		.append(LOG4CXX_STR("{ \"timestamp\": \""))
		.append(timestamp)
		.append(LOG4CXX_STR("\", "))
		.append(LOG4CXX_STR("\"level\": \"INFO\", "))
		.append(LOG4CXX_STR("\"logger\": \"Logger\", "))
		.append(LOG4CXX_STR("\"message\": \"A message goes here.\""));

		setLocationInfo(true);

		appendSerializedMDC(expected1, event1);
		appendSerializedNDC(expected1, event1);
		expected1.append(LOG4CXX_STR(", "));
		appendSerializedLocationInfo(expected1, event1, p);

		expected1.append(LOG4CXX_STR(" }"));
		expected1.append(LOG4CXX_EOL);
		format(output1, event1, p);

		LOGUNIT_ASSERT_EQUAL(expected1, output1);
	}

	/**
	 * Tests format with PrettyPrint set to true.
	 */
	void testFormatWithPrettyPrint()
	{
		Pool p;

		LoggingEventPtr event1 = LoggingEventPtr(new LoggingEvent(LOG4CXX_STR("Logger"),
					Level::getInfo(),
					LOG4CXX_STR("A message goes here."),
					spi::LocationInfo("FooFile", "FooFile", "BarFunc", 42)));

		LogString timestamp;
		helpers::ISO8601DateFormat dateFormat;
		dateFormat.format(timestamp, event1->getTimeStamp(), p);

		NDC::push("one");
		NDC::push("two");
		NDC::push("three");

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

		LogString output1;
		LogString expected1;

		expected1
		.append(LOG4CXX_STR("{"))
		.append(LOG4CXX_EOL)
		.append(ppIndentL1)
		.append(LOG4CXX_STR("\"timestamp\": \""))
		.append(timestamp)
		.append(LOG4CXX_STR("\","))
		.append(LOG4CXX_EOL)
		.append(ppIndentL1)
		.append(LOG4CXX_STR("\"level\": \"INFO\","))
		.append(LOG4CXX_EOL)
		.append(ppIndentL1)
		.append(LOG4CXX_STR("\"logger\": \"Logger\","))
		.append(LOG4CXX_EOL)
		.append(ppIndentL1)
		.append(LOG4CXX_STR("\"message\": \"A message goes here.\""));

		setPrettyPrint(true);
		setLocationInfo(true);

		appendSerializedMDC(expected1, event1);
		appendSerializedNDC(expected1, event1);
		expected1.append(LOG4CXX_STR(","));
		expected1.append(LOG4CXX_EOL);
		appendSerializedLocationInfo(expected1, event1, p);

		expected1.append(LOG4CXX_EOL);
		expected1.append(LOG4CXX_STR("}"));
		expected1.append(LOG4CXX_EOL);
		format(output1, event1, p);

		LOGUNIT_ASSERT_EQUAL(expected1, output1);
	}

	/**
	 * Tests getLocationInfo and setLocationInfo.
	 */
	void testGetSetLocationInfo()
	{
		JSONLayout 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 getPrettyPrint and setPrettyPrint.
	 */
	void testGetSetPrettyPrint()
	{
		JSONLayout layout;
		LOGUNIT_ASSERT_EQUAL(false, layout.getPrettyPrint());
		layout.setPrettyPrint(true);
		LOGUNIT_ASSERT_EQUAL(true, layout.getPrettyPrint());
		layout.setPrettyPrint(false);
		LOGUNIT_ASSERT_EQUAL(false, layout.getPrettyPrint());
	}

	/**
	 * Tests Unicode characters.
	 */
	void testAppendQuotedEscapedString()
	{
		std::string problemMessage = "'\001\"Hello \"\004'";
		LogString expectedQuotedEscapedMessage = LOG4CXX_STR("\"'\\u0001\\\"Hello \\\"\\u0004'\"");
		LOG4CXX_DECODE_CHAR(problemMessageLS, problemMessage);
		LogString quotedEscapedMessage;
		appendQuotedEscapedString(quotedEscapedMessage, problemMessageLS);
		LOGUNIT_ASSERT_EQUAL(expectedQuotedEscapedMessage, quotedEscapedMessage);

		// '\"räksmörgås.josefsson.org\"'
		std::string problemName = "'\"\162\303\244\153\163\155\303\266\162\147\303\245\163\056\152\157\163\145\146\163\163\157\156\056\157\162\147\"'";
		LOG4CXX_DECODE_CHAR(problemNameLS, problemName);
		LogString expectedQuotedEscapedName = LOG4CXX_STR("\"") + problemNameLS + LOG4CXX_STR("\"");
		expectedQuotedEscapedName.insert(2, 1, 0x5c); // insert a backslash before the first double quote
		expectedQuotedEscapedName.insert(expectedQuotedEscapedName.size() - 3, 1, 0x5c); // insert a backslash before the last double quote
		LogString quotedEscapedName;
		appendQuotedEscapedString(quotedEscapedName, problemNameLS);
		LOGUNIT_ASSERT_EQUAL(expectedQuotedEscapedName, quotedEscapedName);

		Transcoder::encode(0xD822, problemNameLS); // Add a character that cannot be converted to UTF16
#if LOG4CXX_LOGCHAR_IS_WCHAR && defined(__STDC_ISO_10646__)
		expectedQuotedEscapedName[expectedQuotedEscapedName.size() - 1] = 0xD822;
		expectedQuotedEscapedName += 0x22; // Add a double quote at the end
#elif LOG4CXX_LOGCHAR_IS_WCHAR
		// encodeUTF16 adds 0xD822, but decodeUTF16 cannot convert 0xD822
		expectedQuotedEscapedName.insert(expectedQuotedEscapedName.size() - 1, LOG4CXX_STR("\\ufffd")); // The Unicode replacement character
#elif LOG4CXX_LOGCHAR_IS_UTF8
		// 0xD822 is encoded in UTF-8 as 0xED 0xA0 0xA2
		expectedQuotedEscapedName.insert(expectedQuotedEscapedName.size() - 1, "\xED\xA0\xA2");
#endif
		LogString escapedQuoted0xD822Name;
		appendQuotedEscapedString(escapedQuoted0xD822Name, problemNameLS);
		LOGUNIT_ASSERT_EQUAL(expectedQuotedEscapedName, escapedQuoted0xD822Name);
	}
};


LOGUNIT_TEST_SUITE_REGISTRATION(JSONLayoutTest);

