#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.Text;
using System.Xml;
using System.Text.RegularExpressions;

namespace log4net.Util
{
	/// <summary>
	/// Utility class that represents a format string.
	/// </summary>
	/// <remarks>
	/// <para>
	/// Utility class that represents a format string.
	/// </para>
	/// </remarks>
	/// <author>Nicko Cadell</author>
	public sealed class SystemStringFormat
	{
		private readonly IFormatProvider m_provider;
		private readonly string m_format;
		private readonly object[] m_args;

		#region Constructor

		/// <summary>
		/// Initialise the <see cref="SystemStringFormat"/>
		/// </summary>
		/// <param name="provider">An <see cref="System.IFormatProvider"/> that supplies culture-specific formatting information.</param>
		/// <param name="format">A <see cref="System.String"/> containing zero or more format items.</param>
		/// <param name="args">An <see cref="System.Object"/> array containing zero or more objects to format.</param>
		public SystemStringFormat(IFormatProvider provider, string format, params object[] args)
		{
			m_provider = provider;
			m_format = format;
			m_args = args;
		}

		#endregion Constructor

		/// <summary>
		/// Format the string and arguments
		/// </summary>
		/// <returns>the formatted string</returns>
		public override string ToString()
		{
			return StringFormat(m_provider, m_format, m_args);
		}

		#region StringFormat

		/// <summary>
		/// Replaces the format item in a specified <see cref="System.String"/> with the text equivalent 
		/// of the value of a corresponding <see cref="System.Object"/> instance in a specified array.
		/// A specified parameter supplies culture-specific formatting information.
		/// </summary>
		/// <param name="provider">An <see cref="System.IFormatProvider"/> that supplies culture-specific formatting information.</param>
		/// <param name="format">A <see cref="System.String"/> containing zero or more format items.</param>
		/// <param name="args">An <see cref="System.Object"/> array containing zero or more objects to format.</param>
		/// <returns>
		/// A copy of format in which the format items have been replaced by the <see cref="System.String"/> 
		/// equivalent of the corresponding instances of <see cref="System.Object"/> in args.
		/// </returns>
		/// <remarks>
		/// <para>
		/// This method does not throw exceptions. If an exception thrown while formatting the result the
		/// exception and arguments are returned in the result string.
		/// </para>
		/// </remarks>
		private static string StringFormat(IFormatProvider provider, string format, params object[] args)
		{
			try
			{
				// The format is missing, log null value
				if (format == null)
				{
					return null;
				}

				// The args are missing - should not happen unless we are called explicitly with a null array
				if (args == null)
				{
					return format;
				}

				// Try to format the string
				return String.Format(provider, format, args);
			}
			catch(Exception ex)
			{
				log4net.Util.LogLog.Warn(declaringType, "Exception while rendering format ["+format+"]", ex);
				return StringFormatError(ex, format, args);
			}
#if !NET_2_0 && !MONO_2_0 && !MONO_3_5 && !MONO_4_0 && !NETSTANDARD1_3
			catch
			{
				log4net.Util.LogLog.Warn(declaringType, "Exception while rendering format ["+format+"]");
				return StringFormatError(null, format, args);
			}
#endif
		}

		/// <summary>
		/// Process an error during StringFormat
		/// </summary>
		private static string StringFormatError(Exception formatException, string format, object[] args)
		{
			try
			{
				StringBuilder buf = new StringBuilder("<log4net.Error>");

				if (formatException != null)
				{
					buf.Append("Exception during StringFormat: ").Append(formatException.Message);
				}
				else
				{
					buf.Append("Exception during StringFormat");
				}
				buf.Append(" <format>").Append(format).Append("</format>");
				buf.Append("<args>");
				RenderArray(args, buf);
				buf.Append("</args>");
				buf.Append("</log4net.Error>");

				return buf.ToString();
			}
			catch(Exception ex)
			{
				log4net.Util.LogLog.Error(declaringType, "INTERNAL ERROR during StringFormat error handling", ex);
				return "<log4net.Error>Exception during StringFormat. See Internal Log.</log4net.Error>";
			}
#if !NET_2_0 && !MONO_2_0 && !MONO_3_5 && !MONO_4_0 && !NETSTANDARD1_3
			catch
			{
				log4net.Util.LogLog.Error(declaringType, "INTERNAL ERROR during StringFormat error handling");
				return "<log4net.Error>Exception during StringFormat. See Internal Log.</log4net.Error>";
			}
#endif
		}

		/// <summary>
		/// Dump the contents of an array into a string builder
		/// </summary>
		private static void RenderArray(Array array, StringBuilder buffer)
		{
			if (array == null)
			{
				buffer.Append(SystemInfo.NullText);
			}
			else
			{
				if (array.Rank != 1)
				{
					buffer.Append(array.ToString());
				}
				else
				{
					buffer.Append("{");
					int len = array.Length;

					if (len > 0)
					{
						RenderObject(array.GetValue(0), buffer);
						for (int i = 1; i < len; i++)
						{
							buffer.Append(", ");
							RenderObject(array.GetValue(i), buffer);
						}
					}
					buffer.Append("}");
				}
			}
		}

		/// <summary>
		/// Dump an object to a string
		/// </summary>
		private static void RenderObject(Object obj, StringBuilder buffer)
		{
			if (obj == null)
			{
				buffer.Append(SystemInfo.NullText);
			}
			else
			{
				try
				{
					buffer.Append(obj);
				}
				catch(Exception ex)
				{
					buffer.Append("<Exception: ").Append(ex.Message).Append(">");
				}
#if !NET_2_0 && !MONO_2_0 && !MONO_3_5 && !MONO_4_0 && !NETSTANDARD1_3
				catch
				{
					buffer.Append("<Exception>");
				}
#endif
			}
		}

		#endregion StringFormat

	    #region Private Static Fields

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

	    #endregion Private Static Fields
	}
}
