/*
 * 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 <chrono>
#include <log4cxx/spi/loggingevent.h>
#include <log4cxx/ndc.h>

#include <log4cxx/level.h>
#include <log4cxx/helpers/loglog.h>
#include <log4cxx/helpers/system.h>
#include <log4cxx/helpers/socket.h>
#if !defined(LOG4CXX)
	#define LOG4CXX 1
#endif
#include <log4cxx/helpers/aprinitializer.h>
#include <log4cxx/helpers/threadspecificdata.h>
#include <log4cxx/helpers/bytebuffer.h>
#include <log4cxx/helpers/messagebuffer.h>
#include <log4cxx/helpers/date.h>
#include <log4cxx/helpers/optional.h>

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

struct LoggingEvent::LoggingEventPrivate
{
	LoggingEventPrivate(const ThreadSpecificData::NamePairPtr p = ThreadSpecificData::getNames()) :
		timeStamp(0),
		pNames(p)
	{
	}

	LoggingEventPrivate
		( const LogString& logger1
		, const LevelPtr& level1
		, const LocationInfo& locationInfo1
		, LogString&& message1
		, const ThreadSpecificData::NamePairPtr p = ThreadSpecificData::getNames()
		) :
		logger(logger1),
		level(level1),
		message(std::move(message1)),
		timeStamp(Date::currentTime()),
		locationInfo(locationInfo1),
		chronoTimeStamp(std::chrono::microseconds(timeStamp)),
		pNames(p)
	{
	}

	LoggingEventPrivate
		( const LogString& logger1
		, const LevelPtr& level1
		, const LocationInfo& locationInfo1
		, helpers::AsyncBuffer&& messageAppenderArg
		, const ThreadSpecificData::NamePairPtr p = ThreadSpecificData::getNames()
		)
		: logger(logger1)
		, level(level1)
		, timeStamp(Date::currentTime())
		, locationInfo(locationInfo1)
		, chronoTimeStamp(std::chrono::microseconds(timeStamp))
		, pNames(p)
		, messageAppender(std::move(messageAppenderArg))
	{
	}

	LoggingEventPrivate(
		const LogString& logger1, const LevelPtr& level1,
		const LogString& message1, const LocationInfo& locationInfo1,
		const ThreadSpecificData::NamePairPtr& p = ThreadSpecificData::getNames()
		) :
		logger(logger1),
		level(level1),
		message(message1),
		timeStamp(Date::currentTime()),
		locationInfo(locationInfo1),
		chronoTimeStamp(std::chrono::microseconds(timeStamp)),
		pNames(p)
	{
	}

	~LoggingEventPrivate()
	{
		delete properties;
	}

	/**
	* The name of the logger used to make the logging request
	**/
	LogString logger;

	/** severity level of logging event. */
	LevelPtr level;

	/**
	* A map of String keys and String values.
	*/
	std::map<LogString, LogString>* properties{NULL};

	/** The application supplied message. */
	LogString message;


	/** The number of microseconds elapsed since 1970-01-01
	 *  at the time this logging event was created.
	 */
	log4cxx_time_t timeStamp;

	/** The source code location where the logging request was made. */
	const spi::LocationInfo locationInfo;

	std::chrono::time_point<std::chrono::system_clock> chronoTimeStamp;

	/**
	 *  Thread names that remain valid for the lifetime of this LoggingEvent
	 *  (i.e. even after thread termination).
	 */
	ThreadSpecificData::NamePairPtr pNames;

	struct DiagnosticContext
	{
		Optional<NDC::DiagnosticContext> ctx;
		MDC::Map map;
	};
	/**
	 *  Used to hold the diagnostic context when the lifetime
	 *  of this LoggingEvent exceeds the duration of the logging request.
	 */
	mutable std::unique_ptr<DiagnosticContext> dc;

	/** Application supplied message builders.
	 */
	helpers::AsyncBuffer messageAppender;

	void renderMessage()
	{
		if (!this->messageAppender.empty())
		{
			helpers::LogCharMessageBuffer buf;
			this->messageAppender.renderMessage(buf);
			this->message = buf.extract_str(buf);
			this->messageAppender.clear();
		}
	}
};

IMPLEMENT_LOG4CXX_OBJECT(LoggingEvent)


//
//   Accessor for start time.
//
log4cxx_time_t LoggingEvent::getStartTime()
{
	return APRInitializer::getStartTime();
}

LoggingEvent::LoggingEvent() :
	m_priv(std::make_unique<LoggingEventPrivate>())
{
}

LoggingEvent::LoggingEvent
	( const LogString&    logger
	, const LevelPtr&     level
	, const LocationInfo& location
	, LogString&&         message
	)
	: m_priv(std::make_unique<LoggingEventPrivate>(logger, level, location, std::move(message)))
{
}

