/*
 * 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/net/syslogappender.h>
#include <log4cxx/helpers/loglog.h>
#include <log4cxx/helpers/stringhelper.h>
#include <log4cxx/helpers/datagramsocket.h>
#include <log4cxx/spi/loggingevent.h>
#include <log4cxx/level.h>
#include <log4cxx/helpers/transcoder.h>
#include <log4cxx/helpers/optionconverter.h>
#if !defined(LOG4CXX)
	#define LOG4CXX 1
#endif
#include <log4cxx/private/syslogappender_priv.h>
#include <algorithm>

#define LOG_UNDEF -1

using namespace LOG4CXX_NS;
using namespace LOG4CXX_NS::helpers;
using namespace LOG4CXX_NS::net;

namespace
{
	constexpr size_t SYSLOG_PACKET_SUFFIX_RESERVED_CHARS = 12;

	void appendPacketSuffix(LogString& item, size_t current, size_t total)
	{
		item.append(LOG4CXX_STR("("));
		StringHelper::toString(current, item);
		item.append(LOG4CXX_STR("/"));
		StringHelper::toString(total, item);
		item.append(LOG4CXX_STR(")"));
	}
}

namespace LOG4CXX_NS
{
namespace net
{
namespace detail
{
LOG4CXX_EXPORT std::vector<LogString> splitSyslogPackets(const LogString& msg, size_t maxMessageLength)
{
	std::vector<LogString> packets;
	auto digitCount = [](size_t value) {
		size_t digits = 1u;
		while (value >= 10u)
		{
			value /= 10u;
			++digits;
		}
		return digits;
	};
	auto reservePackets = [&](size_t count) -> bool
	{
		if (count > packets.max_size())
		{
			LogLog::error(LOG4CXX_STR("SyslogAppender cannot reserve memory for packet splitting; message too large."));
			return false;
		}

		try
		{
			packets.reserve(count);
			return true;
		}
		catch (const std::length_error&)
		{
			LogLog::error(LOG4CXX_STR("SyslogAppender cannot reserve memory for packet splitting; message too large."));
			return false;
		}
	};
	auto splitByChunkSize = [&](size_t chunkSize, bool appendSuffix) -> bool
	{
		const size_t nChunks = msg.size() / chunkSize + ((msg.size() % chunkSize) != 0u ? 1u : 0u);
		if (!reservePackets(nChunks))
		{
			return false;
		}

		for (size_t start = 0u; start < msg.size();)
		{
			const size_t remaining = msg.size() - start;
			const size_t count = std::min(chunkSize, remaining);
			packets.push_back(msg.substr(start, count));
			start += count;
		}

		if (appendSuffix)
		{
			size_t current = 1u;
			for (auto& item : packets)
			{
				appendPacketSuffix(item, current, packets.size());
				++current;
			}
		}

		return true;
	};

	if (maxMessageLength == 0u)
	{
		return packets;
	}

	if (msg.size() <= maxMessageLength)
	{
		packets.push_back(msg);
		return packets;
	}

	size_t chunkSize = maxMessageLength > SYSLOG_PACKET_SUFFIX_RESERVED_CHARS
		? maxMessageLength - SYSLOG_PACKET_SUFFIX_RESERVED_CHARS
		: 1u;

	const size_t maxIterations = 10u;
	for (size_t iter = 0u; iter < maxIterations; ++iter)
	{
		const size_t nChunks = msg.size() / chunkSize + ((msg.size() % chunkSize) != 0u ? 1u : 0u);
		const size_t suffixLen = 2u * digitCount(nChunks) + 3u;

		if (suffixLen <= SYSLOG_PACKET_SUFFIX_RESERVED_CHARS)
		{
			splitByChunkSize(chunkSize, true);
			return packets;
		}

		if (suffixLen >= maxMessageLength)
		{
			LogLog::warn(LOG4CXX_STR("SyslogAppender: suffix does not fit in MaxMessageLength; omitting packet suffix."));
			splitByChunkSize(maxMessageLength, false);
			return packets;
		}

		size_t newChunkSize = maxMessageLength - suffixLen;
		if (newChunkSize == 0u)
		{
			newChunkSize = 1u;
		}

		if (newChunkSize >= chunkSize)
		{
			splitByChunkSize(chunkSize, true);
			return packets;
		}

		chunkSize = newChunkSize;
	}

	splitByChunkSize(chunkSize, true);
	return packets;
}
}
}
}

IMPLEMENT_LOG4CXX_OBJECT(SyslogAppender)

#define _priv static_cast<SyslogAppenderPriv*>(m_priv.get())

SyslogAppender::SyslogAppender()
	: AppenderSkeleton (std::make_unique<SyslogAppenderPriv>())
{
	this->initSyslogFacilityStr();

}

SyslogAppender::SyslogAppender(const LayoutPtr& layout1,
	int syslogFacility1)
	: AppenderSkeleton (std::make_unique<SyslogAppenderPriv>(layout1, syslogFacility1))
{
	this->initSyslogFacilityStr();
}

SyslogAppender::SyslogAppender(const LayoutPtr& layout1,
	const LogString& syslogHost1, int syslogFacility1)
	: AppenderSkeleton (std::make_unique<SyslogAppenderPriv>(layout1, syslogHost1, syslogFacility1))
{
	this->initSyslogFacilityStr();
	setSyslogHost(syslogHost1);
}

SyslogAppender::~SyslogAppender()
{
	_priv->setClosed();
}

/** Release any resources held by this SyslogAppender.*/
void SyslogAppender::close()
{
	_priv->setClosed();

	if (_priv->sw)
	{
		_priv->sw = nullptr;
	}
}

