/*
 * 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_NDC_H
#define _LOG4CXX_NDC_H

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

#include <log4cxx/log4cxx.h>
#include <log4cxx/logstring.h>
#include <stack>

namespace log4cxx
{
/**
the ndc class implements <i>nested diagnostic contexts</i> as
defined by neil harrison in the article "patterns for logging
diagnostic messages" part of the book "<i>pattern languages of
program design 3</i>" edited by martin et al.

<p>a nested diagnostic context, or ndc in short, is an instrument
to distinguish interleaved log output from different sources. log
output is typically interleaved when a server handles multiple
clients near-simultaneously.

<p>interleaved log output can still be meaningful if each log entry
from different contexts had a distinctive stamp. this is where ndcs
come into play.

<p><em><b>note that ndcs are managed on a per thread
basis</b></em>. ndc operations such as #push,
#pop, #clear and #getDepth
affect the ndc of the <em>current</em> thread only. ndcs of other
threads remain unaffected.

<p>for example, a servlet can build a per client request ndc
consisting the clients host name and other information contained in
the the request. <em>cookies</em> are another source of distinctive
information. to build an ndc one uses the #push
operation. simply put,

<p><ul>
 <li>contexts can be nested.

 <p><li>when entering a context, call <code>ndc.push</code>. as a
 side effect, if there is no nested diagnostic context for the
 current thread, this method will create it.

 <p><li>when leaving a context, call <code>ndc.pop</code>.

 <p><li><b>when exiting a thread make sure to call #remove
 </b>.
</ul>

<p>there is no penalty for forgetting to match each
<code>push</code> operation with a corresponding <code>pop</code>,
except the obvious mismatch between the real application context
and the context set in the ndc.

<p>if configured to do so, PatternLayout and
TTCCLayout instances automatically retrieve the nested diagnostic
context for the current thread without any user intervention.
hence, even if a servlet is serving multiple clients
simultaneously, the logs emanating from the same code (belonging to
the same logger) can still be distinguished because each client
request will have a different ndc tag.

<p>heavy duty systems should call the #remove method when
leaving the run method of a thread. this ensures that the memory
used by the thread can be freed by the java garbage
collector. there is a mechanism to lazily remove references to dead
threads. in practice, this means that you can be a little sloppy
and sometimes forget to call #remove before exiting a
thread.

*/
class LOG4CXX_EXPORT NDC
{
	public:
		/**
		 *  Pair of Message and FullMessage.
		 */
		typedef std::pair<LogString, LogString> DiagnosticContext;
		typedef std::stack<DiagnosticContext> Stack;

		/**
		 Creates a nested diagnostic context.
		 Since java performs no automatic cleanup of objects when a
		 scope is left, in log4j push() and pop() must be used
		 to manage the NDC. For convenience, log4cxx provides
		 an NDC constructor and destructor which simply call the push() and
		 pop() methods, allowing for automatic cleanup when the current
		 scope ends.

		 @param message The new diagnostic context information.
		 @see The #push method.
		 */
		NDC(const std::string& message);

		/**
		Removes the topmost element from the NDC stack.

		@see The #pop method.
		*/
		~NDC();

		/**
		Clear any nested diagnostic information if any. This method is
		useful in cases where the same thread can be potentially used
		over and over in different unrelated contexts.
		*/
		static void clear();

		/**
		    Clone the diagnostic context for the current thread.
		    <p>Internally a diagnostic context is represented as a stack.  A
		    given thread can supply the stack (i.e. diagnostic context) to a
		    child thread so that the child can inherit the parent thread's
		    diagnostic context.
		    <p>The child thread uses the #inherit method to
		    inherit the parent's diagnostic context.
		    <p>If not passed to #inherit, returned stack should be deleted by caller.
		    @return Stack A clone of the current thread's diagnostic context, will not be null.
		*/
		static Stack* cloneStack();

		/**
		Inherit the diagnostic context of another thread.
		<p>The parent thread can obtain a reference to its diagnostic
		context using the #cloneStack method.  It should
		communicate this information to its child so that it may inherit
		the parent's diagnostic context.
		<p>The parent's diagnostic context is cloned before being
		inherited. In other words, once inherited, the two diagnostic
		contexts can be managed independently.
		@param stack The diagnostic context of the parent thread,
		    will be deleted during call.  If NULL, NDC will not be modified.
		*/
		static void inherit(Stack* stack);

		/**
		 *   Get the current value of the NDC of the
		 *   currrent thread.
		* @param dest destination to which to append content of NDC.
		* @return true if NDC is set.
		*/
		static bool get(LogString& dest);

		/**
		Get the current nesting depth of this diagnostic context.
		*/
		static int getDepth();


		/**
		* Tests if the NDC is empty.
		*/
		static bool empty();

		/**
		Pop top value off stack.
		@return top value.
		*/
		static LogString pop();
		/**
		Pop top value off stack.
		@param buf to which top value is appended.
		@return true if NDC contained at least one value.
		*/
		static bool pop(std::string& buf);

