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

/**
 * A flexible layout configurable with a pattern string.
 * 
 * ## Configurable parameters: ##
 * 
 * - **converionPattern** - A string which controls the formatting of logging 
 *   events. See docs for full specification.
 * 
 * @package log4php
 * @subpackage layouts
 * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
 * @link http://logging.apache.org/log4php/docs/layouts/pattern.html Layout documentation
 */
class LoggerLayoutPattern extends LoggerLayout {
	
	/** Default conversion pattern */
	const DEFAULT_CONVERSION_PATTERN = '%date %-5level %logger %message%newline';

	/** Default conversion TTCC Pattern */
	const TTCC_CONVERSION_PATTERN = '%d [%t] %p %c %x - %m%n';

	/** The conversion pattern. */ 
	protected $pattern = self::DEFAULT_CONVERSION_PATTERN;
	
	/** Maps conversion keywords to the relevant converter (default implementation). */
	protected static $defaultConverterMap = array(
		'c' => 'LoggerPatternConverterLogger',
		'lo' => 'LoggerPatternConverterLogger',
		'logger' => 'LoggerPatternConverterLogger',
		
		'C' => 'LoggerPatternConverterClass',
		'class' => 'LoggerPatternConverterClass',
		
		'cookie' => 'LoggerPatternConverterCookie',
		
		'd' => 'LoggerPatternConverterDate',
		'date' => 'LoggerPatternConverterDate',
		
		'e' => 'LoggerPatternConverterEnvironment',
		'env' => 'LoggerPatternConverterEnvironment',
		
		'ex' => 'LoggerPatternConverterThrowable',
		'exception' => 'LoggerPatternConverterThrowable',
		'throwable' => 'LoggerPatternConverterThrowable',
		
		'F' => 'LoggerPatternConverterFile',
		'file' => 'LoggerPatternConverterFile',
			
		'l' => 'LoggerPatternConverterLocation',
		'location' => 'LoggerPatternConverterLocation',
		
		'L' => 'LoggerPatternConverterLine',
		'line' => 'LoggerPatternConverterLine',
		
		'm' => 'LoggerPatternConverterMessage',
		'msg' => 'LoggerPatternConverterMessage',
		'message' => 'LoggerPatternConverterMessage',
		
		'M' => 'LoggerPatternConverterMethod',
		'method' => 'LoggerPatternConverterMethod',
		
		'n' => 'LoggerPatternConverterNewLine',
		'newline' => 'LoggerPatternConverterNewLine',
		
		'p' => 'LoggerPatternConverterLevel',
		'le' => 'LoggerPatternConverterLevel',
		'level' => 'LoggerPatternConverterLevel',
	
		'r' => 'LoggerPatternConverterRelative',
		'relative' => 'LoggerPatternConverterRelative',
		
		'req' => 'LoggerPatternConverterRequest',
		'request' => 'LoggerPatternConverterRequest',
		
		's' => 'LoggerPatternConverterServer',
		'server' => 'LoggerPatternConverterServer',
		
		'ses' => 'LoggerPatternConverterSession',
		'session' => 'LoggerPatternConverterSession',
		
		'sid' => 'LoggerPatternConverterSessionID',
		'sessionid' => 'LoggerPatternConverterSessionID',
	
		't' => 'LoggerPatternConverterProcess',
		'pid' => 'LoggerPatternConverterProcess',
		'process' => 'LoggerPatternConverterProcess',
		
		'x' => 'LoggerPatternConverterNDC',
		'ndc' => 'LoggerPatternConverterNDC',
			
		'X' => 'LoggerPatternConverterMDC',
		'mdc' => 'LoggerPatternConverterMDC',
	);

	/** Maps conversion keywords to the relevant converter. */
	protected $converterMap = array();
	
	/** 
	 * Head of a chain of Converters.
	 * @var LoggerPatternConverter 
	 */
	private $head;

	/** Returns the default converter map. */
	public static function getDefaultConverterMap() {
		return self::$defaultConverterMap;
	}
	
	/** Constructor. Initializes the converter map. */
	public function __construct() {
		$this->converterMap = self::$defaultConverterMap;
	}
	
	/**
	 * Sets the 'conversionPattern' parameter.
	 * @param string $conversionPattern
	 */
	public function setConversionPattern($conversionPattern) {
		$this->pattern = $conversionPattern;
	}
	
	/**
	 * Returns the value of the 'conversionPattern' parameter.
	 * @return string
	 */
	public function getConversionPattern() {
		return $this->pattern;
	}
	
	/**
	 * Processes the conversion pattern and creates a corresponding chain of 
	 * pattern converters which will be used to format logging events. 
	 */
	public function activateOptions() {
		if (!isset($this->pattern)) {
			throw new LoggerException("Mandatory parameter 'conversionPattern' is not set.");
		}
		
		$parser = new LoggerPatternParser($this->pattern, $this->converterMap);
		$this->head = $parser->parse();
	}
	
	/**
	 * Produces a formatted string as specified by the conversion pattern.
	 *
	 * @param LoggerLoggingEvent $event
	 * @return string
	 */
	public function format(LoggerLoggingEvent $event) {
		$sbuf = '';
		$converter = $this->head;
		while ($converter !== null) {
			$converter->format($sbuf, $event);
			$converter = $converter->next;
		}
		return $sbuf;
	}
}