/*
 * 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/log4cxx.h>
#include <ostream>
#include <iomanip>

#include "vectorappender.h"
#include <log4cxx/logmanager.h>
#include <log4cxx/simplelayout.h>
#include <log4cxx/spi/loggingevent.h>
#include "insertwide.h"
#include "logunit.h"
#include <log4cxx/stream.h>
#include <log4cxx/helpers/loglog.h>

#if LOG4CXX_CFSTRING_API
	#include <CoreFoundation/CFString.h>
#endif

using namespace log4cxx;
using namespace log4cxx::helpers;
using namespace std;

class ExceptionOnInsert
{
	public:
		ExceptionOnInsert()
		{
		}
};

//
//   define an insertion operation that will throw an
//       exception to test that evaluation was short
//       circuited
//
template<class Elem, class Tr>
::std::basic_ostream<Elem, Tr>& operator<<(
	::std::basic_ostream<Elem, Tr>&,
	const ExceptionOnInsert&)
{
	throw std::exception();
}


/**
   Unit tests for the optional stream-like interface for log4cxx
 */
LOGUNIT_CLASS(StreamTestCase)
{
	LOGUNIT_TEST_SUITE(StreamTestCase);
	LOGUNIT_TEST(testSimple);
	LOGUNIT_TEST(testMultiple);
	LOGUNIT_TEST(testShortCircuit);
	LOGUNIT_TEST_EXCEPTION(testInsertException, std::exception);
	LOGUNIT_TEST(testScientific);
	LOGUNIT_TEST(testPrecision);
	LOGUNIT_TEST(testWidth);
#if LOG4CXX_WCHAR_T_API
	LOGUNIT_TEST(testWide);
	LOGUNIT_TEST(testWideAppend);
	LOGUNIT_TEST(testWideWidth);
#endif
	LOGUNIT_TEST(testBaseFlags);
	LOGUNIT_TEST(testBasePrecisionAndWidth);
	LOGUNIT_TEST(testLogStreamSimple);
	LOGUNIT_TEST(testLogStreamMultiple);
	LOGUNIT_TEST(testLogStreamShortCircuit);
	LOGUNIT_TEST_EXCEPTION(testLogStreamInsertException, std::exception);
	LOGUNIT_TEST(testLogStreamScientific);
	LOGUNIT_TEST(testLogStreamPrecision);
	LOGUNIT_TEST(testLogStreamWidth);
	LOGUNIT_TEST(testLogStreamDelegate);
	LOGUNIT_TEST(testLogStreamFormattingPersists);
	LOGUNIT_TEST(testSetWidthInsert);
#if LOG4CXX_WCHAR_T_API
	LOGUNIT_TEST(testWLogStreamSimple);
	LOGUNIT_TEST(testWLogStreamMultiple);
	LOGUNIT_TEST(testWLogStreamShortCircuit);
	LOGUNIT_TEST_EXCEPTION(testWLogStreamInsertException, std::exception);
	LOGUNIT_TEST(testWLogStreamScientific);
	LOGUNIT_TEST(testWLogStreamPrecision);
	LOGUNIT_TEST(testWLogStreamWidth);
	LOGUNIT_TEST(testWLogStreamDelegate);
	LOGUNIT_TEST(testWLogStreamFormattingPersists);
	LOGUNIT_TEST(testWSetWidthInsert);
#endif
#if LOG4CXX_CFSTRING_API
	LOGUNIT_TEST(testCFString);
	LOGUNIT_TEST(testCFStringAppend);
#endif
	LOGUNIT_TEST_SUITE_END();

	VectorAppenderPtr vectorAppender;

#ifdef _DEBUG
	struct Fixture
	{
		Fixture() {
			helpers::LogLog::setInternalDebugging(true);
		}
	} suiteFixture;
#endif

public:
	void setUp()
	{
		LoggerPtr root(Logger::getRootLogger());
		LayoutPtr layout(new SimpleLayout());
		vectorAppender = VectorAppenderPtr(new VectorAppender());
		root->addAppender(vectorAppender);
	}

	void tearDown()
	{
		LogManager::shutdown();
	}

	void testSimple()
	{
		LoggerPtr root(Logger::getRootLogger());
		LOG4CXX_INFO(root, "This is a test");
		LOGUNIT_ASSERT_EQUAL((size_t) 1, vectorAppender->getVector().size());
	}

	void testMultiple()
	{
		LoggerPtr root(Logger::getRootLogger());
		LOG4CXX_INFO(root, "This is a test" << ": Details to follow");
		LOGUNIT_ASSERT_EQUAL((size_t) 1, vectorAppender->getVector().size());
	}

	void testShortCircuit()
	{
		LoggerPtr logger(Logger::getLogger("StreamTestCase.shortCircuit"));
		logger->setLevel(Level::getInfo());
		ExceptionOnInsert someObj;
		LOG4CXX_DEBUG(logger, someObj);
		LOGUNIT_ASSERT_EQUAL((size_t) 0, vectorAppender->getVector().size());
	}

	void testInsertException()
	{
		LoggerPtr logger(Logger::getLogger("StreamTestCase.insertException"));
		ExceptionOnInsert someObj;
		LOG4CXX_INFO(logger, someObj);
	}

	void testScientific()
	{
		LoggerPtr root(Logger::getRootLogger());
		LOG4CXX_INFO(root, std::scientific << 0.000001115);
		auto events = vectorAppender->getVector();
		LOGUNIT_ASSERT_EQUAL((size_t) 1, events.size());
		LogString msg(events.front()->getMessage());
		LOGUNIT_ASSERT(msg.find(LOG4CXX_STR("e-")) != LogString::npos ||
			msg.find(LOG4CXX_STR("E-")) != LogString::npos);
	}

	void testPrecision()
	{
		LoggerPtr root(Logger::getRootLogger());
		LOG4CXX_INFO(root, std::setprecision(4) << 1.000001);
		spi::LoggingEventPtr event(vectorAppender->getVector()[0]);
		LogString msg(event->getMessage());
		LOGUNIT_ASSERT(msg.find(LOG4CXX_STR("1.00000")) == LogString::npos);
	}


	void testWidth()
	{
		LoggerPtr root(Logger::getRootLogger());
		LOG4CXX_INFO(root, '[' << std::fixed << std::setprecision(2) << std::setw(7) << std::right << std::setfill('_') << 10.0 << ']');
		spi::LoggingEventPtr event(vectorAppender->getVector()[0]);
		LogString msg(event->getMessage());
		LOGUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR("[__10.00]")), msg);
	}

	void testBaseFlags()
	{
		logstream base1(Logger::getRootLogger(), Level::getInfo());
		logstream base2(Logger::getRootLogger(), Level::getInfo());
		base1 << std::boolalpha;
		base2 << std::noboolalpha;
		std::ostringstream os1a, os1b, os2a, os2b;
		os1a << std::boolalpha;
		int fillchar;

		if (base1.set_stream_state(os1b, fillchar))
		{
			os1b.fill(fillchar);
		}

		LOGUNIT_ASSERT_EQUAL(os1a.flags(), os1b.flags());
		os2a << std::noboolalpha;

		if (base2.set_stream_state(os2b, fillchar))
		{
			os2b.fill(fillchar);
		}

		LOGUNIT_ASSERT_EQUAL(os2a.flags(), os2b.flags());
	}


	void testBasePrecisionAndWidth()
	{
		logstream base(Logger::getRootLogger(), Level::getInfo());
		base.precision(2);
		base.width(5);
		std::ostringstream os1, os2;
		os1.precision(2);
		os1.width(5);
		os1 << 3.1415926;
		int fillchar;

		if (base.set_stream_state(os2, fillchar))
		{
			os2.fill(fillchar);
		}

		os2 << 3.1415926;
		string expected(os1.str());
		string actual(os2.str());
		LOGUNIT_ASSERT_EQUAL(expected, actual);
	}

	void testLogStreamSimple()
	{
		logstream root(Logger::getRootLogger(), Level::getInfo());
		root << std::string("This is a test") << LOG4CXX_ENDMSG;
		LOGUNIT_ASSERT_EQUAL((size_t) 1, vectorAppender->getVector().size());
	}

	void testLogStreamMultiple()
	{
		logstream root(Logger::getRootLogger(), Level::getInfo());
		root << std::string("This is a test") << std::string(": Details to follow") << LOG4CXX_ENDMSG;
		LOGUNIT_ASSERT_EQUAL((size_t) 1, vectorAppender->getVector().size());
	}

	void testLogStreamShortCircuit()
	{
		LoggerPtr logger(Logger::getLogger("StreamTestCase.shortCircuit"));
		logger->setLevel(Level::getInfo());
		logstream os(logger, Level::getDebug());
		ExceptionOnInsert someObj;
		os << someObj << LOG4CXX_ENDMSG;
		LOGUNIT_ASSERT_EQUAL((size_t) 0, vectorAppender->getVector().size());
	}

	void testLogStreamInsertException()
	{
		LoggerPtr logger(Logger::getLogger("StreamTestCase.insertException"));
		ExceptionOnInsert someObj;
		logstream os(logger, Level::getInfo());
		os << someObj << LOG4CXX_ENDMSG;
	}

	void testLogStreamScientific()
	{
		LoggerPtr root(Logger::getRootLogger());
		logstream os(root, Level::getInfo());
		os << std::scientific << 0.000001115 << LOG4CXX_ENDMSG;
		spi::LoggingEventPtr event(vectorAppender->getVector()[0]);
		LogString msg(event->getMessage());
		LOGUNIT_ASSERT(msg.find(LOG4CXX_STR("e-")) != LogString::npos ||
			msg.find(LOG4CXX_STR("E-")) != LogString::npos);
	}

	void testLogStreamPrecision()
	{
		LoggerPtr root(Logger::getRootLogger());
		logstream os(root, Level::getInfo());
		os << std::setprecision(4) << 1.000001 << LOG4CXX_ENDMSG;
		spi::LoggingEventPtr event(vectorAppender->getVector()[0]);
		LogString msg(event->getMessage());
		LOGUNIT_ASSERT(msg.find(LOG4CXX_STR("1.00000")) == LogString::npos);
	}


	void testLogStreamWidth()
	{
		LoggerPtr root(Logger::getRootLogger());
		logstream os(root, Level::getInfo());
		os << '[' << std::fixed << std::setprecision(2) << std::setw(7) << std::right << std::setfill('_') << 10.0 << ']' << LOG4CXX_ENDMSG;
		spi::LoggingEventPtr event(vectorAppender->getVector()[0]);
		LogString msg(event->getMessage());
		LOGUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR("[__10.00]")), msg);
	}

	void report(std::ostream & os)
	{
		os << "This just in: \n";
		os << "Use logstream in places that expect a std::ostream.\n";
	}

	void testLogStreamDelegate()
	{
		logstream root(Logger::getRootLogger(), Level::getInfo());
		report(root);
		root << LOG4CXX_ENDMSG;
		LOGUNIT_ASSERT_EQUAL((size_t) 1, vectorAppender->getVector().size());
	}

	void testLogStreamFormattingPersists()
	{
		LoggerPtr root(Logger::getRootLogger());
		root->setLevel(Level::getInfo());
		logstream os(root, Level::getDebug());
		os << std::hex << 20 << LOG4CXX_ENDMSG;
		os << Level::getInfo() << 16 << LOG4CXX_ENDMSG;
		spi::LoggingEventPtr event(vectorAppender->getVector()[0]);
		LogString msg(event->getMessage());
		LOGUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR("10")), msg);
	}

	void testSetWidthInsert()
	{
		LoggerPtr root(Logger::getRootLogger());
		root->setLevel(Level::getInfo());
		logstream os(root, Level::getInfo());
		os << std::setw(5);
		LOGUNIT_ASSERT_EQUAL(5, os.width());
	}



