<?php
/**
 * 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.
 *
 * @package log4php
 */

/**
 * The NDC class implements <i>nested diagnostic contexts</i>.
 * 
 * NDC was 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.
 *
 * 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.
 *
 * This class is similar to the {@link LoggerMDC} class except that it is
 * based on a stack instead of a map.
 *
 * 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.
 *
 * <b>Note that NDCs are managed on a per thread basis</b>. 
 * 
 * NDC operations such as {@link push()}, {@link pop()}, 
 * {@link clear()}, {@link getDepth()} and {@link setMaxDepth()}
 * affect the NDC of the <i>current</i> thread only. NDCs of other
 * threads remain unaffected.
 *
 * For example, a servlet can build a per client request NDC
 * consisting the clients host name and other information contained in
 * the the request. <i>Cookies</i> are another source of distinctive
 * information. To build an NDC one uses the {@link push()}
 * operation.
 * 
 * Simply put,
 *
 * - Contexts can be nested.
 * - When entering a context, call <kbd>LoggerNDC::push()</kbd>
 *	 As a side effect, if there is no nested diagnostic context for the
 *	 current thread, this method will create it.
 * - When leaving a context, call <kbd>LoggerNDC::pop()</kbd>
 * - <b>When exiting a thread make sure to call {@link remove()}</b>
 *	 
 * There is no penalty for forgetting to match each
 * <kbd>push</kbd> operation with a corresponding <kbd>pop</kbd>,
 * except the obvious mismatch between the real application context
 * and the context set in the NDC.
 *
 * If configured to do so, {@link LoggerPatternLayout} and {@link LoggerLayoutTTCC} 
 * 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 category) can still be distinguished because each client
 * request will have a different NDC tag.
 *
 * Example:
 *	
 * {@example ../../examples/php/ndc.php 19}<br>
 *
 * With the properties file:
 * 
 * {@example ../../examples/resources/ndc.properties 18}<br>
 * 
 * Will result in the following (notice the conn and client ids):
 * 
 * <pre>
 * 2009-09-13 19:04:27 DEBUG root conn=1234: just received a new connection in src/examples/php/ndc.php at 23
 * 2009-09-13 19:04:27 DEBUG root conn=1234 client=ab23: some more messages that can in src/examples/php/ndc.php at 25
 * 2009-09-13 19:04:27 DEBUG root conn=1234 client=ab23: now related to a client in src/examples/php/ndc.php at 26
 * 2009-09-13 19:04:27 DEBUG root : back and waiting for new connections in src/examples/php/ndc.php at 29
 * </pre>
 *	
 * @version $Revision$
 * @package log4php 
 * @since 0.3
 */
class LoggerNDC {
	
	/** This is the repository of NDC stack */
	private static $stack = array();
	
	/**
	 * 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.
	 *
	 * <p>This method is equivalent to calling the {@link setMaxDepth()}
	 * method with a zero <var>maxDepth</var> argument.
	 */
	public static function clear() {
		self::$stack = array();
	}

	/**
	 * Never use this method directly, use the {@link LoggerLoggingEvent::getNDC()} method instead.
	 * @return array
	 */
	public static function get() {
		return implode(' ', self::$stack);
	}
  
	/**
	 * Get the current nesting depth of this diagnostic context.
	 *
	 * @see setMaxDepth()
	 * @return integer
	 */
	public static function getDepth() {
		return count(self::$stack);
	}

	/**
	 * Clients should call this method before leaving a diagnostic
	 * context.
	 *
	 * <p>The returned value is the value that was pushed last. If no
	 * context is available, then the empty string "" is returned.</p>
	 *
	 * @return string The innermost diagnostic context.
	 */
	public static function pop() {
		if(count(self::$stack) > 0) {
			return array_pop(self::$stack);
		} else {
			return '';
		}
	}

	/**
	 * 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.</p>
	 * @return string The innermost diagnostic context.
	 */
	public static function peek() {
		if(count(self::$stack) > 0) {
			return end(self::$stack);
		} else {
			return '';
		}
	}
	
	/**
	 * Push new diagnostic context information for the current thread.
	 *
	 * <p>The contents of the <var>message</var> parameter is
	 * determined solely by the client.
	 *	
	 * @param string $message The new diagnostic context information.
	 */
	public static function push($message) {
		array_push(self::$stack, (string)$message);
	}

	/**
	 * Remove the diagnostic context for this thread.
	 */
	public static function remove() {
		LoggerNDC::clear();
	}

	/**
	 * Set maximum depth of this diagnostic context. If the current
	 * depth is smaller or equal to <var>maxDepth</var>, then no
	 * action is taken.
	 *
	 * <p>This method is a convenient alternative to multiple 
	 * {@link pop()} calls. Moreover, it is often the case that at 
	 * the end of complex call sequences, the depth of the NDC is
	 * unpredictable. The {@link setMaxDepth()} method circumvents
	 * this problem.
	 *
	 * @param integer $maxDepth
	 * @see getDepth()
	 */
	public static function setMaxDepth($maxDepth) {
		$maxDepth = (int)$maxDepth;
		if(LoggerNDC::getDepth() > $maxDepth) {
			self::$stack = array_slice(self::$stack, 0, $maxDepth);
		}
	}
}
