/*
 * 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/appender.h>
#include <log4cxx/logger.h>
#include <log4cxx/varia/fallbackerrorhandler.h>
#include <log4cxx/helpers/loglog.h>
#include <log4cxx/helpers/stringhelper.h>
#include <log4cxx/spi/loggingevent.h>
#include <log4cxx/hierarchy.h>
#include <log4cxx/logmanager.h>

using namespace LOG4CXX_NS;
using namespace LOG4CXX_NS::helpers;
using namespace LOG4CXX_NS::spi;
using namespace LOG4CXX_NS::varia;

IMPLEMENT_LOG4CXX_OBJECT(FallbackErrorHandler)

struct FallbackErrorHandler::FallbackErrorHandlerPrivate
{
	AppenderWeakPtr backup;
	AppenderWeakPtr primary;
	std::vector<LoggerPtr> loggers;
	bool errorReported = false;
};

FallbackErrorHandler::FallbackErrorHandler()
	: m_priv(std::make_unique<FallbackErrorHandlerPrivate>())
{
}

FallbackErrorHandler::~FallbackErrorHandler() {}

void FallbackErrorHandler::setLogger(const LoggerPtr& logger)
{
	if (LogLog::isDebugEnabled())
	{
		LogLog::debug(((LogString) LOG4CXX_STR("FB: Adding logger ["))
			+ logger->getName() + LOG4CXX_STR("]."));
	}
	m_priv->loggers.push_back(logger);
}

void FallbackErrorHandler::error(const LogString& message,
	const std::exception& e,
	int errorCode) const
{
	error(message, e, errorCode, 0);
}

void FallbackErrorHandler::error(const LogString& message,
	const std::exception& e,
	int, const spi::LoggingEventPtr&) const
{
	if (LogLog::isDebugEnabled())
	{
		LogLog::debug(((LogString) LOG4CXX_STR("FB: The following error reported: "))
			+  message, e);
		LogLog::debug(LOG4CXX_STR("FB: INITIATING FALLBACK PROCEDURE."));
	}

	AppenderPtr primaryLocked = m_priv->primary.lock();
	AppenderPtr backupLocked = m_priv->backup.lock();

	if ( !primaryLocked || !backupLocked )
	{
		return;
	}

	for (LoggerPtr l : m_priv->loggers)
	{
		if (LogLog::isDebugEnabled())
		{
			LogLog::debug(LOG4CXX_STR("FB: Replacing [")
				+ primaryLocked->getName() + LOG4CXX_STR("] with [")
				+ backupLocked->getName() + LOG4CXX_STR("] in logger [")
				+ l->getName() + LOG4CXX_STR("]."));
		}
		if (!l->replaceAppender(primaryLocked, backupLocked))
		{
			LogLog::debug(LOG4CXX_STR("FB: Failed to replace [")
				+ primaryLocked->getName() + LOG4CXX_STR("] with [")
				+ backupLocked->getName() + LOG4CXX_STR("] in logger [")
				+ l->getName() + LOG4CXX_STR("]."));
		}
	}
	m_priv->errorReported = true;
}

void FallbackErrorHandler::setAppender(const AppenderPtr& primary1)
{
	if (LogLog::isDebugEnabled())
	{
		LogLog::debug(((LogString) LOG4CXX_STR("FB: Setting primary appender to ["))
			+ primary1->getName() + LOG4CXX_STR("]."));
	}
	m_priv->primary = primary1;
}

void FallbackErrorHandler::setBackupAppender(const AppenderPtr& backup1)
{
	if (LogLog::isDebugEnabled())
	{
		LogLog::debug(((LogString) LOG4CXX_STR("FB: Setting backup appender to ["))
			+ backup1->getName() + LOG4CXX_STR("]."));
	}
	m_priv->backup = backup1;

	// Make sure that we keep a reference to the appender around, since otherwise
	// the appender would be lost if it has no loggers that use it.
	auto repository = LogManager::getLoggerRepository();
	if (auto hierarchy = dynamic_cast<Hierarchy*>(repository.get()))
	{
		hierarchy->addAppender(backup1);
	}

}

void FallbackErrorHandler::activateOptions()
{
}

void FallbackErrorHandler::setOption(const LogString&, const LogString&)
{
}

bool FallbackErrorHandler::errorReported() const
{
	return m_priv->errorReported;
}
