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

#include <apr_time.h>
#include <apr_portable.h>
#include <apr_strings.h>
#include <log4cxx/helpers/stringhelper.h>
#include <log4cxx/helpers/objectoutputstream.h>
#include <log4cxx/helpers/bytebuffer.h>
#include <log4cxx/logger.h>
#include <log4cxx/private/log4cxx_private.h>

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

IMPLEMENT_LOG4CXX_OBJECT(LoggingEvent)


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

LoggingEvent::LoggingEvent() :
	ndc(0),
	mdcCopy(0),
	properties(0),
	ndcLookupRequired(true),
	mdcCopyLookupRequired(true),
	timeStamp(0),
	locationInfo()
{
}

LoggingEvent::LoggingEvent(
	const LogString& logger1, const LevelPtr& level1,
	const LogString& message1, const LocationInfo& locationInfo1) :
	logger(logger1),
	level(level1),
	ndc(0),
	mdcCopy(0),
	properties(0),
	ndcLookupRequired(true),
	mdcCopyLookupRequired(true),
	message(message1),
	timeStamp(apr_time_now()),
	locationInfo(locationInfo1),
	threadName(getCurrentThreadName())
{
}

LoggingEvent::~LoggingEvent()
{
	delete ndc;
	delete mdcCopy;
	delete properties;
}

bool LoggingEvent::getNDC(LogString& dest) const
{
	if (ndcLookupRequired)
	{
		ndcLookupRequired = false;
		LogString val;

		if (NDC::get(val))
		{
			ndc = new LogString(val);
		}
	}

	if (ndc)
	{
		dest.append(*ndc);
		return true;
	}

	return false;
}

bool LoggingEvent::getMDC(const LogString& key, LogString& dest) const
{
	// Note the mdcCopy is used if it exists. Otherwise we use the MDC
	// that is associated with the thread.
	if (mdcCopy != 0 && !mdcCopy->empty())
	{
		MDC::Map::const_iterator it = mdcCopy->find(key);

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

	return MDC::get(key, dest);

}

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

	if (mdcCopy != 0 && !mdcCopy->empty())
	{
		MDC::Map::const_iterator it;

		for (it = mdcCopy->begin(); it != mdcCopy->end(); it++)
		{
			set.push_back(it->first);

		}
	}
	else
	{
		ThreadSpecificData* data = ThreadSpecificData::getCurrentData();

		if (data != 0)
		{
			MDC::Map& m = data->getMap();

			for (MDC::Map::const_iterator it = m.begin(); it != m.end(); it++)
			{
				set.push_back(it->first);
			}
		}
	}

	return set;
}

void LoggingEvent::getMDCCopy() const
{
	if (mdcCopyLookupRequired)
	{
		mdcCopyLookupRequired = false;
		// the clone call is required for asynchronous logging.
		ThreadSpecificData* data = ThreadSpecificData::getCurrentData();

		if (data != 0)
		{
			mdcCopy = new MDC::Map(data->getMap());
		}
		else
		{
			mdcCopy = new MDC::Map();
		}
	}
}

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

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

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

	return false;
}

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

	if (properties != 0)
	{
		std::map<LogString, LogString>::const_iterator it;

		for (it = properties->begin(); it != properties->end(); it++)
		{
			set.push_back(it->first);
		}
	}

	return set;
}


const LogString LoggingEvent::getCurrentThreadName()
{
#if APR_HAS_THREADS
#if defined(_WIN32)
	char result[20];
	DWORD threadId = GetCurrentThreadId();
	apr_snprintf(result, sizeof(result), LOG4CXX_WIN32_THREAD_FMTSPEC, threadId);
#else
	// apr_os_thread_t encoded in HEX takes needs as many characters
	// as two times the size of the type, plus an additional null byte.
	char result[sizeof(apr_os_thread_t) * 3 + 10];
	apr_os_thread_t threadId = apr_os_thread_current();
	apr_snprintf(result, sizeof(result), LOG4CXX_APR_THREAD_FMTSPEC, (void*) &threadId);
#endif
	LOG4CXX_DECODE_CHAR(str, (const char*) result);
	return str;
#else
	return LOG4CXX_STR("0x00000000");
#endif
}


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

	(*properties)[key] = value;
}



