#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 log4net.Core;
using log4net.Util;

namespace log4net.Layout
{
	/// <summary>
	/// Layout that formats the log events as XML elements.
	/// </summary>
	/// <remarks>
	/// <para>
	/// The output of the <see cref="XmlLayout" /> consists of a series of 
	/// log4net:event elements. It does not output a complete well-formed XML 
	/// file. The output is designed to be included as an <em>external entity</em>
	/// in a separate file to form a correct XML file.
	/// </para>
	/// <para>
	/// For example, if <c>abc</c> is the name of the file where
	/// the <see cref="XmlLayout" /> output goes, then a well-formed XML file would 
	/// be:
	/// </para>
	/// <code lang="XML">
	/// &lt;?xml version="1.0" ?&gt;
	/// 
	/// &lt;!DOCTYPE log4net:events SYSTEM "log4net-events.dtd" [&lt;!ENTITY data SYSTEM "abc"&gt;]&gt;
	///
	/// &lt;log4net:events version="1.2" xmlns:log4net="http://logging.apache.org/log4net/schemas/log4net-events-1.2&gt;
	///     &amp;data;
	/// &lt;/log4net:events&gt;
	/// </code>
	/// <para>
	/// This approach enforces the independence of the <see cref="XmlLayout" /> 
	/// and the appender where it is embedded.
	/// </para>
	/// <para>
	/// The <c>version</c> attribute helps components to correctly
	/// interpret output generated by <see cref="XmlLayout" />. The value of 
	/// this attribute should be "1.2" for release 1.2 and later.
	/// </para>
	/// <para>
	/// Alternatively the <c>Header</c> and <c>Footer</c> properties can be
	/// configured to output the correct XML header, open tag and close tag.
	/// When setting the <c>Header</c> and <c>Footer</c> properties it is essential
	/// that the underlying data store not be appendable otherwise the data
	/// will become invalid XML.
	/// </para>
	/// </remarks>
	/// <author>Nicko Cadell</author>
	/// <author>Gert Driesen</author>
	public class XmlLayout : XmlLayoutBase
	{
		#region Public Instance Constructors

		/// <summary>
		/// Constructs an XmlLayout
		/// </summary>
		public XmlLayout() : base()
		{
		}

		/// <summary>
		/// Constructs an XmlLayout.
		/// </summary>
		/// <remarks>
		/// <para>
		/// The <b>LocationInfo</b> option takes a boolean value. By
		/// default, it is set to false which means there will be no location
		/// information output by this layout. If the the option is set to
		/// true, then the file name and line number of the statement
		/// at the origin of the log statement will be output. 
		/// </para>
		/// <para>
		/// If you are embedding this layout within an SmtpAppender
		/// then make sure to set the <b>LocationInfo</b> option of that 
		/// appender as well.
		/// </para>
		/// </remarks>
		public XmlLayout(bool locationInfo) :  base(locationInfo)
		{
		}

		#endregion Public Instance Constructors

		#region Public Instance Properties

		/// <summary>
		/// The prefix to use for all element names
		/// </summary>
		/// <remarks>
		/// <para>
		/// The default prefix is <b>log4net</b>. Set this property
		/// to change the prefix. If the prefix is set to an empty string
		/// then no prefix will be written.
		/// </para>
		/// </remarks>
		public string Prefix
		{
			get { return m_prefix; }
			set { m_prefix = value; }
		}

		
		/// <summary>
		/// Set whether or not to base64 encode the message.
		/// </summary>
		/// <remarks>
		/// <para>
		/// By default the log message will be written as text to the xml
		/// output. This can cause problems when the message contains binary
		/// data. By setting this to true the contents of the message will be
		/// base64 encoded. If this is set then invalid character replacement
		/// (see <see cref="XmlLayoutBase.InvalidCharReplacement"/>) will not be performed
		/// on the log message.
		/// </para>
		/// </remarks>
		public bool Base64EncodeMessage
		{
			get {return m_base64Message;}
			set {m_base64Message=value;}
		}