		/**
		Looks at the last diagnostic context at the top of this NDC
		without removing it.
		<p>The returned value is the value that was pushed last. If no
		context is available, then the empty string "" is returned.
		@return String The innermost diagnostic context.
		*/
		static LogString peek();
		/**
		Get top value without removing value.
		@param buf to which top value is appended.
		@return true if NDC contained at least one value.
		*/
		static bool peek(std::string& buf);

		/**
		Push new diagnostic context information for the current thread.
		<p>The contents of the <code>message</code> parameter is
		determined solely by the client.
		@param message The new diagnostic context information.
		*/
		static void push(const std::string& message);
		/**
		Push new diagnostic context information for the current thread.
		<p>The contents of the <code>message</code> parameter is
		determined solely by the client.
		@param message The new diagnostic context information.
		*/
		static void pushLS(const LogString& message);

		/**
		Remove the diagnostic context for this thread.
		<p>Each thread that created a diagnostic context by calling
		#push should call this method before exiting. Otherwise,
		the memory used by the <b>thread</b> cannot be reclaimed by the
		VM.
		<p>As this is such an important problem in heavy duty systems and
		because it is difficult to always guarantee that the remove
		method is called before exiting a thread, this method has been
		augmented to lazily remove references to dead threads. In
		practice, this means that you can be a little sloppy and
		occasionally forget to call #remove before exiting a
		thread. However, you must call <code>remove</code> sometime. If
		you never call it, then your application is sure to run out of
		memory.
		*/
		static void remove();

#if LOG4CXX_WCHAR_T_API
		/**
		  Creates a nested diagnostic context.
		  Since java performs no automatic cleanup of objects when a
		  scope is left, in log4j push() and pop() must be used
		  to manage the NDC. For convenience, log4cxx provides
		  an NDC constructor and destructor which simply call the push() and
		  pop() methods, allowing for automatic cleanup when the current
		  scope ends.

		  @param message The new diagnostic context information.
		  @see The #push method.
		  */
		NDC(const std::wstring& message);
		/**
		Push new diagnostic context information for the current thread.
		<p>The contents of the <code>message</code> parameter is
		determined solely by the client.
		@param message The new diagnostic context information.
		*/
		static void push(const std::wstring& message);
		/**
		 *   Appends the current NDC content to the provided string.
		 *   @param dst destination.
		 *   @return true if NDC value set.
		 */
		static bool peek(std::wstring& dst);
		/**
		 *   Appends the current NDC content to the provided string and removes the value from the NDC.
		 *   @param dst destination.
		 *   @return true if NDC value set.
		 */
		static bool pop(std::wstring& dst);
#endif
#if LOG4CXX_UNICHAR_API
		/**
		  Creates a nested diagnostic context.
		  Since java performs no automatic cleanup of objects when a
		  scope is left, in log4j push() and pop() must be used
		  to manage the NDC. For convenience, log4cxx provides
		  an NDC constructor and destructor which simply call the push() and
		  pop() methods, allowing for automatic cleanup when the current
		  scope ends.

		  @param message The new diagnostic context information.
		  @see The #push method.
		  */
		NDC(const std::basic_string<UniChar>& message);
		/**
		Push new diagnostic context information for the current thread.
		<p>The contents of the <code>message</code> parameter is
		determined solely by the client.
		@param message The new diagnostic context information.
		*/
		static void push(const std::basic_string<UniChar>& message);
		/**
		 *   Appends the current NDC content to the provided string.
		 *   @param dst destination.
		 *   @return true if NDC value set.
		 */
		static bool peek(std::basic_string<UniChar>& dst);
		/**
		 *   Appends the current NDC content to the provided string and removes the value from the NDC.
		 *   @param dst destination.
		 *   @return true if NDC value set.
		 */
		static bool pop(std::basic_string<UniChar>& dst);
#endif
#if LOG4CXX_CFSTRING_API
		/**
		  Creates a nested diagnostic context.
		  Since java performs no automatic cleanup of objects when a
		  scope is left, in log4j push() and pop() must be used
		  to manage the NDC. For convenience, log4cxx provides
		  an NDC constructor and destructor which simply call the push() and
		  pop() methods, allowing for automatic cleanup when the current
		  scope ends.

		  @param message The new diagnostic context information.
		  @see The #push method.
		  */
		NDC(const CFStringRef& message);
		/**
		Push new diagnostic context information for the current thread.
		<p>The contents of the <code>message</code> parameter is
		determined solely by the client.
		@param message The new diagnostic context information.
		*/
		static void push(const CFStringRef& message);
		/**
		 *   Gets the current NDC value.
		 *   @param dst destination.
		 *   @return true if NDC value set.
		 */
		static bool peek(CFStringRef& dst);
		/**
		 *  Gets and removes the current NDC value.
		 *   @param dst destination.
		 *   @return true if NDC value set.
		 */
		static bool pop(CFStringRef& dst);
#endif

	private:
		NDC(const NDC&);
		NDC& operator=(const NDC&);
		static LogString& getMessage(DiagnosticContext& ctx);
		static LogString& getFullMessage(DiagnosticContext& ctx);
}; // class NDC;
}  // namespace log4cxx

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


#endif // _LOG4CXX_NDC_H
