#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
	}
}
