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

#ifndef _LOG4CXX_LOG_MANAGER_H
#define _LOG4CXX_LOG_MANAGER_H

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

#include <log4cxx/logstring.h>
#include <vector>
#include <log4cxx/spi/repositoryselector.h>

namespace log4cxx
{
class Logger;
typedef helpers::ObjectPtrT<Logger> LoggerPtr;
typedef std::vector<LoggerPtr> LoggerList;

namespace spi
{
class LoggerFactory;
typedef helpers::ObjectPtrT<LoggerFactory> LoggerFactoryPtr;
}

/**
* Use the <code>LogManager</code> class to retreive Logger
* instances or to operate on the current
* {@link log4cxx::spi::LoggerRepository LoggerRepository}.
* When the <code>LogManager</code> class is loaded
* into memory the default initialization procedure is inititated.
    */
class LOG4CXX_EXPORT LogManager
{
	private:
		static void* guard;
		static spi::RepositorySelectorPtr& getRepositorySelector();

	public:
		/**
		Sets <code>LoggerFactory</code> but only if the correct
		<em>guard</em> is passed as parameter.

		<p>Initally the guard is null.  If the guard is
		<code>null</code>, then invoking this method sets the logger
		factory and the guard. Following invocations will throw a {@link
		helpers::IllegalArgumentException IllegalArgumentException},
		        unless the previously set <code>guard</code> is passed as the second
		        parameter.

		<p>This allows a high-level component to set the {@link
		spi::RepositorySelector RepositorySelector} used by the
		        <code>LogManager</code>.
		        */

		static void setRepositorySelector(spi::RepositorySelectorPtr selector,
			void* guard);

		static spi::LoggerRepositoryPtr& getLoggerRepository();

		/**
		Retrieve the appropriate root logger.
		*/
		static LoggerPtr getRootLogger();

		/**
		Retrieve the appropriate Logger instance.
		* @param name logger name in current encoding.
		* @return logger.
		*/
		static LoggerPtr getLogger(const std::string& name);
		/**
		Retrieve the appropriate Logger instance.
		* @param name logger name in current encoding.
		* @param factory logger factory.
		* @return logger.
		*/
		static LoggerPtr getLogger(const std::string& name,
			const spi::LoggerFactoryPtr& factory);
		/**
		 * Determines if logger name exists in the hierarchy.
		 * @param name logger name.
		 * @return true if logger exists.
		 */
		static LoggerPtr exists(const std::string& name);
#if LOG4CXX_WCHAR_T_API
		/**
		Retrieve the appropriate Logger instance.
		* @param name logger name.
		* @return logger.
		*/
		static LoggerPtr getLogger(const std::wstring& name);
		/**
		Retrieve the appropriate Logger instance.
		* @param name logger name.
		* @param factory logger factory.
		* @return logger.
		*/
		static LoggerPtr getLogger(const std::wstring& name,
			const spi::LoggerFactoryPtr& factory);
		/**
		 * Determines if logger name exists in the hierarchy.
		 * @param name logger name.
		 * @return true if logger exists.
		 */
		static LoggerPtr exists(const std::wstring& name);
#endif
#if LOG4CXX_UNICHAR_API
		/**
		Retrieve the appropriate Logger instance.
		* @param name logger name.
		* @return logger.
		*/
		static LoggerPtr getLogger(const std::basic_string<UniChar>& name);
		/**
		Retrieve the appropriate Logger instance.
		* @param name logger name.
		* @param factory logger factory.
		* @return logger.
		*/
		static LoggerPtr getLogger(const std::basic_string<UniChar>& name,
			const spi::LoggerFactoryPtr& factory);
		/**
		 * Determines if logger name exists in the hierarchy.
		 * @param name logger name.
		 * @return true if logger exists.
		 */
		static LoggerPtr exists(const std::basic_string<UniChar>& name);
#endif
#if LOG4CXX_CFSTRING_API
		/**
		Retrieve the appropriate Logger instance.
		* @param name logger name.
		* @return logger.
		*/
		static LoggerPtr getLogger(const CFStringRef& name);
		/**
		Retrieve the appropriate Logger instance.
		* @param name logger name.
		* @param factory logger factory.
		* @return logger.
		*/
		static LoggerPtr getLogger(const CFStringRef& name,
			const spi::LoggerFactoryPtr& factory);
		/**
		 * Determines if logger name exists in the hierarchy.
		 * @param name logger name.
		 * @return true if logger exists.
		 */
		static LoggerPtr exists(const CFStringRef& name);
#endif


		/**
		Retrieve the appropriate Logger instance.
		* @param name logger name.
		* @return logger.
		*/
		static LoggerPtr getLoggerLS(const LogString& name);
		/**
		Retrieve the appropriate Logger instance.
		* @param name logger name.
		* @param factory logger factory.
		* @return logger.
		*/
		static LoggerPtr getLoggerLS(const LogString& name,
			const spi::LoggerFactoryPtr& factory);

		/**
		 * Determines if logger name exists in the hierarchy.
		 * @param name logger name.
		 * @return true if logger exists.
		 */
		static LoggerPtr existsLS(const LogString& name);

		static LoggerList getCurrentLoggers();

		/**
		Safely close and remove all appenders in all loggers including
		the root logger.
		*/
		static void shutdown();

		/**
		Reset all values contained in this current {@link
		spi::LoggerRepository LoggerRepository}  to their default.
		*/
		static void resetConfiguration();
}; // class LogManager
}  // namespace log4cxx

#if defined(_MSC_VER)
	#pragma warning ( pop )
#endif


#endif //_LOG4CXX_LOG_MANAGER_H
