/*
 * 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/stream.h>
#include <log4cxx/helpers/transcoder.h>
#if !defined(LOG4CXX)
	#define LOG4CXX 1
#endif
#include <log4cxx/private/log4cxx_private.h>

using namespace log4cxx;

logstream_base::logstream_ios_base::logstream_ios_base(std::ios_base::fmtflags initval,
	int initsize)
{
#if LOG4CXX_MEMSET_IOS_BASE
	//
	//    the destructor for std::ios_base in the MSVC STL
	//        releases a pointer that was not initialized in the constructor.
	//
	memset(this, 0, sizeof(*this));
#endif
	flags(initval);
	precision(initsize);
	width(initsize);

}


logstream_base::logstream_base(const LoggerPtr& log,
	const LevelPtr& lvl) : initset((std::ios_base::fmtflags) - 1, 1),
	initclear((std::ios_base::fmtflags) 0, 0), fillchar(0), fillset(false), logger(log), level(lvl), location()
{
	enabled = logger->isEnabledFor(level);
}

logstream_base::~logstream_base()
{
}

void logstream_base::insert(std::ios_base & (*manip)(std::ios_base&))
{
	get_stream_state(initclear, initset, fillchar, fillset);
	(*manip)(initset);
	(*manip)(initclear);
	refresh_stream_state();
}

bool logstream_base::set_stream_state(std::ios_base& dest, int& dstchar)
{
	std::ios_base::fmtflags setval = initset.flags();
	std::ios_base::fmtflags clrval = initclear.flags();
	std::ios_base::fmtflags mask = setval ^ (~clrval);
	dest.setf(clrval, mask);

	if (initset.precision() == initclear.precision())
	{
		dest.precision(initset.precision());
	}

	if (initset.width() == initclear.width())
	{
		dest.width(initset.width());
	}

	dstchar = fillchar;
	return fillset;
}

logstream_base& logstream_base::endmsg(logstream_base& stream)
{
	stream.end_message();
	return stream;
}

logstream_base& logstream_base::nop(logstream_base& stream)
{
	return stream;
}

void logstream_base::end_message()
{
	if (isEnabled())
	{
		log(logger, level, location);
	}

	erase();
}



int log4cxx::logstream_base::precision(int p)
{
	get_stream_state(initclear, initset, fillchar, fillset);
	initset.precision(p);
	int oldVal = initclear.precision(p);
	refresh_stream_state();
	return oldVal;
}

int log4cxx::logstream_base::precision()
{
	get_stream_state(initclear, initset, fillchar, fillset);
	return initclear.precision();
}

int log4cxx::logstream_base::width(int w)
{
	get_stream_state(initclear, initset, fillchar, fillset);
	initset.width(w);
	int oldVal = initclear.width(w);
	refresh_stream_state();
	return oldVal;
}

int log4cxx::logstream_base::width()
{
	get_stream_state(initclear, initset, fillchar, fillset);
	return initclear.width();
}

int log4cxx::logstream_base::fill(int newfill)
{
	get_stream_state(initclear, initset, fillchar, fillset);
	int oldfill = fillchar;
	fillchar = newfill;
	fillset = true;
	refresh_stream_state();
	return oldfill;
}

int logstream_base::fill()
{
	get_stream_state(initclear, initset, fillchar, fillset);
	return fillchar;
}

std::ios_base::fmtflags logstream_base::flags(std::ios_base::fmtflags newflags)
{
	get_stream_state(initclear, initset, fillchar, fillset);
	initset.flags(newflags);
	std::ios_base::fmtflags oldVal = initclear.flags(newflags);
	refresh_stream_state();
	return oldVal;
}

std::ios_base::fmtflags logstream_base::setf(std::ios_base::fmtflags newflags, std::ios_base::fmtflags mask)
{
	get_stream_state(initclear, initset, fillchar, fillset);
	initset.setf(newflags, mask);
	std::ios_base::fmtflags oldVal = initclear.setf(newflags, mask);
	refresh_stream_state();
	return oldVal;
}

std::ios_base::fmtflags logstream_base::setf(std::ios_base::fmtflags newflags)
{
	get_stream_state(initclear, initset, fillchar, fillset);
	initset.setf(newflags);
	std::ios_base::fmtflags oldVal = initclear.setf(newflags);
	refresh_stream_state();
	return oldVal;
}



void logstream_base::setLevel(const ::log4cxx::LevelPtr& newlevel)
{
	level = newlevel;
	bool oldLevel = enabled;
	enabled = logger->isEnabledFor(level);

	if (oldLevel != enabled)
	{
		erase();
	}
}

bool logstream_base::isEnabledFor(const ::log4cxx::LevelPtr& l) const
{
	return logger->isEnabledFor(l);
}


void logstream_base::setLocation(const log4cxx::spi::LocationInfo& newlocation)
{
	if (LOG4CXX_UNLIKELY(enabled))
	{
		location = newlocation;
	}
}


logstream::logstream(const log4cxx::LoggerPtr& logger,
	const log4cxx::LevelPtr& level) : logstream_base(logger, level), stream(0)
{
}

logstream::logstream(const Ch* loggerName,
	const log4cxx::LevelPtr& level)
	: logstream_base(log4cxx::Logger::getLogger(loggerName), level), stream(0)
{
}


logstream::logstream(const std::basic_string<Ch>& loggerName,
	const log4cxx::LevelPtr& level) : logstream_base(log4cxx::Logger::getLogger(loggerName), level), stream(0)
{
}

logstream::~logstream()
{
	delete stream;
}

logstream& logstream::operator<<(logstream_base & (*manip)(logstream_base&))
{
	(*manip)(*this);
	return *this;
}

logstream& logstream::operator<<(const LevelPtr& l)
{
	setLevel(l);
	return *this;
}

logstream& logstream::operator<<(const log4cxx::spi::LocationInfo& newlocation)
{
	setLocation(newlocation);
	return *this;
}

logstream& logstream::operator>>(const log4cxx::spi::LocationInfo& newlocation)
{
	setLocation(newlocation);
	return *this;
}

logstream& logstream::operator<<(std::ios_base & (*manip)(std::ios_base&))
{
	logstream_base::insert(manip);
	return *this;
}

logstream::operator std::basic_ostream<char>& ()
{
	if (stream == 0)
	{
		stream = new std::basic_stringstream<Ch>();
		refresh_stream_state();
	}

	return *stream;
}

void logstream::log(LoggerPtr& log,
	const LevelPtr& lev,
	const log4cxx::spi::LocationInfo& loc)
{
	if (stream != 0)
	{
		std::basic_string<Ch> msg = stream->str();

		if (!msg.empty())
		{
			log->log(lev, msg, loc);
		}
	}
}


void logstream::erase()
{
	if (stream != 0)
	{
		std::basic_string<Ch> emptyStr;
		stream->str(emptyStr);
	}
}


void logstream::get_stream_state(std::ios_base& base,
	std::ios_base& mask,
	int& fill,
	bool& fillSet) const
{
	if (stream != 0)
	{
		std::ios_base::fmtflags flags = stream->flags();
		base.flags(flags);
		mask.flags(flags);
		int width = stream->width();
		base.width(width);
		mask.width(width);
		int precision = stream->precision();
		base.precision(precision);
		mask.precision(precision);
		fill = stream->fill();
		fillSet = true;
	}
}

void logstream::refresh_stream_state()
{
	if (stream != 0)
	{
		int ch;

		if (logstream_base::set_stream_state(*stream, ch))
		{
			stream->fill(ch);
		}
	}
}


#if LOG4CXX_WCHAR_T_API

wlogstream::wlogstream(const log4cxx::LoggerPtr& logger,
	const log4cxx::LevelPtr& level) : logstream_base(logger, level), stream(0)
{
}

wlogstream::wlogstream(const Ch* loggerName,
	const log4cxx::LevelPtr& level)
	: logstream_base(log4cxx::Logger::getLogger(loggerName), level), stream(0)
{
}


wlogstream::wlogstream(const std::basic_string<Ch>& loggerName,
	const log4cxx::LevelPtr& level) : logstream_base(log4cxx::Logger::getLogger(loggerName), level), stream(0)
{
}

wlogstream::~wlogstream()
{
	delete stream;
}

wlogstream& wlogstream::operator<<(logstream_base & (*manip)(logstream_base&))
{
	(*manip)(*this);
	return *this;
}

wlogstream& wlogstream::operator<<(const LevelPtr& l)
{
	setLevel(l);
	return *this;
}

wlogstream& wlogstream::operator<<(const log4cxx::spi::LocationInfo& newlocation)
{
	setLocation(newlocation);
	return *this;
}

wlogstream& wlogstream::operator>>(const log4cxx::spi::LocationInfo& newlocation)
{
	setLocation(newlocation);
	return *this;
}




wlogstream& wlogstream::operator<<(std::ios_base & (*manip)(std::ios_base&))
{
	logstream_base::insert(manip);
	return *this;
}

wlogstream::operator std::basic_ostream<wchar_t>& ()
{
	if (stream == 0)
	{
		stream = new std::basic_stringstream<Ch>();
		refresh_stream_state();
	}

	return *stream;
}

void wlogstream::log(LoggerPtr& log,
	const LevelPtr& lev,
	const log4cxx::spi::LocationInfo& loc)
{
	if (stream != 0)
	{
		std::basic_string<Ch> msg = stream->str();

		if (!msg.empty())
		{
			log->log(lev, msg, loc);
		}
	}
}


void wlogstream::erase()
{
	if (stream != 0)
	{
		std::basic_string<Ch> emptyStr;
		stream->str(emptyStr);
	}
}


void wlogstream::get_stream_state(std::ios_base& base,
	std::ios_base& mask,
	int& fill,
	bool& fillSet) const
{
	if (stream != 0)
	{
		std::ios_base::fmtflags flags = stream->flags();
		base.flags(flags);
		mask.flags(flags);
		int width = stream->width();
		base.width(width);
		mask.width(width);
		int precision = stream->precision();
		base.precision(precision);
		mask.precision(precision);
		fill = stream->fill();
		fillSet = true;
	}
}

void wlogstream::refresh_stream_state()
{
	if (stream != 0)
	{
		int ch;

		if (logstream_base::set_stream_state(*stream, ch))
		{
			stream->fill(ch);
		}
	}
}
#endif

#if LOG4CXX_UNICHAR_API
ulogstream::ulogstream(const Ch* loggerName,
	const log4cxx::LevelPtr& level)
	: logstream_base(log4cxx::Logger::getLogger(loggerName), level), stream(0)
{
}


ulogstream::ulogstream(const std::basic_string<Ch>& loggerName,
	const log4cxx::LevelPtr& level) : logstream_base(log4cxx::Logger::getLogger(loggerName), level), stream(0)
{
}
#endif

#if LOG4CXX_CFSTRING_API
ulogstream::ulogstream(const CFStringRef& loggerName,
	const log4cxx::LevelPtr& level)
	: logstream_base(log4cxx::Logger::getLogger(loggerName), level), stream(0)
{
}

#endif


#if LOG4CXX_UNICHAR_API || LOG4CXX_CFSTRING_API

ulogstream::ulogstream(const log4cxx::LoggerPtr& logger,
	const log4cxx::LevelPtr& level) : logstream_base(logger, level), stream(0)
{
}



ulogstream::~ulogstream()
{
	delete stream;
}

ulogstream& ulogstream::operator<<(logstream_base & (*manip)(logstream_base&))
{
	(*manip)(*this);
	return *this;
}

ulogstream& ulogstream::operator<<(const LevelPtr& level)
{
	setLevel(level);
	return *this;
}

ulogstream& ulogstream::operator<<(const log4cxx::spi::LocationInfo& newlocation)
{
	setLocation(newlocation);
	return *this;
}

ulogstream& ulogstream::operator>>(const log4cxx::spi::LocationInfo& newlocation)
{
	setLocation(newlocation);
	return *this;
}




ulogstream& ulogstream::operator<<(std::ios_base & (*manip)(std::ios_base&))
{
	logstream_base::insert(manip);
	return *this;
}

ulogstream::operator std::basic_ostream<UniChar>& ()
{
	if (stream == 0)
	{
		stream = new std::basic_stringstream<Ch>();
		refresh_stream_state();
	}

	return *stream;
}

void ulogstream::log(LoggerPtr& logger,
	const LevelPtr& level,
	const log4cxx::spi::LocationInfo& location)
{
	if (stream != 0)
	{
		std::basic_string<Ch> msg = stream->str();

		if (!msg.empty() && logger->isEnabledFor(level))
		{
			LOG4CXX_DECODE_UNICHAR(lsmsg, msg);
			logger->forcedLogLS(level, lsmsg, location);
		}
	}
}


void ulogstream::erase()
{
	if (stream != 0)
	{
		std::basic_string<Ch> emptyStr;
		stream->str(emptyStr);
	}
}


void ulogstream::get_stream_state(std::ios_base& base,
	std::ios_base& mask,
	int& fill,
	bool& fillSet) const
{
	if (stream != 0)
	{
		std::ios_base::fmtflags flags = stream->flags();
		base.flags(flags);
		mask.flags(flags);
		int width = stream->width();
		base.width(width);
		mask.width(width);
		int precision = stream->precision();
		base.precision(precision);
		mask.precision(precision);
		fill = stream->fill();
		fillSet = true;
	}
}

void ulogstream::refresh_stream_state()
{
	if (stream != 0)
	{
		int fillchar;

		if (logstream_base::set_stream_state(*stream, fillchar))
		{
			stream->fill(fillchar);
		}
	}
}
#endif