#if LOG4CXX_WCHAR_T_API
	void testWide()
	{
		LoggerPtr root(Logger::getRootLogger());
		LOG4CXX_INFO(root, L"This is a test");
		LOGUNIT_ASSERT_EQUAL((size_t) 1, vectorAppender->getVector().size());
	}

	void testWideAppend()
	{
		LoggerPtr root(Logger::getRootLogger());
		LOG4CXX_INFO(root, L"This is a test" << L": Details to follow");
		LOGUNIT_ASSERT_EQUAL((size_t) 1, vectorAppender->getVector().size());
	}

	void testWideWidth()
	{
		LoggerPtr root(Logger::getRootLogger());
		LOG4CXX_INFO(root, L'[' << std::fixed << std::setprecision(2) << std::setw(7) << std::right << std::setfill(L'_') << 10.0 << L"]");
		spi::LoggingEventPtr event(vectorAppender->getVector()[0]);
		LogString msg(event->getMessage());
		LOGUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR("[__10.00]")), msg);
	}

	void testWLogStreamSimple()
	{
		wlogstream root(Logger::getRootLogger(), Level::getInfo());
		root << L"This is a test" << LOG4CXX_ENDMSG;
		LOGUNIT_ASSERT_EQUAL((size_t) 1, vectorAppender->getVector().size());
	}

	void testWLogStreamMultiple()
	{
		wlogstream root(Logger::getRootLogger(), Level::getInfo());
		root << L"This is a test" << L": Details to follow" << LOG4CXX_ENDMSG;
		LOGUNIT_ASSERT_EQUAL((size_t) 1, vectorAppender->getVector().size());
	}

	void testWLogStreamShortCircuit()
	{
		LoggerPtr logger(Logger::getLogger("StreamTestCase.shortCircuit"));
		logger->setLevel(Level::getInfo());
		wlogstream os(logger, Level::getDebug());
		ExceptionOnInsert someObj;
		os << someObj << LOG4CXX_ENDMSG;
		LOGUNIT_ASSERT_EQUAL((size_t) 0, vectorAppender->getVector().size());
	}

	void testWLogStreamInsertException()
	{
		LoggerPtr logger(Logger::getLogger("StreamTestCase.insertException"));
		ExceptionOnInsert someObj;
		wlogstream os(logger, Level::getInfo());
		os << someObj << LOG4CXX_ENDMSG;
	}

	void testWLogStreamScientific()
	{
		LoggerPtr root(Logger::getRootLogger());
		wlogstream os(root, Level::getInfo());
		os << std::scientific << 0.000001115 << LOG4CXX_ENDMSG;
		spi::LoggingEventPtr event(vectorAppender->getVector()[0]);
		LogString msg(event->getMessage());
		LOGUNIT_ASSERT(msg.find(LOG4CXX_STR("e-")) != LogString::npos ||
			msg.find(LOG4CXX_STR("E-")) != LogString::npos);
	}

	void testWLogStreamPrecision()
	{
		LoggerPtr root(Logger::getRootLogger());
		wlogstream os(root, Level::getInfo());
		os << std::setprecision(4) << 1.000001 << LOG4CXX_ENDMSG;
		spi::LoggingEventPtr event(vectorAppender->getVector()[0]);
		LogString msg(event->getMessage());
		LOGUNIT_ASSERT(msg.find(LOG4CXX_STR("1.00000")) == LogString::npos);
	}


	void testWLogStreamWidth()
	{
		LoggerPtr root(Logger::getRootLogger());
		wlogstream os(root, Level::getInfo());
		os << L"[" << std::fixed << std::setprecision(2) << std::setw(7) << std::right << std::setfill(L'_') << 10.0 << L"]" << LOG4CXX_ENDMSG;
		spi::LoggingEventPtr event(vectorAppender->getVector()[0]);
		LogString msg(event->getMessage());
		LOGUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR("[__10.00]")), msg);
	}

	void wreport(std::basic_ostream<wchar_t>& os)
	{
		os << L"This just in: \n";
		os << L"Use logstream in places that expect a std::ostream.\n";
	}

	void testWLogStreamDelegate()
	{
		wlogstream root(Logger::getRootLogger(), Level::getInfo());
		wreport(root);
		root << LOG4CXX_ENDMSG;
		LOGUNIT_ASSERT_EQUAL((size_t) 1, vectorAppender->getVector().size());
	}

	void testWLogStreamFormattingPersists()
	{
		LoggerPtr root(Logger::getRootLogger());
		root->setLevel(Level::getInfo());
		wlogstream os(root, Level::getDebug());
		os << std::hex << 20 << LOG4CXX_ENDMSG;
		os << Level::getInfo() << 16 << LOG4CXX_ENDMSG;
		spi::LoggingEventPtr event(vectorAppender->getVector()[0]);
		LogString msg(event->getMessage());
		LOGUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR("10")), msg);
	}

	void testWSetWidthInsert()
	{
		LoggerPtr root(Logger::getRootLogger());
		root->setLevel(Level::getInfo());
		wlogstream os(root, Level::getInfo());
		os << std::setw(5);
		LOGUNIT_ASSERT_EQUAL(5, os.width());
	}

