/*
 * 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.
 */


#if defined(_MSC_VER)
	#pragma warning ( disable: 4231 4251 4275 4786 )
#endif

#include <log4cxx/logmanager.h>
#include <log4cxx/spi/defaultrepositoryselector.h>
#include <log4cxx/hierarchy.h>
#include <log4cxx/spi/rootlogger.h>
#include <log4cxx/spi/loggerfactory.h>
#include <stdexcept>
#include <log4cxx/level.h>
#include <log4cxx/spi/loggerrepository.h>
#include <log4cxx/helpers/exception.h>
#include <log4cxx/helpers/optionconverter.h>
#include <log4cxx/helpers/loglog.h>

#include <apr_general.h>

#include <log4cxx/spi/loggingevent.h>
#include <log4cxx/file.h>
#include <log4cxx/helpers/transcoder.h>
#if !defined(LOG4CXX)
	#define LOG4CXX 1
#endif
#include <log4cxx/helpers/aprinitializer.h>

using namespace log4cxx;
using namespace log4cxx::spi;
using namespace log4cxx::helpers;

IMPLEMENT_LOG4CXX_OBJECT(DefaultRepositorySelector)

void* LogManager::guard = 0;



RepositorySelectorPtr& LogManager::getRepositorySelector()
{
	//
	//     call to initialize APR and trigger "start" of logging clock
	//
	APRInitializer::initialize();
	static spi::RepositorySelectorPtr selector;
	return selector;
}

void LogManager::setRepositorySelector(spi::RepositorySelectorPtr selector,
	void* guard1)
{
	if ((LogManager::guard != 0) && (LogManager::guard != guard1))
	{
		throw IllegalArgumentException(LOG4CXX_STR("Attempted to reset the LoggerFactory without possessing the guard."));
	}

	if (selector == 0)
	{
		throw IllegalArgumentException(LOG4CXX_STR("RepositorySelector must be non-null."));
	}

	LogManager::guard = guard1;
	LogManager::getRepositorySelector() = selector;
}



LoggerRepositoryPtr& LogManager::getLoggerRepository()
{
	if (getRepositorySelector() == 0)
	{
		LoggerRepositoryPtr hierarchy(new Hierarchy());
		RepositorySelectorPtr selector(new DefaultRepositorySelector(hierarchy));
		getRepositorySelector() = selector;
	}

	return getRepositorySelector()->getLoggerRepository();
}

LoggerPtr LogManager::getRootLogger()
{
	// Delegate the actual manufacturing of the logger to the logger repository.
	return getLoggerRepository()->getRootLogger();
}

/**
Retrieve the appropriate Logger instance.
*/
LoggerPtr LogManager::getLoggerLS(const LogString& name)
{
	return getLoggerRepository()->getLogger(name);
}

/**
Retrieve the appropriate Logger instance.
*/
LoggerPtr LogManager::getLoggerLS(const LogString& name,
	const spi::LoggerFactoryPtr& factory)
{
	// Delegate the actual manufacturing of the logger to the logger repository.
	return getLoggerRepository()->getLogger(name, factory);
}

LoggerPtr LogManager::getLogger(const std::string& name)
{
	LOG4CXX_DECODE_CHAR(n, name);
	return getLoggerLS(n);
}

LoggerPtr LogManager::getLogger(const std::string& name,
	const spi::LoggerFactoryPtr& factory)
{
	LOG4CXX_DECODE_CHAR(n, name);
	return getLoggerLS(n, factory);
}

LoggerPtr LogManager::exists(const std::string& name)
{
	LOG4CXX_DECODE_CHAR(n, name);
	return existsLS(n);
}

#if LOG4CXX_WCHAR_T_API
LoggerPtr LogManager::getLogger(const std::wstring& name)
{
	LOG4CXX_DECODE_WCHAR(n, name);
	return getLoggerLS(n);
}

LoggerPtr LogManager::getLogger(const std::wstring& name,
	const spi::LoggerFactoryPtr& factory)
{
	LOG4CXX_DECODE_WCHAR(n, name);
	return getLoggerLS(n, factory);
}

LoggerPtr LogManager::exists(const std::wstring& name)
{
	LOG4CXX_DECODE_WCHAR(n, name);
	return existsLS(n);
}
#endif

#if LOG4CXX_UNICHAR_API
LoggerPtr LogManager::getLogger(const std::basic_string<UniChar>& name)
{
	LOG4CXX_DECODE_UNICHAR(n, name);
	return getLoggerLS(n);
}

LoggerPtr LogManager::getLogger(const std::basic_string<UniChar>& name,
	const spi::LoggerFactoryPtr& factory)
{
	LOG4CXX_DECODE_UNICHAR(n, name);
	return getLoggerLS(n, factory);
}

LoggerPtr LogManager::exists(const std::basic_string<UniChar>& name)
{
	LOG4CXX_DECODE_UNICHAR(n, name);
	return existsLS(n);
}
#endif

#if LOG4CXX_CFSTRING_API
LoggerPtr LogManager::getLogger(const CFStringRef& name)
{
	LOG4CXX_DECODE_CFSTRING(n, name);
	return getLoggerLS(n);
}

LoggerPtr LogManager::getLogger(const CFStringRef& name,
	const spi::LoggerFactoryPtr& factory)
{
	LOG4CXX_DECODE_CFSTRING(n, name);
	return getLoggerLS(n, factory);
}

LoggerPtr LogManager::exists(const CFStringRef& name)
{
	LOG4CXX_DECODE_CFSTRING(n, name);
	return existsLS(n);
}
#endif

LoggerPtr LogManager::existsLS(const LogString& name)
{
	return getLoggerRepository()->exists(name);
}

LoggerList LogManager::getCurrentLoggers()
{
	return getLoggerRepository()->getCurrentLoggers();
}

void LogManager::shutdown()
{
	getLoggerRepository()->shutdown();
}

void LogManager::resetConfiguration()
{
	getLoggerRepository()->resetConfiguration();
}
