#region Apache License
//
// 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.
//
#endregion

using System;
using System.Collections;
using System.Globalization;

using log4net.Core;
using log4net.Layout;

namespace log4net.Util
{
	/// <summary>
	/// Most of the work of the <see cref="PatternLayout"/> class
	/// is delegated to the PatternParser class.
	/// </summary>
	/// <remarks>
	/// <para>
	/// The <c>PatternParser</c> processes a pattern string and
	/// returns a chain of <see cref="PatternConverter"/> objects.
	/// </para>
	/// </remarks>
	/// <author>Nicko Cadell</author>
	/// <author>Gert Driesen</author>
	public sealed class PatternParser
	{
		#region Public Instance Constructors

		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="pattern">The pattern to parse.</param>
		/// <remarks>
		/// <para>
		/// Initializes a new instance of the <see cref="PatternParser" /> class 
		/// with the specified pattern string.
		/// </para>
		/// </remarks>
		public PatternParser(string pattern) 
		{
			m_pattern = pattern;
		}

		#endregion Public Instance Constructors

		#region Public Instance Methods

		/// <summary>
		/// Parses the pattern into a chain of pattern converters.
		/// </summary>
		/// <returns>The head of a chain of pattern converters.</returns>
		/// <remarks>
		/// <para>
		/// Parses the pattern into a chain of pattern converters.
		/// </para>
		/// </remarks>
		public PatternConverter Parse()
		{
			string[] converterNamesCache = BuildCache();

			ParseInternal(m_pattern, converterNamesCache);

			return m_head;
		}

		#endregion Public Instance Methods

		#region Public Instance Properties

		/// <summary>
		/// Get the converter registry used by this parser
		/// </summary>
		/// <value>
		/// The converter registry used by this parser
		/// </value>
		/// <remarks>
		/// <para>
		/// Get the converter registry used by this parser
		/// </para>
		/// </remarks>
		public Hashtable PatternConverters
		{
			get { return m_patternConverters; }
		}

		#endregion Public Instance Properties

		#region Private Instance Methods

		/// <summary>
		/// Build the unified cache of converters from the static and instance maps
		/// </summary>
		/// <returns>the list of all the converter names</returns>
		/// <remarks>
		/// <para>
		/// Build the unified cache of converters from the static and instance maps
		/// </para>
		/// </remarks>
		private string[] BuildCache()
		{
			string[] converterNamesCache = new string[m_patternConverters.Keys.Count];
			m_patternConverters.Keys.CopyTo(converterNamesCache, 0);

			// sort array so that longer strings come first
			Array.Sort(converterNamesCache, 0, converterNamesCache.Length, StringLengthComparer.Instance);

			return converterNamesCache;
		}

		#region StringLengthComparer

		/// <summary>
		/// Sort strings by length
		/// </summary>
		/// <remarks>
		/// <para>
		/// <see cref="IComparer" /> that orders strings by string length.
		/// The longest strings are placed first
		/// </para>
		/// </remarks>
		private sealed class StringLengthComparer : IComparer
		{
			public static readonly StringLengthComparer Instance = new StringLengthComparer();

			private StringLengthComparer()
			{
			}

			#region Implementation of IComparer

			public int Compare(object x, object y)
			{
				string s1 = x as string;
				string s2 = y as string;

				if (s1 == null && s2 == null)
				{
					return 0;
				}
				if (s1 == null)
				{
					return 1;
				}
				if (s2 == null)
				{
					return -1;
				}

				return s2.Length.CompareTo(s1.Length);
			}
		
			#endregion
		}

		#endregion // StringLengthComparer

		/// <summary>
		/// Internal method to parse the specified pattern to find specified matches
		/// </summary>
		/// <param name="pattern">the pattern to parse</param>
		/// <param name="matches">the converter names to match in the pattern</param>
		/// <remarks>
		/// <para>
		/// The matches param must be sorted such that longer strings come before shorter ones.
		/// </para>
		/// </remarks>
		private void ParseInternal(string pattern, string[] matches)
		{
			int offset = 0;
			while(offset < pattern.Length)
			{
				int i = pattern.IndexOf('%', offset);
				if (i < 0 || i == pattern.Length - 1)
				{
					ProcessLiteral(pattern.Substring(offset));
					offset = pattern.Length;
				}
				else
				{
					if (pattern[i+1] == '%')
					{
						// Escaped
						ProcessLiteral(pattern.Substring(offset, i - offset + 1));
						offset = i + 2;
					}
					else
					{
						ProcessLiteral(pattern.Substring(offset, i - offset));
						offset = i + 1;

						FormattingInfo formattingInfo = new FormattingInfo();

						// Process formatting options

						// Look for the align flag
						if (offset < pattern.Length)
						{
							if (pattern[offset] == '-')
							{
								// Seen align flag
								formattingInfo.LeftAlign = true;
								offset++;
							}
						}
						// Look for the minimum length
						while (offset < pattern.Length && char.IsDigit(pattern[offset]))
						{
							// Seen digit
							if (formattingInfo.Min < 0)
							{
								formattingInfo.Min = 0;
							}

							formattingInfo.Min = (formattingInfo.Min * 10) + int.Parse(pattern[offset].ToString(), NumberFormatInfo.InvariantInfo);

							offset++;
						}
						// Look for the separator between min and max
						if (offset < pattern.Length)
						{
							if (pattern[offset] == '.')
							{
								// Seen separator
								offset++;
							}
						}
						// Look for the maximum length
						while (offset < pattern.Length && char.IsDigit(pattern[offset]))
						{
							// Seen digit
							if (formattingInfo.Max == int.MaxValue)
							{
								formattingInfo.Max = 0;
							}

							formattingInfo.Max = (formattingInfo.Max * 10) + int.Parse(pattern[offset].ToString(), NumberFormatInfo.InvariantInfo);

							offset++;
						}

						int remainingStringLength = pattern.Length - offset;

						// Look for pattern
						for(int m=0; m<matches.Length; m++)
						{
							string key = matches[m];

							if (key.Length <= remainingStringLength)
							{
								if (string.Compare(pattern, offset, key, 0, key.Length) == 0)
								{
									// Found match
									offset = offset + matches[m].Length;

									string option = null;

									// Look for option
									if (offset < pattern.Length)
									{
										if (pattern[offset] == '{')
										{
											// Seen option start
											offset++;
											
											int optEnd = pattern.IndexOf('}', offset);
											if (optEnd < 0)
											{
												// error
											}
											else
											{
												option = pattern.Substring(offset, optEnd - offset);
												offset = optEnd + 1;
											}
										}
									}

									ProcessConverter(matches[m], option, formattingInfo);
									break;
								}
							}
						}
					}
				}
			}
		}

