/*
 * 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 <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;
spi::RepositorySelectorPtr LogManager::repositorySelector;


RepositorySelectorPtr LogManager::getRepositorySelector()
{
	//
	//     call to initialize APR and trigger "start" of logging clock
	//
    APRInitializer::initialize();
    if (!repositorySelector)
    {
        LoggerRepositoryPtr hierarchy(new Hierarchy());
        RepositorySelectorPtr selector(new DefaultRepositorySelector(hierarchy));
        repositorySelector = selector;
    }
    return repositorySelector;
}

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()
{
	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()
{
    LoggerRepositoryPtr repPtr = getLoggerRepository();
	getLoggerRepository()->shutdown();
}

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