void LoggingEvent::writeProlog(ObjectOutputStream& os, Pool& p)
{
	unsigned char classDesc[] =
	{
		0x72, 0x00, 0x21,
		0x6F, 0x72, 0x67, 0x2E, 0x61, 0x70, 0x61, 0x63,
		0x68, 0x65, 0x2E, 0x6C, 0x6F, 0x67, 0x34, 0x6A,
		0x2E, 0x73, 0x70, 0x69, 0x2E, 0x4C, 0x6F, 0x67,
		0x67, 0x69, 0x6E, 0x67, 0x45, 0x76, 0x65, 0x6E,
		0x74, 0xF3, 0xF2, 0xB9, 0x23, 0x74, 0x0B, 0xB5,
		0x3F, 0x03, 0x00, 0x0A, 0x5A, 0x00, 0x15, 0x6D,
		0x64, 0x63, 0x43, 0x6F, 0x70, 0x79, 0x4C, 0x6F,
		0x6F, 0x6B, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75,
		0x69, 0x72, 0x65, 0x64, 0x5A, 0x00, 0x11, 0x6E,
		0x64, 0x63, 0x4C, 0x6F, 0x6F, 0x6B, 0x75, 0x70,
		0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64,
		0x4A, 0x00, 0x09, 0x74, 0x69, 0x6D, 0x65, 0x53,
		0x74, 0x61, 0x6D, 0x70, 0x4C, 0x00, 0x0C, 0x63,
		0x61, 0x74, 0x65, 0x67, 0x6F, 0x72, 0x79, 0x4E,
		0x61, 0x6D, 0x65, 0x74, 0x00, 0x12, 0x4C, 0x6A,
		0x61, 0x76, 0x61, 0x2F, 0x6C, 0x61, 0x6E, 0x67,
		0x2F, 0x53, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3B,
		0x4C, 0x00, 0x0C, 0x6C, 0x6F, 0x63, 0x61, 0x74,
		0x69, 0x6F, 0x6E, 0x49, 0x6E, 0x66, 0x6F, 0x74,
		0x00, 0x23, 0x4C, 0x6F, 0x72, 0x67, 0x2F, 0x61,
		0x70, 0x61, 0x63, 0x68, 0x65, 0x2F, 0x6C, 0x6F,
		0x67, 0x34, 0x6A, 0x2F, 0x73, 0x70, 0x69, 0x2F,
		0x4C, 0x6F, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E,
		0x49, 0x6E, 0x66, 0x6F, 0x3B, 0x4C, 0x00, 0x07,
		0x6D, 0x64, 0x63, 0x43, 0x6F, 0x70, 0x79, 0x74,
		0x00, 0x15, 0x4C, 0x6A, 0x61, 0x76, 0x61, 0x2F,
		0x75, 0x74, 0x69, 0x6C, 0x2F, 0x48, 0x61, 0x73,
		0x68, 0x74, 0x61, 0x62, 0x6C, 0x65, 0x3B, 0x4C,
		0x00, 0x03, 0x6E, 0x64, 0x63,
		0x74, 0x00, 0x12, 0x4C, 0x6A,
		0x61, 0x76, 0x61, 0x2F, 0x6C, 0x61, 0x6E, 0x67,
		0x2F, 0x53, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3B,
		0x4C, 0x00, 0x0F, 0x72, 0x65, 0x6E,
		0x64, 0x65, 0x72, 0x65, 0x64, 0x4D, 0x65, 0x73,
		0x73, 0x61, 0x67, 0x65,
		0x74, 0x00, 0x12, 0x4C, 0x6A,
		0x61, 0x76, 0x61, 0x2F, 0x6C, 0x61, 0x6E, 0x67,
		0x2F, 0x53, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3B,
		0x4C, 0x00, 0x0A, 0x74, 0x68, 0x72, 0x65,
		0x61, 0x64, 0x4E, 0x61, 0x6D, 0x65,
		0x74, 0x00, 0x12, 0x4C, 0x6A,
		0x61, 0x76, 0x61, 0x2F, 0x6C, 0x61, 0x6E, 0x67,
		0x2F, 0x53, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3B,
		0x4C, 0x00, 0x0D, 0x74, 0x68,
		0x72, 0x6F, 0x77, 0x61, 0x62, 0x6C, 0x65, 0x49,
		0x6E, 0x66, 0x6F, 0x74, 0x00, 0x2B, 0x4C, 0x6F,
		0x72, 0x67, 0x2F, 0x61, 0x70, 0x61, 0x63, 0x68,
		0x65, 0x2F, 0x6C, 0x6F, 0x67, 0x34, 0x6A, 0x2F,
		0x73, 0x70, 0x69, 0x2F, 0x54, 0x68, 0x72, 0x6F,
		0x77, 0x61, 0x62, 0x6C, 0x65, 0x49, 0x6E, 0x66,
		0x6F, 0x72, 0x6D, 0x61, 0x74, 0x69, 0x6F, 0x6E,
		0x3B, 0x78, 0x70
	};

	os.writeProlog("org.apache.log4j.spi.LoggingEvent",
		8, (char*) classDesc, sizeof(classDesc), p);
}

void LoggingEvent::write(helpers::ObjectOutputStream& os, Pool& p) const
{
	writeProlog(os, p);
	// mdc and ndc lookup required should always be false
	char lookupsRequired[] = { 0, 0 };
	os.writeBytes(lookupsRequired, sizeof(lookupsRequired), p);
	os.writeLong(timeStamp / 1000, p);
	os.writeObject(logger, p);
	locationInfo.write(os, p);

	if (mdcCopy == 0 || mdcCopy->size() == 0)
	{
		os.writeNull(p);
	}
	else
	{
		os.writeObject(*mdcCopy, p);
	}

	if (ndc == 0)
	{
		os.writeNull(p);
	}
	else
	{
		os.writeObject(*ndc, p);
	}

	os.writeObject(message, p);
	os.writeObject(threadName, p);
	//  throwable
	os.writeNull(p);
	os.writeByte(ObjectOutputStream::TC_BLOCKDATA, p);
	os.writeByte(0x04, p);
	os.writeInt(level->toInt(), p);
	os.writeNull(p);
	os.writeByte(ObjectOutputStream::TC_ENDBLOCKDATA, p);
}