		/// <summary>
		/// Process a parsed literal
		/// </summary>
		/// <param name="text">the literal text</param>
		private void ProcessLiteral(string text)
		{
			if (text.Length > 0)
			{
				// Convert into a pattern
				ProcessConverter("literal", text, new FormattingInfo());
			}
		}

		/// <summary>
		/// Process a parsed converter pattern
		/// </summary>
		/// <param name="converterName">the name of the converter</param>
		/// <param name="option">the optional option for the converter</param>
		/// <param name="formattingInfo">the formatting info for the converter</param>
		private void ProcessConverter(string converterName, string option, FormattingInfo formattingInfo)
		{
			LogLog.Debug(declaringType, "Converter ["+converterName+"] Option ["+option+"] Format [min="+formattingInfo.Min+",max="+formattingInfo.Max+",leftAlign="+formattingInfo.LeftAlign+"]");

			// Lookup the converter type
            ConverterInfo converterInfo = (ConverterInfo)m_patternConverters[converterName];
			if (converterInfo == null)
			{
				LogLog.Error(declaringType, "Unknown converter name ["+converterName+"] in conversion pattern.");
			}
			else
			{
				// Create the pattern converter
				PatternConverter pc = null;
				try
				{
                    pc = (PatternConverter)Activator.CreateInstance(converterInfo.Type);
				}
				catch(Exception createInstanceEx)
				{
                    LogLog.Error(declaringType, "Failed to create instance of Type [" + converterInfo.Type.FullName + "] using default constructor. Exception: " + createInstanceEx.ToString());
				}

				// formattingInfo variable is an instance variable, occasionally reset 
				// and used over and over again
				pc.FormattingInfo = formattingInfo;
				pc.Option = option;
                pc.Properties = converterInfo.Properties;

			    IOptionHandler optionHandler = pc as IOptionHandler;
				if (optionHandler != null)
				{
					optionHandler.ActivateOptions();
				}

				AddConverter(pc);
			}
		}

		/// <summary>
		/// Resets the internal state of the parser and adds the specified pattern converter 
		/// to the chain.
		/// </summary>
		/// <param name="pc">The pattern converter to add.</param>
		private void AddConverter(PatternConverter pc) 
		{
			// Add the pattern converter to the list.

			if (m_head == null) 
			{
				m_head = m_tail = pc;
			}
			else 
			{
				// Set the next converter on the tail
				// Update the tail reference
				// note that a converter may combine the 'next' into itself
				// and therefore the tail would not change!
				m_tail = m_tail.SetNext(pc);
			}
		}

		#endregion Protected Instance Methods

		#region Private Constants

		private const char ESCAPE_CHAR = '%';
  
		#endregion Private Constants

		#region Private Instance Fields

		/// <summary>
		/// The first pattern converter in the chain
		/// </summary>
		private PatternConverter m_head;

		/// <summary>
		///  the last pattern converter in the chain
		/// </summary>
		private PatternConverter m_tail;

		/// <summary>
		/// The pattern
		/// </summary>
		private string m_pattern;

		/// <summary>
		/// Internal map of converter identifiers to converter types
		/// </summary>
		/// <remarks>
		/// <para>
		/// This map overrides the static s_globalRulesRegistry map.
		/// </para>
		/// </remarks>
		private Hashtable m_patternConverters = new Hashtable();

		#endregion Private Instance Fields

	    #region Private Static Fields

	    /// <summary>
	    /// The fully qualified type of the PatternParser class.
	    /// </summary>
	    /// <remarks>
	    /// Used by the internal logger to record the Type of the
	    /// log message.
	    /// </remarks>
	    private readonly static Type declaringType = typeof(PatternParser);

	    #endregion Private Static Fields
	}
}
