/*
 * 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/logstring.h>
#include <log4cxx/jsonlayout.h>
#include <log4cxx/spi/loggingevent.h>
#include <log4cxx/level.h>
#include <log4cxx/helpers/optionconverter.h>
#include <log4cxx/helpers/cacheddateformat.h>
#include <log4cxx/helpers/simpledateformat.h>
#include <log4cxx/helpers/stringhelper.h>
#include <log4cxx/helpers/transcoder.h>
#include <log4cxx/private/layout_priv.h>

#include <string.h>

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

IMPLEMENT_LOG4CXX_OBJECT(JSONLayout)

struct JSONLayout::JSONLayoutPrivate
{
	JSONLayoutPrivate() :
		locationInfo(false),
		prettyPrint(false),
		ppIndentL1(LOG4CXX_STR("  ")),
		ppIndentL2(LOG4CXX_STR("    ")),
		expectedPatternLength(100),
		threadInfo(false) {}

	// Print no location info by default
	bool locationInfo; //= false
	bool prettyPrint; //= false

	pattern::CachedDateFormat dateFormat
		{ std::make_shared<helpers::SimpleDateFormat>(LOG4CXX_STR("yyyy-MM-dd HH:mm:ss,SSS"))
		, pattern::CachedDateFormat::getMaximumCacheValidity(LOG4CXX_STR("yyyy-MM-dd HH:mm:ss,SSS"))
		};

	LogString ppIndentL1;
	LogString ppIndentL2;

	// Expected length of a formatted event excluding the message text
	size_t expectedPatternLength;

	// Thread info is not included by default
	bool threadInfo; //= false
};

JSONLayout::JSONLayout() :
	m_priv(std::make_unique<JSONLayoutPrivate>())
{
}

JSONLayout::~JSONLayout(){}

void JSONLayout::setLocationInfo(bool locationInfoFlag)
{
	m_priv->locationInfo = locationInfoFlag;
}

bool JSONLayout::getLocationInfo() const
{
	return m_priv->locationInfo;
}

void JSONLayout::setPrettyPrint(bool prettyPrintFlag)
{
	m_priv->prettyPrint = prettyPrintFlag;
}

bool JSONLayout::getPrettyPrint() const
{
	return m_priv->prettyPrint;
}

void JSONLayout::setThreadInfo(bool newValue)
{
	m_priv->threadInfo = newValue;
}

bool JSONLayout::getThreadInfo() const
{
	return m_priv->threadInfo;
}

LogString JSONLayout::getContentType() const
{
	return LOG4CXX_STR("application/json");
}

void JSONLayout::activateOptions(  )
{
	m_priv->expectedPatternLength = priv::doubledLayoutSize(getFormattedEventCharacterCount());
}

void JSONLayout::setOption(const LogString& option, const LogString& value)
{
	if (StringHelper::equalsIgnoreCase(option,
			LOG4CXX_STR("LOCATIONINFO"), LOG4CXX_STR("locationinfo")))
	{
		setLocationInfo(OptionConverter::toBoolean(value, false));
	}
	else if (StringHelper::equalsIgnoreCase(option,
			LOG4CXX_STR("THREADINFO"), LOG4CXX_STR("threadinfo")))
	{
		setThreadInfo(OptionConverter::toBoolean(value, false));
	}
	else if (StringHelper::equalsIgnoreCase(option,
			LOG4CXX_STR("PRETTYPRINT"), LOG4CXX_STR("prettyprint")))
	{
		setPrettyPrint(OptionConverter::toBoolean(value, false));
	}
	else
		Layout::setOption(option, value);
}

void JSONLayout::format( LogString& output, const spi::LoggingEventPtr& event ) const
{
	auto& lsMsg = event->getRenderedMessage();
	priv::reserveFormattedEvent(output, m_priv->expectedPatternLength, lsMsg.size());
	output.append(LOG4CXX_STR("{"));
	output.append(m_priv->prettyPrint ? LOG4CXX_EOL : LOG4CXX_STR(" "));

	if (m_priv->prettyPrint)
	{
		output.append(m_priv->ppIndentL1);
	}

	output.append(LOG4CXX_STR("\"timestamp\": \""));
	m_priv->dateFormat.format(output, event->getTimeStamp());
	output.append(LOG4CXX_STR("\","));
	output.append(m_priv->prettyPrint ? LOG4CXX_EOL : LOG4CXX_STR(" "));

	if (m_priv->threadInfo)
	{
		if (m_priv->prettyPrint)
		{
			output.append(m_priv->ppIndentL1);
		}
		appendQuotedEscapedString(output, LOG4CXX_STR("thread"));
		output.append(LOG4CXX_STR(": "));
		appendQuotedEscapedString(output, event->getThreadName());
		output.append(LOG4CXX_STR(","));
		output.append(m_priv->prettyPrint ? LOG4CXX_EOL : LOG4CXX_STR(" "));
	}

	if (m_priv->prettyPrint)
	{
		output.append(m_priv->ppIndentL1);
	}

	output.append(LOG4CXX_STR("\"level\": "));
	LogString level;
	event->getLevel()->toString(level);
	appendQuotedEscapedString(output, level);
	output.append(LOG4CXX_STR(","));
	output.append(m_priv->prettyPrint ? LOG4CXX_EOL : LOG4CXX_STR(" "));

	if (m_priv->prettyPrint)
	{
		output.append(m_priv->ppIndentL1);
	}

	output.append(LOG4CXX_STR("\"logger\": "));
	appendQuotedEscapedString(output, event->getLoggerName());
	output.append(LOG4CXX_STR(","));
	output.append(m_priv->prettyPrint ? LOG4CXX_EOL : LOG4CXX_STR(" "));

	if (m_priv->prettyPrint)
	{
		output.append(m_priv->ppIndentL1);
	}

	output.append(LOG4CXX_STR("\"message\": "));
	appendQuotedEscapedString(output, lsMsg);

	appendSerializedMDC(output, event);
	appendSerializedNDC(output, event);

	if (m_priv->locationInfo)
	{
		output.append(LOG4CXX_STR(","));
		output.append(m_priv->prettyPrint ? LOG4CXX_EOL : LOG4CXX_STR(" "));
		appendSerializedLocationInfo(output, event);
	}

	output.append(m_priv->prettyPrint ? LOG4CXX_EOL : LOG4CXX_STR(" "));
	output.append(LOG4CXX_STR("}"));
	output.append(LOG4CXX_EOL);
}

void JSONLayout::appendQuotedEscapedString(LogString& buf,
	const LogString& input) const
{
	appendItem(input, buf);
}

void JSONLayout::appendItem(const LogString& input, LogString& buf)
{
	auto toHexDigit = [](int ch) -> int
	{
		return (10 <= ch ? (0x61 - 10) : 0x30) + ch;
	};
	/* add leading quote */
	buf.push_back(0x22);

	auto start = input.begin();
	for (auto nextCodePoint = start; input.end() != nextCodePoint; )
	{
		auto lastCodePoint = nextCodePoint;
		auto ch = static_cast<unsigned int>(*nextCodePoint);
		if (ch <= 0x7f)
			++nextCodePoint;
		else
			ch = Transcoder::getCodePoint(input, nextCodePoint);
		if (0x22 == ch || 0x5c == ch) // double quote or backslash?
			;
		else if (0x20 <= ch && 0xFFFD != ch) // not a control character or the replacement character?
			continue;

		if (start != lastCodePoint)
			buf.append(start, lastCodePoint);
		start = nextCodePoint;
		switch (ch)
		{
			case 0x08:
				/* \b backspace */
				buf.push_back(0x5c);
				buf.push_back('b');
				break;

			case 0x09:
				/* \t tab */
				buf.push_back(0x5c);
				buf.push_back('t');
				break;

			case 0x0a:
				/* \n newline */
				buf.push_back(0x5c);
				buf.push_back('n');
				break;

			case 0x0c:
				/* \f form feed */
				buf.push_back(0x5c);
				buf.push_back('f');
				break;

			case 0x0d:
				/* \r carriage return */
				buf.push_back(0x5c);
				buf.push_back('r');
				break;

			case 0x22:
				/* \" double quote */
				buf.push_back(0x5c);
				buf.push_back(0x22);
				break;

			case 0x5c:
				/* \\ backslash */
				buf.push_back(0x5c);
				buf.push_back(0x5c);
				break;

			default:
				buf.push_back(0x5c);
				buf.push_back(0x75); // 'u'
				buf.push_back(toHexDigit((ch & 0xF000) >> 12));
				buf.push_back(toHexDigit((ch & 0xF00) >> 8));
				buf.push_back(toHexDigit((ch & 0xF0) >> 4));
				buf.push_back(toHexDigit(ch & 0xF));
				break;
		}
	}
	buf.append(start, input.end());

	/* add trailing quote */
	buf.push_back(0x22);
}