void SyslogAppender::initSyslogFacilityStr()
{
	_priv->facilityStr = getFacilityString(_priv->syslogFacility);

	if (_priv->facilityStr.empty())
	{
		LogString msg(LOG4CXX_STR("\""));
		StringHelper::toString(_priv->syslogFacility, msg);
		msg.append(LOG4CXX_STR("\" is an unknown syslog facility. Defaulting to \"USER\"."));
		LogLog::warn(msg);
		_priv->syslogFacility = LOG_USER;
		_priv->facilityStr = LOG4CXX_STR("user:");
	}
	else
	{
		_priv->facilityStr += LOG4CXX_STR(":");
	}
}

/**
Returns the specified syslog facility as a lower-case String,
e.g. "kern", "user", etc.
*/
LogString SyslogAppender::getFacilityString(
	int syslogFacility)
{
	switch (syslogFacility)
	{
		case LOG_KERN:
			return LOG4CXX_STR("kern");

		case LOG_USER:
			return LOG4CXX_STR("user");

		case LOG_MAIL:
			return LOG4CXX_STR("mail");

		case LOG_DAEMON:
			return LOG4CXX_STR("daemon");

		case LOG_AUTH:
			return LOG4CXX_STR("auth");

		case LOG_SYSLOG:
			return LOG4CXX_STR("syslog");

		case LOG_LPR:
			return LOG4CXX_STR("lpr");

		case LOG_NEWS:
			return LOG4CXX_STR("news");

		case LOG_UUCP:
			return LOG4CXX_STR("uucp");

		case LOG_CRON:
			return LOG4CXX_STR("cron");
#ifdef LOG_AUTHPRIV

		case LOG_AUTHPRIV:
			return LOG4CXX_STR("authpriv");
#endif
#ifdef LOG_FTP

		case LOG_FTP:
			return LOG4CXX_STR("ftp");
#endif

		case LOG_LOCAL0:
			return LOG4CXX_STR("local0");

		case LOG_LOCAL1:
			return LOG4CXX_STR("local1");

		case LOG_LOCAL2:
			return LOG4CXX_STR("local2");

		case LOG_LOCAL3:
			return LOG4CXX_STR("local3");

		case LOG_LOCAL4:
			return LOG4CXX_STR("local4");

		case LOG_LOCAL5:
			return LOG4CXX_STR("local5");

		case LOG_LOCAL6:
			return LOG4CXX_STR("local6");

		case LOG_LOCAL7:
			return LOG4CXX_STR("local7");

		default:
			return LogString();
	}
}