		/// <summary>
		/// Set whether or not to base64 encode the property values.
		/// </summary>
		/// <remarks>
		/// <para>
		/// By default the properties will be written as text to the xml
		/// output. This can cause problems when one or more properties contain
		/// binary data. By setting this to true the values of the properties
		/// will be base64 encoded. If this is set then invalid character replacement
		/// (see <see cref="XmlLayoutBase.InvalidCharReplacement"/>) will not be performed
		/// on the property values.
		/// </para>
		/// </remarks>
		public bool Base64EncodeProperties
		{
			get {return m_base64Properties;}
			set {m_base64Properties=value;}
		}


		#endregion Public Instance Properties

		#region Implementation of IOptionHandler

		/// <summary>
		/// Initialize layout options
		/// </summary>
		/// <remarks>
		/// <para>
		/// This is part of the <see cref="IOptionHandler"/> delayed object
		/// activation scheme. The <see cref="ActivateOptions"/> method must 
		/// be called on this object after the configuration properties have
		/// been set. Until <see cref="ActivateOptions"/> is called this
		/// object is in an undefined state and must not be used. 
		/// </para>
		/// <para>
		/// If any of the configuration properties are modified then 
		/// <see cref="ActivateOptions"/> must be called again.
		/// </para>
		/// <para>
		/// Builds a cache of the element names
		/// </para>
		/// </remarks>
		override public void ActivateOptions() 
		{
			base.ActivateOptions();

			// Cache the full element names including the prefix
			if (m_prefix != null && m_prefix.Length > 0)
			{
				m_elmEvent = m_prefix + ":" + ELM_EVENT;
				m_elmMessage = m_prefix + ":" + ELM_MESSAGE;
				m_elmProperties = m_prefix + ":" + ELM_PROPERTIES;
				m_elmData = m_prefix + ":" + ELM_DATA;
				m_elmException = m_prefix + ":" + ELM_EXCEPTION;
				m_elmLocation = m_prefix + ":" + ELM_LOCATION;
			}
		}

		#endregion Implementation of IOptionHandler

		#region Override implementation of XMLLayoutBase