void JSONLayout::appendSerializedMDC(LogString& buf,
	const LoggingEventPtr& event) const
{
	LoggingEvent::KeySet keys = event->getMDCKeySet();

	if (keys.empty())
	{
		return;
	}

	buf.append(LOG4CXX_STR(","));
	buf.append(m_priv->prettyPrint ? LOG4CXX_EOL : LOG4CXX_STR(" "));

	if (m_priv->prettyPrint)
	{
		buf.append(m_priv->ppIndentL1);
	}

	appendQuotedEscapedString(buf, LOG4CXX_STR("context_map"));
	buf.append(LOG4CXX_STR(": {"));
	buf.append(m_priv->prettyPrint ? LOG4CXX_EOL : LOG4CXX_STR(" "));

	for (LoggingEvent::KeySet::iterator it = keys.begin();
		it != keys.end(); ++it)
	{
		if (m_priv->prettyPrint)
		{
			buf.append(m_priv->ppIndentL2);
		}

		appendQuotedEscapedString(buf, *it);
		buf.append(LOG4CXX_STR(": "));
		LogString value;
		event->getMDC(*it, value);
		appendQuotedEscapedString(buf, value);

		/* if this isn't the last k:v pair, we need a comma */
		if (it + 1 != keys.end())
		{
			buf.append(LOG4CXX_STR(","));
			buf.append(m_priv->prettyPrint ? LOG4CXX_EOL : LOG4CXX_STR(" "));
		}
		else
		{
			buf.append(m_priv->prettyPrint ? LOG4CXX_EOL : LOG4CXX_STR(" "));
		}
	}

	if (m_priv->prettyPrint)
	{
		buf.append(m_priv->ppIndentL1);
	}

	buf.append(LOG4CXX_STR("}"));
}

