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