int SyslogAppender::getFacility(
	const LogString& s)
{
	if (StringHelper::equalsIgnoreCase(s, LOG4CXX_STR("KERN"), LOG4CXX_STR("kern")))
	{
		return LOG_KERN;
	}
	else if (StringHelper::equalsIgnoreCase(s, LOG4CXX_STR("USER"), LOG4CXX_STR("user")))
	{
		return LOG_USER;
	}
	else if (StringHelper::equalsIgnoreCase(s, LOG4CXX_STR("MAIL"), LOG4CXX_STR("mail")))
	{
		return LOG_MAIL;
	}
	else if (StringHelper::equalsIgnoreCase(s, LOG4CXX_STR("DAEMON"), LOG4CXX_STR("daemon")))
	{
		return LOG_DAEMON;
	}
	else if (StringHelper::equalsIgnoreCase(s, LOG4CXX_STR("AUTH"), LOG4CXX_STR("auth")))
	{
		return LOG_AUTH;
	}
	else if (StringHelper::equalsIgnoreCase(s, LOG4CXX_STR("SYSLOG"), LOG4CXX_STR("syslog")))
	{
		return LOG_SYSLOG;
	}
	else if (StringHelper::equalsIgnoreCase(s, LOG4CXX_STR("LPR"), LOG4CXX_STR("lpr")))
	{
		return LOG_LPR;
	}
	else if (StringHelper::equalsIgnoreCase(s, LOG4CXX_STR("NEWS"), LOG4CXX_STR("news")))
	{
		return LOG_NEWS;
	}
	else if (StringHelper::equalsIgnoreCase(s, LOG4CXX_STR("UUCP"), LOG4CXX_STR("uucp")))
	{
		return LOG_UUCP;
	}
	else if (StringHelper::equalsIgnoreCase(s, LOG4CXX_STR("CRON"), LOG4CXX_STR("cron")))
	{
		return LOG_CRON;
	}

#ifdef LOG_AUTHPRIV
	else if (StringHelper::equalsIgnoreCase(s, LOG4CXX_STR("AUTHPRIV"), LOG4CXX_STR("authpriv")))
	{
		return LOG_AUTHPRIV;
	}

#endif
#ifdef LOG_FTP
	else if (StringHelper::equalsIgnoreCase(s, LOG4CXX_STR("FTP"), LOG4CXX_STR("ftp")))
	{
		return LOG_FTP;
	}

#endif
	else if (StringHelper::equalsIgnoreCase(s, LOG4CXX_STR("LOCAL0"), LOG4CXX_STR("local0")))
	{
		return LOG_LOCAL0;
	}
	else if (StringHelper::equalsIgnoreCase(s, LOG4CXX_STR("LOCAL1"), LOG4CXX_STR("local1")))
	{
		return LOG_LOCAL1;
	}
	else if (StringHelper::equalsIgnoreCase(s, LOG4CXX_STR("LOCAL2"), LOG4CXX_STR("local2")))
	{
		return LOG_LOCAL2;
	}
	else if (StringHelper::equalsIgnoreCase(s, LOG4CXX_STR("LOCAL3"), LOG4CXX_STR("local3")))
	{
		return LOG_LOCAL3;
	}
	else if (StringHelper::equalsIgnoreCase(s, LOG4CXX_STR("LOCAL4"), LOG4CXX_STR("local4")))
	{
		return LOG_LOCAL4;
	}
	else if (StringHelper::equalsIgnoreCase(s, LOG4CXX_STR("LOCAL5"), LOG4CXX_STR("local5")))
	{
		return LOG_LOCAL5;
	}
	else if (StringHelper::equalsIgnoreCase(s, LOG4CXX_STR("LOCAL6"), LOG4CXX_STR("local6")))
	{
		return LOG_LOCAL6;
	}
	else if (StringHelper::equalsIgnoreCase(s, LOG4CXX_STR("LOCAL7"), LOG4CXX_STR("local7")))
	{
		return LOG_LOCAL7;
	}
	else
	{
		return LOG_UNDEF;
	}
}

void SyslogAppender::append( const spi::LoggingEventPtr& event )
{
	LogString msg;
	_priv->layout->format(msg, event);
	auto packets = detail::splitSyslogPackets(msg, static_cast<size_t>(_priv->maxMessageLength));
	if (packets.empty() && !msg.empty())
	{
		return;
	}

	// On the local host, we can directly use the system function 'syslog'
	// if it is available
#if LOG4CXX_HAVE_SYSLOG

	if (_priv->sw == 0)
	{
		for (auto const& item : packets)
		{
			// use of "%s" to avoid a security hole
			LOG4CXX_ENCODE_CHAR(itemStr, item);
			::syslog(_priv->syslogFacility | event->getLevel()->getSyslogEquivalent(),
				"%s", itemStr.c_str());
		}

		return;
	}

#endif

	// We must not attempt to append if sw is null.
	if (_priv->sw == 0)
	{
		_priv->errorHandler->error(LOG4CXX_STR("No syslog host is set for SyslogAppedender named \"") +
			_priv->name + LOG4CXX_STR("\"."));
		return;
	}

	for (auto const& item : packets)
	{
		LogString sbuf(1, 0x3C /* '<' */);
		StringHelper::toString((_priv->syslogFacility | event->getLevel()->getSyslogEquivalent()), sbuf);
		sbuf.append(1, (logchar) 0x3E /* '>' */);

		if (_priv->facilityPrinting)
		{
			sbuf.append(_priv->facilityStr);
		}

		sbuf.append(item);
		_priv->sw->write(sbuf);
	}
}


