/*
 * 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/xmlsocketappender.h>
#include <log4cxx/helpers/loglog.h>
#include <log4cxx/helpers/outputstreamwriter.h>
#include <log4cxx/helpers/charsetencoder.h>
#include <log4cxx/helpers/optionconverter.h>
#include <log4cxx/helpers/stringhelper.h>
#include <log4cxx/xml/xmllayout.h>
#include <log4cxx/level.h>
#include <log4cxx/helpers/transform.h>
#include <log4cxx/helpers/transcoder.h>
#include <log4cxx/helpers/socketoutputstream.h>

using namespace log4cxx;
using namespace log4cxx::helpers;
using namespace log4cxx::net;
using namespace log4cxx::xml;

IMPLEMENT_LOG4CXX_OBJECT(XMLSocketAppender)

// The default port number of remote logging server (4560)
int XMLSocketAppender::DEFAULT_PORT                 = 4560;

// The default reconnection delay (30000 milliseconds or 30 seconds).
int XMLSocketAppender::DEFAULT_RECONNECTION_DELAY   = 30000;

const int XMLSocketAppender::MAX_EVENT_LEN          = 1024;

XMLSocketAppender::XMLSocketAppender()
	: SocketAppenderSkeleton(DEFAULT_PORT, DEFAULT_RECONNECTION_DELAY)
{
    layout = XMLLayoutPtr(new XMLLayout());
}

XMLSocketAppender::XMLSocketAppender(InetAddressPtr address1, int port1)
	: SocketAppenderSkeleton(address1, port1, DEFAULT_RECONNECTION_DELAY)
{
    layout = XMLLayoutPtr(new XMLLayout());
	Pool p;
	activateOptions(p);
}

XMLSocketAppender::XMLSocketAppender(const LogString& host, int port1)
	: SocketAppenderSkeleton(host, port1, DEFAULT_RECONNECTION_DELAY)
{
    layout = XMLLayoutPtr(new XMLLayout());
	Pool p;
	activateOptions(p);
}

XMLSocketAppender::~XMLSocketAppender()
{
	finalize();
}


int XMLSocketAppender::getDefaultDelay() const
{
	return DEFAULT_RECONNECTION_DELAY;
}

int XMLSocketAppender::getDefaultPort() const
{
	return DEFAULT_PORT;
}

void XMLSocketAppender::setSocket(log4cxx::helpers::SocketPtr& socket, Pool& p)
{
	OutputStreamPtr os(new SocketOutputStream(socket));
	CharsetEncoderPtr charset(CharsetEncoder::getUTF8Encoder());
	log4cxx::unique_lock<log4cxx::shared_mutex> lock(mutex);
    writer = OutputStreamWriterPtr(new OutputStreamWriter(os, charset));
}

void XMLSocketAppender::cleanUp(Pool& p)
{
	if (writer != 0)
	{
		try
		{
			writer->close(p);
			writer = 0;
		}
		catch (std::exception&)
		{
		}
	}
}

void XMLSocketAppender::append(const spi::LoggingEventPtr& event, log4cxx::helpers::Pool& p)
{
	if (writer != 0)
	{
		LogString output;
		layout->format(output, event, p);

		try
		{
			writer->write(output, p);
			writer->flush(p);
		}
		catch (std::exception& e)
		{
			writer = 0;
			LogLog::warn(LOG4CXX_STR("Detected problem with connection: "), e);

			if (getReconnectionDelay() > 0)
			{
				fireConnector();
			}
		}
	}
}




