/*
 * 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 "logunit.h"
#include <log4cxx/appenderskeleton.h>
#include <log4cxx/helpers/pool.h>
#include <log4cxx/helpers/loglog.h>
#include <log4cxx/helpers/transcoder.h>

using namespace log4cxx;

/**
 * Tests activateOptions in ABI 15 and 16.
 *
 */

class ABI_15_Appender : public AppenderSkeleton
{
public:
	void close() override
	{}

	void append( LOG4CXX_APPEND_FORMAL_PARAMETERS ) override
	{
		helpers::LogLog::debug(LOG4CXX_STR("ABI_15_Appender::append"));
	}

	bool requiresLayout() const override
	{
		return false;
	}

	void activateOptions(helpers::Pool& p)
	{
		helpers::LogLog::debug(LOG4CXX_STR("ABI_15_Appender::activateOptions"));
		AppenderSkeleton::activateOptions(p);
		m_activated = true;
	}

	bool isActivated() const
	{
		return m_activated;
	}
private:
	bool m_activated{ false };
};


class BaseAppender : public AppenderSkeleton
{
public:
	void close() override
	{}

	void append( LOG4CXX_APPEND_FORMAL_PARAMETERS ) override
	{
		helpers::LogLog::debug(LOG4CXX_STR("BaseAppender::append"));
	}

	bool requiresLayout() const override
	{
		return false;
	}

	using AppenderSkeleton::activateOptions;
	void activateOptions( LOG4CXX_ACTIVATE_OPTIONS_FORMAL_PARAMETERS ) override
	{
		helpers::LogLog::debug(LOG4CXX_STR("BaseAppender::activateOptions"));
		AppenderSkeleton::activateOptions( LOG4CXX_ACTIVATE_OPTIONS_PARAMETER );
		m_activated = true;
	}

	bool isActivated() const
	{
		return m_activated;
	}
private:
	bool m_activated{ false };
};

class ABI_15_Specialized_Appender : public BaseAppender
{
public:
	using spi::OptionHandler::activateOptions;
	// void activateOptions(helpers::Pool& p) override --> compiler error: 'ABI_15_Specialized_Appender::activateOptions': method with override specifier 'override' did not override any base class methods
	//                                                                     'log4cxx::spi::OptionHandler::activateOptions': Use activateOptions() without parameters instead
	void activateOptions(helpers::Pool& p)
	{
		helpers::LogLog::debug(LOG4CXX_STR("ABI_15_Specialized_Appender::activateOptions"));
		BaseAppender::activateOptions(p); // --> compiler warning: 'log4cxx::spi::OptionHandler::activateOptions': Use activateOptions() without parameters instead
		m_activated = true;
	}

	bool isActivated() const
	{
		return BaseAppender::isActivated() && m_activated;
	}
private:
	bool m_activated{ false };
};

#if 15 < LOG4CXX_ABI_VERSION
class ABI_16_Appender : public BaseAppender
{
public:
	void activateOptions() override
	{
		helpers::LogLog::debug(LOG4CXX_STR("ABI_16_Appender::activateOptions"));
		BaseAppender::activateOptions();
		m_activated = true;
	}

	bool isActivated() const
	{
		return BaseAppender::isActivated() && m_activated;
	}
private:
	bool m_activated{ false };
};

#endif

LOGUNIT_CLASS(OptionHandlerTest)
{
	LOGUNIT_TEST_SUITE(OptionHandlerTest);
	LOGUNIT_TEST(ABI_15_AppenderTest);
	LOGUNIT_TEST(ABI_15_Specialized_AppenderTest);
#if LOG4CXX_ABI_VERSION <= 15
	LOGUNIT_TEST(ABI_15_Specialized_Appender_unagumented_activate_Test);
#else
	LOGUNIT_TEST(ABI_16_AppenderTest);
#endif
	LOGUNIT_TEST_SUITE_END();
public:

	/**
	 * Checks a simple user defined ABI 15 style appender still works
	 */
	void ABI_15_AppenderTest()
	{
		helpers::Pool p;
		ABI_15_Appender a15;
		a15.activateOptions(p);
		LOGUNIT_ASSERT(a15.isActivated());
	}

	/**
	 * Checks all levels of the appender heirarchy are activated
	 */
	void ABI_15_Specialized_AppenderTest()
	{
		helpers::Pool p;
		ABI_15_Specialized_Appender a15s;
		a15s.activateOptions(p);
		LOGUNIT_ASSERT(a15s.isActivated());
	}

#if LOG4CXX_ABI_VERSION <= 15
	/**
	 * Checks all levels of the appender heirarchy are activated
	 */
	void ABI_15_Specialized_Appender_unagumented_activate_Test()
	{
		helpers::Pool p;
		ABI_15_Specialized_Appender a15s;
		a15s.activateOptions();
		LOGUNIT_ASSERT(a15s.isActivated());
	}

#else
	/**
	 * Checks all levels of the appender heirarchy are activated
	 */
	void ABI_16_AppenderTest()
	{
		ABI_16_Appender a16;
		a16.activateOptions();
		LOGUNIT_ASSERT(a16.isActivated());
	}
#endif

};

LOGUNIT_TEST_SUITE_REGISTRATION(OptionHandlerTest);

