/*
 * 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_LEVEL_H
#define _LOG4CXX_LEVEL_H


#include <log4cxx/logstring.h>
#include <limits.h>
#include <log4cxx/helpers/objectimpl.h>
#include <log4cxx/helpers/objectptr.h>


namespace log4cxx
{
	/**
	 * LOG4CXX_PTR_DEF can't be used to get a smart pointer for Level because we need to override
	 * the comparison operator and this doesn't work if the template has alread been initialized,
	 * which is what the macro does on some platforms. The overriding takes place underneath the
	 * definition of Level because we need one of it's methods.
	 *
	 * https://issues.apache.org/jira/browse/LOGCXX-394
	 */
	class Level;
	typedef log4cxx::helpers::ObjectPtrT<Level> LevelPtr;

        /**
        Defines the minimum set of levels recognized by the system, that is
        <code>OFF</code>, <code>FATAL</code>, <code>ERROR</code>,
        <code>WARN</code>, <code>INFO</code>, <code>DEBUG</code> and
        <code>ALL</code>.
        <p>The <code>Level</code> class may be subclassed to define a larger
        level set.
        */
        class LOG4CXX_EXPORT Level : public helpers::ObjectImpl
        {
        public:
                class LOG4CXX_EXPORT LevelClass : public helpers::Class
                {
                public:
                        LevelClass() : helpers::Class() {}

                        virtual LogString getName() const {
                            return LOG4CXX_STR("Level");
                        }

                        virtual LevelPtr toLevel(const LogString& sArg) const
                        { return Level::toLevelLS(sArg); }

                        virtual LevelPtr toLevel(int val) const
                        { return Level::toLevel(val); }
                };

                DECLARE_LOG4CXX_OBJECT_WITH_CUSTOM_CLASS(Level, LevelClass)
                BEGIN_LOG4CXX_CAST_MAP()
                        LOG4CXX_CAST_ENTRY(Level)
                END_LOG4CXX_CAST_MAP()

                /**
                Instantiate a Level object.
                */
                Level(int level,
                       const LogString& name,
                       int syslogEquivalent);

                /**
                Convert the string passed as argument to a level. If the
                conversion fails, then this method returns DEBUG.
                * @param sArg level name.
                */
                static LevelPtr toLevel(const std::string& sArg);
                /**
                Convert the string passed as argument to a level. If the
                conversion fails, then this method returns the value of
                <code>defaultLevel</code>.
                * @param sArg level name.
                * @param defaultLevel level to return if no match.
                * @return
                */
                static LevelPtr toLevel(const std::string& sArg,
                        const LevelPtr& defaultLevel);
                /**
                 *  Get the name of the level in the current encoding.
                 *  @param name buffer to which name is appended.
                 */
                void toString(std::string& name) const;

#if LOG4CXX_WCHAR_T_API
                /**
                Convert the string passed as argument to a level. If the
                conversion fails, then this method returns DEBUG.
                * @param sArg level name.
                */
                static LevelPtr toLevel(const std::wstring& sArg);
                /**
                Convert the string passed as argument to a level. If the
                conversion fails, then this method returns the value of
                <code>defaultLevel</code>.
                * @param sArg level name.
                * @param defaultLevel level to return if no match.
                * @return
                */
                static LevelPtr toLevel(const std::wstring& sArg,
                        const LevelPtr& defaultLevel);
                /**
                 *  Get the name of the level.
                 *  @param name buffer to which name is appended.
                 */
                void toString(std::wstring& name) const;
#endif
#if LOG4CXX_UNICHAR_API
                /**
                Convert the string passed as argument to a level. If the
                conversion fails, then this method returns DEBUG.
                * @param sArg level name.
                */
                static LevelPtr toLevel(const std::basic_string<UniChar>& sArg);
                /**
                Convert the string passed as argument to a level. If the
                conversion fails, then this method returns the value of
                <code>defaultLevel</code>.
                * @param sArg level name.
                * @param defaultLevel level to return if no match.
                * @return
                */
                static LevelPtr toLevel(const std::basic_string<UniChar>& sArg,
                        const LevelPtr& defaultLevel);
                /**
                 *  Get the name of the level.
                 *  @param name buffer to which name is appended.
                 */
                void toString(std::basic_string<UniChar>& name) const;
#endif
#if LOG4CXX_CFSTRING_API
                /**
                Convert the string passed as argument to a level. If the
                conversion fails, then this method returns DEBUG.
                * @param sArg level name.
                */
                static LevelPtr toLevel(const CFStringRef& sArg);
                /**
                Convert the string passed as argument to a level. If the
                conversion fails, then this method returns the value of
                <code>defaultLevel</code>.
                * @param sArg level name.
                * @param defaultLevel level to return if no match.
                * @return
                */
                static LevelPtr toLevel(const CFStringRef& sArg,
                        const LevelPtr& defaultLevel);
                /**
                 *  Get the name of the level.
                 *  @param name buffer to which name is appended.
                 */
                void toString(CFStringRef& name) const;
#endif
                /**
                Convert the string passed as argument to a level. If the
                conversion fails, then this method returns DEBUG.
                * @param sArg level name.
                */
                static LevelPtr toLevelLS(const LogString& sArg);
                /**
                Convert the string passed as argument to a level. If the
                conversion fails, then this method returns the value of
                <code>defaultLevel</code>.
                * @param sArg level name.
                * @param defaultLevel level to return if no match.
                * @return
                */
                static LevelPtr toLevelLS(const LogString& sArg,
                        const LevelPtr& defaultLevel);
                /**
                Returns the string representation of this level.
                * @return level name.
                */
                LogString toString() const;

                /**
                Convert an integer passed as argument to a level. If the
                conversion fails, then this method returns DEBUG.
                */
                static LevelPtr toLevel(int val);

                /**
                Convert an integer passed as argument to a level. If the
                conversion fails, then this method returns the specified default.
                */
                static LevelPtr toLevel(int val, const LevelPtr& defaultLevel);

                enum {
                    OFF_INT = INT_MAX,
                    FATAL_INT = 50000,
                    ERROR_INT = 40000,
                    WARN_INT = 30000,
                    INFO_INT = 20000,
                    DEBUG_INT = 10000,
                    TRACE_INT = 5000,
                    ALL_INT = INT_MIN
                };


                static LevelPtr getAll();
                static LevelPtr getFatal();
                static LevelPtr getError();
                static LevelPtr getWarn();
                static LevelPtr getInfo();
                static LevelPtr getDebug();
                static LevelPtr getTrace();
                static LevelPtr getOff();


                /**
                Two levels are equal if their level fields are equal.
                */
                virtual bool equals(const LevelPtr& level) const;

                inline bool operator==(const Level& level1) const
                        { return (this->level == level1.level); }

                inline bool operator!=(const Level& level1) const
                        { return (this->level != level1.level); }

                /**
                Return the syslog equivalent of this level as an integer.
                */
                inline int getSyslogEquivalent() const {
                  return syslogEquivalent;
                }


                /**
                Returns <code>true</code> if this level has a higher or equal
                level than the level passed as argument, <code>false</code>
                otherwise.

                <p>You should think twice before overriding the default
                implementation of <code>isGreaterOrEqual</code> method.

                */
                virtual bool isGreaterOrEqual(const LevelPtr& level) const;


                /**
                Returns the integer representation of this level.
                */
                inline int toInt() const {
                  return level;
                }

        private:
                int level;
                LogString name;
                int syslogEquivalent;
                Level(const Level&);
                Level& operator=(const Level&);
        };

	/**
	 * We need to double some logic from LOG4CXX_PTR_DEF or else we are unable to override the
	 * comparison operator, which we need to properly fix LOGCXX-394.
	 *
	 * https://issues.apache.org/jira/browse/LOGCXX-394
	 */
	namespace helpers {

	/** @class log4cxx::helpers::ObjectPtr */
	template<> inline bool LevelPtr::operator==(const LevelPtr& rhs) const
	{ return (*this)->equals(rhs); }
	template<> inline bool LevelPtr::operator!=(const LevelPtr& rhs) const
	{ return !(*this == rhs); }
	#if defined(_MSC_VER) && !defined(LOG4CXX_STATIC) && defined(LOG4CXX)
		template class LOG4CXX_EXPORT log4cxx::helpers::ObjectPtrT<Level>;
	#elif defined(_MSC_VER) && !defined(LOG4CXX_STATIC)
		#pragma warning(push)
		#pragma warning(disable: 4231)
		extern template class LOG4CXX_EXPORT log4cxx::helpers::ObjectPtrT<Level>;
		#pragma warning(pop)
	#endif

	}

}

#define DECLARE_LOG4CXX_LEVEL(level)\
public:\
        class Class##level : public Level::LevelClass\
{\
public:\
        Class##level() : Level::LevelClass() {}\
        virtual LogString getName() const { return LOG4CXX_STR(#level); } \
        virtual LevelPtr toLevel(const LogString& sArg) const\
        { return level::toLevelLS(sArg); }\
        virtual LevelPtr toLevel(int val) const\
        { return level::toLevel(val); }\
};\
DECLARE_LOG4CXX_OBJECT_WITH_CUSTOM_CLASS(level, Class##level)

#define IMPLEMENT_LOG4CXX_LEVEL(level) \
IMPLEMENT_LOG4CXX_OBJECT_WITH_CUSTOM_CLASS(level, Class##level)


#endif //_LOG4CXX_LEVEL_H