LoggingEvent::LoggingEvent
	( const LogString&    logger
	, const LevelPtr&     level
	, const LocationInfo& location
	, helpers::AsyncBuffer&& messageAppender
	)
	: m_priv(std::make_unique<LoggingEventPrivate>(logger, level, location, std::move(messageAppender)))
{
}

LoggingEvent::LoggingEvent(
	const LogString& logger1, const LevelPtr& level1,
	const LogString& message1, const LocationInfo& locationInfo1) :
	m_priv(std::make_unique<LoggingEventPrivate>(logger1, level1, message1, locationInfo1))
{
}

LoggingEvent::~LoggingEvent()
{
}

const LogString& LoggingEvent::getThreadUserName() const
{
	return m_priv->pNames->threadName;
}

bool LoggingEvent::getNDC(LogString& dest) const
{
	bool result = false;
	// Use the copy of the diagnostic context if it exists.
	// Otherwise use the NDC that is associated with the thread.
	if (m_priv->dc)
	{
		result = bool(m_priv->dc->ctx);
		if (result)
			dest.append(NDC::getFullMessage(m_priv->dc->ctx.value()));
	}
	else
		result = NDC::get(dest);
	return result;
}

bool LoggingEvent::getMDC(const LogString& key, LogString& dest) const
{
	bool result = false;
	// Use the copy of the diagnostic context if it exists.
	// Otherwise use the MDC that is associated with the thread.
	if (m_priv->dc)
	{
		auto& map = m_priv->dc->map;
		auto it = map.find(key);
		if (it != map.end() && !it->second.empty())
		{
			dest.append(it->second);
			result = true;
		}
	}
	else
		result = MDC::get(key, dest);
	return result;
}

LoggingEvent::KeySet LoggingEvent::getMDCKeySet() const
{
	LoggingEvent::KeySet result;
	if (m_priv->dc)
	{
		for (auto const& item : m_priv->dc->map)
			result.push_back(item.first);
	}
	else if (auto pData = ThreadSpecificData::getCurrentData())
	{
		for (auto const& item : pData->getMap())
			result.push_back(item.first);
	}
	return result;
}

void LoggingEvent::LoadDC() const
{
	m_priv->dc = std::make_unique<LoggingEventPrivate::DiagnosticContext>();
	if (auto pData = ThreadSpecificData::getCurrentData())
	{
		m_priv->dc->map = pData->getMap();
		auto& stack = pData->getStack();
		if (!stack.empty())
			m_priv->dc->ctx = stack.top();
	}
}

#if LOG4CXX_ABI_VERSION <= 15
void LoggingEvent::getMDCCopy() const
{
	if (!m_priv->dc)
		LoadDC();
}
#endif

bool LoggingEvent::getProperty(const LogString& key, LogString& dest) const
{
	if (m_priv->properties == 0)
	{
		return false;
	}

	std::map<LogString, LogString>::const_iterator  it = m_priv->properties->find(key);

	if (it != m_priv->properties->end())
	{
		dest.append(it->second);
		return true;
	}

	return false;
}

LoggingEvent::KeySet LoggingEvent::getPropertyKeySet() const
{
	LoggingEvent::KeySet set;

	if (m_priv->properties)
	{
		for (auto item : *m_priv->properties)
		{
			set.push_back(item.first);
		}
	}

	return set;
}

void LoggingEvent::renderMessage()
{
	m_priv->renderMessage();
}

void LoggingEvent::setProperty(const LogString& key, const LogString& value)
{
	if (m_priv->properties == 0)
	{
		m_priv->properties = new std::map<LogString, LogString>;
	}

	(*m_priv->properties)[key] = value;
}

const LevelPtr& LoggingEvent::getLevel() const
{
	return m_priv->level;
}

const LogString& LoggingEvent::getLoggerName() const
{
	return m_priv->logger;
}

const LogString& LoggingEvent::getMessage() const
{
	return m_priv->message;
}

const LogString& LoggingEvent::getRenderedMessage() const
{
	m_priv->renderMessage();
	return m_priv->message;
}

const LogString& LoggingEvent::getThreadName() const
{
	return m_priv->pNames->idString;
}

log4cxx_time_t LoggingEvent::getTimeStamp() const
{
	return m_priv->timeStamp;
}

const LOG4CXX_NS::spi::LocationInfo& LoggingEvent::getLocationInformation() const
{
	return m_priv->locationInfo;
}

std::chrono::time_point<std::chrono::system_clock> LoggingEvent::getChronoTimeStamp() const{
	return m_priv->chronoTimeStamp;
}