void SyslogAppender::setOption(const LogString& option, const LogString& value)
{
	if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("SYSLOGHOST"), LOG4CXX_STR("sysloghost")))
	{
		setSyslogHost(value);
	}
	else if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("FACILITY"), LOG4CXX_STR("facility")))
	{
		setFacility(value);
	}
	else if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("MAXMESSAGELENGTH"), LOG4CXX_STR("maxmessagelength")))
	{
		setMaxMessageLength(OptionConverter::toInt(value, 1024));
	}
	else
	{
		AppenderSkeleton::setOption(option, value);
	}
}

void SyslogAppender::setSyslogHost(const LogString& syslogHost1)
{
	if (_priv->sw != 0)
	{
		_priv->sw = nullptr;
	}

	LogString slHost = syslogHost1;
	int slHostPort = -1;

	LogString::size_type colonPos = 0;
	colonPos = slHost.rfind(':');

	if (colonPos != LogString::npos)
	{
		slHostPort = StringHelper::toInt(slHost.substr(colonPos + 1));
		// Erase the :port part of the host name
		slHost.erase( colonPos );
	}

	// On the local host, we can directly use the system function 'syslog'
	// if it is available (cf. append)
#if LOG4CXX_HAVE_SYSLOG

	if (syslogHost1 != LOG4CXX_STR("localhost") && syslogHost1 != LOG4CXX_STR("127.0.0.1")
		&& !syslogHost1.empty())
#endif
	{
		if (slHostPort >= 0)
		{
			_priv->sw = std::make_unique<SyslogWriter>(slHost, slHostPort);
		}
		else
		{
			_priv->sw = std::make_unique<SyslogWriter>(slHost);
		}
	}

	_priv->syslogHost = slHost;
	_priv->syslogHostPort = slHostPort;
}


void SyslogAppender::setFacility(const LogString& facilityName)
{
	if (facilityName.empty())
	{
		return;
	}

	_priv->syslogFacility = getFacility(facilityName);

	if (_priv->syslogFacility == LOG_UNDEF)
	{
		LogLog::warn(LOG4CXX_STR("[") + facilityName +
			LOG4CXX_STR("] is an unknown syslog facility. Defaulting to [USER]."));
		_priv->syslogFacility = LOG_USER;
	}

	this->initSyslogFacilityStr();
}

const LogString& SyslogAppender::getSyslogHost() const
{
	return _priv->syslogHost;
}

LogString SyslogAppender::getFacility() const
{
	return getFacilityString(_priv->syslogFacility);
}

void SyslogAppender::setFacilityPrinting(bool facilityPrinting1)
{
	_priv->facilityPrinting = facilityPrinting1;
}

bool SyslogAppender::getFacilityPrinting() const
{
	return _priv->facilityPrinting;
}

void SyslogAppender::setMaxMessageLength(int maxMessageLength1)
{
	// append() reserves 12 characters per chunk for an "(x/y)" sequence suffix.
	// A value at or below the suffix size produces a zero-length chunk (causing
	// an infinite split loop) or an iterator computed before msg.begin() (UB).
	static const int MIN_MAX_MESSAGE_LENGTH = 13;
	if (maxMessageLength1 < MIN_MAX_MESSAGE_LENGTH)
	{
		LogLog::warn(LOG4CXX_STR("SyslogAppender MaxMessageLength is too small. Using the default value."));
		maxMessageLength1 = 1024;
	}
	_priv->maxMessageLength = maxMessageLength1;
}

int SyslogAppender::getMaxMessageLength() const
{
	return _priv->maxMessageLength;
}