#endif

#if LOG4CXX_CFSTRING_API
	void testCFString()
	{
		LoggerPtr root(Logger::getRootLogger());
		LOG4CXX_INFO(root, CFSTR("This is a test"));
		LOGUNIT_ASSERT_EQUAL((size_t) 1, vectorAppender->getVector().size());
	}

	void testCFStringAppend()
	{
		LoggerPtr root(Logger::getRootLogger());
		LOG4CXX_INFO(root, CFSTR("This is a test") << CFSTR(": Details to follow"));
		LOGUNIT_ASSERT_EQUAL((size_t) 1, vectorAppender->getVector().size());
	}
#endif

};

LOGUNIT_TEST_SUITE_REGISTRATION(StreamTestCase);


#if !LOG4CXX_USE_GLOBAL_SCOPE_TEMPLATE
//
//   The following code tests compilation errors
//      around bug LOGCXX-150 and is not intended to be executed.
//      Skipped for VC6 since it can't handle having the
//      templated operator<< in class scope.s
namespace foo
{
class Bar
{
		void fn();
};

std::ostream& operator<<(std::ostream& o, Bar const& b)
{
	return o << "Bar";
}
}


using namespace foo;

namespace
{
log4cxx::LoggerPtr logger(log4cxx::Logger::getLogger("foo"));
log4cxx::logstream lout(logger, log4cxx::Level::getDebug());
}

void Bar::fn()
{
	lout << "hi" << LOG4CXX_ENDMSG;
}
#endif