void JSONLayout::appendSerializedNDC(LogString& buf,
	const LoggingEventPtr& event) const
{
	LogString ndcVal;

	if (!event->getNDC(ndcVal))
	{
		return;
	}

	buf.append(LOG4CXX_STR(","));
	buf.append(m_priv->prettyPrint ? LOG4CXX_EOL : LOG4CXX_STR(" "));

	if (m_priv->prettyPrint)
	{
		buf.append(m_priv->ppIndentL1);
	}

	appendQuotedEscapedString(buf, LOG4CXX_STR("context_stack"));
	buf.append(LOG4CXX_STR(": ["));
	buf.append(m_priv->prettyPrint ? LOG4CXX_EOL : LOG4CXX_STR(" "));

	if (m_priv->prettyPrint)
	{
		buf.append(m_priv->ppIndentL2);
	}

	appendQuotedEscapedString(buf, ndcVal);
	buf.append(m_priv->prettyPrint ? LOG4CXX_EOL : LOG4CXX_STR(" "));

	if (m_priv->prettyPrint)
	{
		buf.append(m_priv->ppIndentL1);
	}

	buf.append(LOG4CXX_STR("]"));
}

void JSONLayout::appendSerializedLocationInfo(LogString& buf, const LoggingEventPtr& event) const
{
	if (m_priv->prettyPrint)
	{
		buf.append(m_priv->ppIndentL1);
	}

	appendQuotedEscapedString(buf, LOG4CXX_STR("location_info"));
	buf.append(LOG4CXX_STR(": {"));
	buf.append(m_priv->prettyPrint ? LOG4CXX_EOL : LOG4CXX_STR(" "));
	const LocationInfo& locInfo = event->getLocationInformation();

	if (m_priv->prettyPrint)
	{
		buf.append(m_priv->ppIndentL2);
	}

	appendQuotedEscapedString(buf, LOG4CXX_STR("file"));
	buf.append(LOG4CXX_STR(": "));
	LOG4CXX_DECODE_CHAR(fileName, locInfo.getFileName());
	appendQuotedEscapedString(buf, fileName);
	buf.append(LOG4CXX_STR(","));
	buf.append(m_priv->prettyPrint ? LOG4CXX_EOL : LOG4CXX_STR(" "));

	if (m_priv->prettyPrint)
	{
		buf.append(m_priv->ppIndentL2);
	}

	appendQuotedEscapedString(buf, LOG4CXX_STR("line"));
	buf.append(LOG4CXX_STR(": "));
	LogString lineNumber;
	StringHelper::toString(locInfo.getLineNumber(), lineNumber);
	appendQuotedEscapedString(buf, lineNumber);
	buf.append(LOG4CXX_STR(","));
	buf.append(m_priv->prettyPrint ? LOG4CXX_EOL : LOG4CXX_STR(" "));

	if (m_priv->prettyPrint)
	{
		buf.append(m_priv->ppIndentL2);
	}

	appendQuotedEscapedString(buf, LOG4CXX_STR("class"));
	buf.append(LOG4CXX_STR(": "));
	LOG4CXX_DECODE_CHAR(className, locInfo.getClassName());
	appendQuotedEscapedString(buf, className);
	buf.append(LOG4CXX_STR(","));
	buf.append(m_priv->prettyPrint ? LOG4CXX_EOL : LOG4CXX_STR(" "));

	if (m_priv->prettyPrint)
	{
		buf.append(m_priv->ppIndentL2);
	}

	appendQuotedEscapedString(buf, LOG4CXX_STR("method"));
	buf.append(LOG4CXX_STR(": "));
	LOG4CXX_DECODE_CHAR(methodName, locInfo.getMethodName());
	appendQuotedEscapedString(buf, methodName);
	buf.append(m_priv->prettyPrint ? LOG4CXX_EOL : LOG4CXX_STR(" "));

	if (m_priv->prettyPrint)
	{
		buf.append(m_priv->ppIndentL1);
	}

	buf.append(LOG4CXX_STR("}"));
}

