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

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

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)

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

#endif //_LOG4CXX_LEVEL_H