		/// <summary>
		/// Does the actual writing of the XML.
		/// </summary>
		/// <param name="writer">The writer to use to output the event to.</param>
		/// <param name="loggingEvent">The event to write.</param>
		/// <remarks>
		/// <para>
		/// Override the base class <see cref="XmlLayoutBase.FormatXml"/> method
		/// to write the <see cref="LoggingEvent"/> to the <see cref="XmlWriter"/>.
		/// </para>
		/// </remarks>
		override protected void FormatXml(XmlWriter writer, LoggingEvent loggingEvent)
		{
			writer.WriteStartElement(m_elmEvent);
			writer.WriteAttributeString(ATTR_LOGGER, loggingEvent.LoggerName);

#if NET_2_0 || NETCF_2_0 || MONO_2_0 || NETSTANDARD1_3
			writer.WriteAttributeString(ATTR_TIMESTAMP, XmlConvert.ToString(loggingEvent.TimeStamp, XmlDateTimeSerializationMode.Local));
#else
			writer.WriteAttributeString(ATTR_TIMESTAMP, XmlConvert.ToString(loggingEvent.TimeStamp));
#endif

			writer.WriteAttributeString(ATTR_LEVEL, loggingEvent.Level.DisplayName);
			writer.WriteAttributeString(ATTR_THREAD, loggingEvent.ThreadName);

			if (loggingEvent.Domain != null && loggingEvent.Domain.Length > 0)
			{
				writer.WriteAttributeString(ATTR_DOMAIN, loggingEvent.Domain);
			}
			if (loggingEvent.Identity != null && loggingEvent.Identity.Length > 0)
			{
				writer.WriteAttributeString(ATTR_IDENTITY, loggingEvent.Identity);
			}
			if (loggingEvent.UserName != null && loggingEvent.UserName.Length > 0)
			{
				writer.WriteAttributeString(ATTR_USERNAME, loggingEvent.UserName);
			}
    
			// Append the message text
			writer.WriteStartElement(m_elmMessage);
			if (!this.Base64EncodeMessage)
			{
				Transform.WriteEscapedXmlString(writer, loggingEvent.RenderedMessage, this.InvalidCharReplacement);
			}
			else
			{
				byte[] messageBytes = Encoding.UTF8.GetBytes(loggingEvent.RenderedMessage);
				string base64Message = Convert.ToBase64String(messageBytes, 0, messageBytes.Length);
				Transform.WriteEscapedXmlString(writer, base64Message,this.InvalidCharReplacement);
			}
			writer.WriteEndElement();

			PropertiesDictionary properties = loggingEvent.GetProperties();

			// Append the properties text
			if (properties.Count > 0)
			{
				writer.WriteStartElement(m_elmProperties);
				foreach(System.Collections.DictionaryEntry entry in properties)
				{
					writer.WriteStartElement(m_elmData);
					writer.WriteAttributeString(ATTR_NAME, Transform.MaskXmlInvalidCharacters((string)entry.Key,this.InvalidCharReplacement));

					// Use an ObjectRenderer to convert the object to a string
					string valueStr =null;
					if (!this.Base64EncodeProperties)
					{
						valueStr = Transform.MaskXmlInvalidCharacters(loggingEvent.Repository.RendererMap.FindAndRender(entry.Value),this.InvalidCharReplacement);
					}
					else
					{
						byte[] propertyValueBytes = Encoding.UTF8.GetBytes(loggingEvent.Repository.RendererMap.FindAndRender(entry.Value));
						valueStr = Convert.ToBase64String(propertyValueBytes, 0, propertyValueBytes.Length);
					}
					writer.WriteAttributeString(ATTR_VALUE, valueStr);

					writer.WriteEndElement();
				}
				writer.WriteEndElement();
			}

			string exceptionStr = loggingEvent.GetExceptionString();
			if (exceptionStr != null && exceptionStr.Length > 0)
			{
				// Append the stack trace line
				writer.WriteStartElement(m_elmException);
				Transform.WriteEscapedXmlString(writer, exceptionStr,this.InvalidCharReplacement);
				writer.WriteEndElement();
			}

			if (LocationInfo)
			{ 
				LocationInfo locationInfo = loggingEvent.LocationInformation;

				writer.WriteStartElement(m_elmLocation);
				writer.WriteAttributeString(ATTR_CLASS, locationInfo.ClassName);
				writer.WriteAttributeString(ATTR_METHOD, locationInfo.MethodName);
				writer.WriteAttributeString(ATTR_FILE, locationInfo.FileName);
				writer.WriteAttributeString(ATTR_LINE, locationInfo.LineNumber);
				writer.WriteEndElement();
			}

			writer.WriteEndElement();
		}

		#endregion Override implementation of XMLLayoutBase

		#region Private Instance Fields
  
		/// <summary>
		/// The prefix to use for all generated element names
		/// </summary>
		private string m_prefix = PREFIX;

		private string m_elmEvent = ELM_EVENT;
		private string m_elmMessage = ELM_MESSAGE;
		private string m_elmData = ELM_DATA;
		private string m_elmProperties = ELM_PROPERTIES;
		private string m_elmException = ELM_EXCEPTION;
		private string m_elmLocation = ELM_LOCATION;

		private bool m_base64Message=false;
		private bool m_base64Properties=false;

		#endregion Private Instance Fields

		#region Private Static Fields

		private const string PREFIX = "log4net";

		private const string ELM_EVENT = "event";
		private const string ELM_MESSAGE = "message";
		private const string ELM_PROPERTIES = "properties";
		private const string ELM_GLOBAL_PROPERTIES = "global-properties";
		private const string ELM_DATA = "data";
		private const string ELM_EXCEPTION = "exception";
		private const string ELM_LOCATION = "locationInfo";

		private const string ATTR_LOGGER = "logger";
		private const string ATTR_TIMESTAMP = "timestamp";
		private const string ATTR_LEVEL = "level";
		private const string ATTR_THREAD = "thread";
		private const string ATTR_DOMAIN = "domain";
		private const string ATTR_IDENTITY = "identity";
		private const string ATTR_USERNAME = "username";
		private const string ATTR_CLASS = "class";
		private const string ATTR_METHOD = "method";
		private const string ATTR_FILE = "file";
		private const string ATTR_LINE = "line";
		private const string ATTR_NAME = "name";
		private const string ATTR_VALUE = "value";


		#endregion Private Static Fields
	}
}

