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

namespace log4net.Repository.Hierarchy
{
	/// <summary>
	/// Implementation of <see cref="ILogger"/> used by <see cref="Hierarchy"/>
	/// </summary>
	/// <remarks>
	/// <para>
	/// Internal class used to provide implementation of <see cref="ILogger"/>
	/// interface. Applications should use <see cref="LogManager"/> to get
	/// logger instances.
	/// </para>
	/// <para>
	/// This is one of the central classes in the log4net implementation. One of the
	/// distinctive features of log4net are hierarchical loggers and their
	/// evaluation. The <see cref="Hierarchy"/> organizes the <see cref="Logger"/>
	/// instances into a rooted tree hierarchy.
	/// </para>
	/// <para>
	/// The <see cref="Logger"/> class is abstract. Only concrete subclasses of
	/// <see cref="Logger"/> can be created. The <see cref="ILoggerFactory"/>
	/// is used to create instances of this type for the <see cref="Hierarchy"/>.
	/// </para>
	/// </remarks>
	/// <author>Nicko Cadell</author>
	/// <author>Gert Driesen</author>
	/// <author>Aspi Havewala</author>
	/// <author>Douglas de la Torre</author>
	public abstract class Logger : IAppenderAttachable, ILogger
	{
		#region Protected Instance Constructors

		/// <summary>
		/// This constructor created a new <see cref="Logger" /> instance and
		/// sets its name.
		/// </summary>
		/// <param name="name">The name of the <see cref="Logger" />.</param>
		/// <remarks>
		/// <para>
		/// This constructor is protected and designed to be used by
		/// a subclass that is not abstract.
		/// </para>
		/// <para>
		/// Loggers are constructed by <see cref="ILoggerFactory"/> 
		/// objects. See <see cref="DefaultLoggerFactory"/> for the default
		/// logger creator.
		/// </para>
		/// </remarks>
		protected Logger(string name) 
		{
#if NETCF || NETSTANDARD1_3
			// NETCF: String.Intern causes Native Exception
			m_name = name;
#else
			m_name = string.Intern(name);
#endif
		}

		#endregion Protected Instance Constructors

		#region Public Instance Properties

		/// <summary>
		/// Gets or sets the parent logger in the hierarchy.
		/// </summary>
		/// <value>
		/// The parent logger in the hierarchy.
		/// </value>
		/// <remarks>
		/// <para>
		/// Part of the Composite pattern that makes the hierarchy.
		/// The hierarchy is parent linked rather than child linked.
		/// </para>
		/// </remarks>
		virtual public Logger Parent
		{
			get { return m_parent; }
			set { m_parent = value; }
		}

		/// <summary>
		/// Gets or sets a value indicating if child loggers inherit their parent's appenders.
		/// </summary>
		/// <value>
		/// <c>true</c> if child loggers inherit their parent's appenders.
		/// </value>
		/// <remarks>
		/// <para>
		/// Additivity is set to <c>true</c> by default, that is children inherit
		/// the appenders of their ancestors by default. If this variable is
		/// set to <c>false</c> then the appenders found in the
		/// ancestors of this logger are not used. However, the children
		/// of this logger will inherit its appenders, unless the children
		/// have their additivity flag set to <c>false</c> too. See
		/// the user manual for more details.
		/// </para>
		/// </remarks>
		virtual public bool Additivity
		{
			get { return m_additive; }
			set { m_additive = value; }
		}

		/// <summary>
		/// Gets the effective level for this logger.
		/// </summary>
		/// <returns>The nearest level in the logger hierarchy.</returns>
		/// <remarks>
		/// <para>
		/// Starting from this logger, searches the logger hierarchy for a
		/// non-null level and returns it. Otherwise, returns the level of the
		/// root logger.
		/// </para>
		/// <para>The Logger class is designed so that this method executes as
		/// quickly as possible.</para>
		/// </remarks>
		virtual public Level EffectiveLevel
		{
			get 
			{
				for(Logger c = this; c != null; c = c.m_parent) 
				{
					Level level = c.m_level;

					// Casting level to Object for performance, otherwise the overloaded operator is called
					if ((object)level != null) 
					{
						return level;
					}
				}
				return null; // If reached will cause an NullPointerException.
			}
		}

		/// <summary>
		/// Gets or sets the <see cref="Hierarchy"/> where this 
		/// <c>Logger</c> instance is attached to.
		/// </summary>
		/// <value>The hierarchy that this logger belongs to.</value>
		/// <remarks>
		/// <para>
		/// This logger must be attached to a single <see cref="Hierarchy"/>.
		/// </para>
		/// </remarks>
		virtual public Hierarchy Hierarchy
		{
			get { return m_hierarchy; }
			set { m_hierarchy = value; }
		}

		/// <summary>
		/// Gets or sets the assigned <see cref="Level"/>, if any, for this Logger.  
		/// </summary>
		/// <value>
		/// The <see cref="Level"/> of this logger.
		/// </value>
		/// <remarks>
		/// <para>
		/// The assigned <see cref="Level"/> can be <c>null</c>.
		/// </para>
		/// </remarks>
		virtual public Level Level
		{
			get { return m_level; }
			set { m_level = value; }
		}

		#endregion Public Instance Properties

		#region Implementation of IAppenderAttachable

		/// <summary>
		/// Add <paramref name="newAppender"/> to the list of appenders of this
		/// Logger instance.
		/// </summary>
		/// <param name="newAppender">An appender to add to this logger</param>
		/// <remarks>
		/// <para>
		/// Add <paramref name="newAppender"/> to the list of appenders of this
		/// Logger instance.
		/// </para>
		/// <para>
		/// If <paramref name="newAppender"/> is already in the list of
		/// appenders, then it won't be added again.
		/// </para>
		/// </remarks>
		virtual public void AddAppender(IAppender newAppender) 
		{
			if (newAppender == null)
			{
				throw new ArgumentNullException("newAppender");
			}

			m_appenderLock.AcquireWriterLock();
			try
			{
				if (m_appenderAttachedImpl == null) 
				{
					m_appenderAttachedImpl = new log4net.Util.AppenderAttachedImpl();
				}
				m_appenderAttachedImpl.AddAppender(newAppender);
			}
			finally
			{
				m_appenderLock.ReleaseWriterLock();
			}
		}

		/// <summary>
		/// Get the appenders contained in this logger as an 
		/// <see cref="System.Collections.ICollection"/>.
		/// </summary>
		/// <returns>A collection of the appenders in this logger</returns>
		/// <remarks>
		/// <para>
		/// Get the appenders contained in this logger as an 
		/// <see cref="System.Collections.ICollection"/>. If no appenders 
		/// can be found, then a <see cref="EmptyCollection"/> is returned.
		/// </para>
		/// </remarks>
		virtual public AppenderCollection Appenders 
		{
			get
			{
				m_appenderLock.AcquireReaderLock();
				try
				{
					if (m_appenderAttachedImpl == null)
					{
						return AppenderCollection.EmptyCollection;
					}
					else 
					{
						return m_appenderAttachedImpl.Appenders;
					}
				}
				finally
				{
					m_appenderLock.ReleaseReaderLock();
				}
			}
		}

		/// <summary>
		/// Look for the appender named as <c>name</c>
		/// </summary>
		/// <param name="name">The name of the appender to lookup</param>
		/// <returns>The appender with the name specified, or <c>null</c>.</returns>
		/// <remarks>
		/// <para>
		/// Returns the named appender, or null if the appender is not found.
		/// </para>
		/// </remarks>
		virtual public IAppender GetAppender(string name) 
		{
			m_appenderLock.AcquireReaderLock();
			try
			{
				if (m_appenderAttachedImpl == null || name == null)
				{
					return null;
				}

				return m_appenderAttachedImpl.GetAppender(name);
			}
			finally
			{
				m_appenderLock.ReleaseReaderLock();
			}
		}

		/// <summary>
		/// Remove all previously added appenders from this Logger instance.
		/// </summary>
		/// <remarks>
		/// <para>
		/// Remove all previously added appenders from this Logger instance.
		/// </para>
		/// <para>
		/// This is useful when re-reading configuration information.
		/// </para>
		/// </remarks>
		virtual public void RemoveAllAppenders() 
		{
			m_appenderLock.AcquireWriterLock();
			try
			{
				if (m_appenderAttachedImpl != null) 
				{
					m_appenderAttachedImpl.RemoveAllAppenders();
					m_appenderAttachedImpl = null;
				}
			}
			finally
			{
				m_appenderLock.ReleaseWriterLock();
			}
		}

		/// <summary>
		/// Remove the appender passed as parameter form the list of appenders.
		/// </summary>
		/// <param name="appender">The appender to remove</param>
		/// <returns>The appender removed from the list</returns>
		/// <remarks>
		/// <para>
		/// Remove the appender passed as parameter form the list of appenders.
		/// The appender removed is not closed.
		/// If you are discarding the appender you must call
		/// <see cref="IAppender.Close"/> on the appender removed.
		/// </para>
		/// </remarks>
		virtual public IAppender RemoveAppender(IAppender appender) 
		{
			m_appenderLock.AcquireWriterLock();
			try
			{
				if (appender != null && m_appenderAttachedImpl != null) 
				{
					return m_appenderAttachedImpl.RemoveAppender(appender);
				}
			}
			finally
			{
				m_appenderLock.ReleaseWriterLock();
			}
			return null;
		}

		/// <summary>
		/// Remove the appender passed as parameter form the list of appenders.
		/// </summary>
		/// <param name="name">The name of the appender to remove</param>
		/// <returns>The appender removed from the list</returns>
		/// <remarks>
		/// <para>
		/// Remove the named appender passed as parameter form the list of appenders.
		/// The appender removed is not closed.
		/// If you are discarding the appender you must call
		/// <see cref="IAppender.Close"/> on the appender removed.
		/// </para>
		/// </remarks>
		virtual public IAppender RemoveAppender(string name) 
		{
			m_appenderLock.AcquireWriterLock();
			try
			{
				if (name != null && m_appenderAttachedImpl != null)
				{
					return m_appenderAttachedImpl.RemoveAppender(name);
				}
			}
			finally
			{
				m_appenderLock.ReleaseWriterLock();
			}
			return null;
		}
  
		#endregion

		#region Implementation of ILogger

		/// <summary>
		/// Gets the logger name.
		/// </summary>
		/// <value>
		/// The name of the logger.
		/// </value>
		/// <remarks>
		/// <para>
		/// The name of this logger
		/// </para>
		/// </remarks>
		virtual public string Name
		{
			get { return m_name; }
		}

		/// <summary>
		/// This generic form is intended to be used by wrappers.
		/// </summary>
		/// <param name="callerStackBoundaryDeclaringType">The declaring type of the method that is
		/// the stack boundary into the logging system for this call.</param>
		/// <param name="level">The level of the message to be logged.</param>
		/// <param name="message">The message object to log.</param>
		/// <param name="exception">The exception to log, including its stack trace.</param>
		/// <remarks>
		/// <para>
		/// Generate a logging event for the specified <paramref name="level"/> using
		/// the <paramref name="message"/> and <paramref name="exception"/>.
		/// </para>
		/// <para>
		/// This method must not throw any exception to the caller.
		/// </para>
		/// </remarks>
		virtual public void Log(Type callerStackBoundaryDeclaringType, Level level, object message, Exception exception) 
		{
			try
			{
				if (IsEnabledFor(level))
				{
                    ForcedLog((callerStackBoundaryDeclaringType != null) ? callerStackBoundaryDeclaringType : declaringType, level, message, exception);
				}
			}
			catch (Exception ex)
			{
				log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex);
			}
#if !NET_2_0 && !MONO_2_0 && !MONO_3_5 && !MONO_4_0 && !NETSTANDARD1_3
			catch
			{
				log4net.Util.LogLog.Error(declaringType, "Exception while logging");
			}
#endif
		}

		/// <summary>
		/// This is the most generic printing method that is intended to be used 
		/// by wrappers.
		/// </summary>
		/// <param name="logEvent">The event being logged.</param>
		/// <remarks>
		/// <para>
		/// Logs the specified logging event through this logger.
		/// </para>
		/// <para>
		/// This method must not throw any exception to the caller.
		/// </para>
		/// </remarks>
		virtual public void Log(LoggingEvent logEvent)
		{
			try
			{
				if (logEvent != null)
				{
					if (IsEnabledFor(logEvent.Level))
					{
						ForcedLog(logEvent);
					}
				}
			}
			catch (Exception ex)
			{
				log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex);
			}
#if !NET_2_0 && !MONO_2_0 && !MONO_3_5 && !MONO_4_0 && !NETSTANDARD1_3
			catch
			{
				log4net.Util.LogLog.Error(declaringType, "Exception while logging");
			}
#endif
		}

		/// <summary>
		/// Checks if this logger is enabled for a given <see cref="Level"/> passed as parameter.
		/// </summary>
		/// <param name="level">The level to check.</param>
		/// <returns>
		/// <c>true</c> if this logger is enabled for <c>level</c>, otherwise <c>false</c>.
		/// </returns>
		/// <remarks>
		/// <para>
		/// Test if this logger is going to log events of the specified <paramref name="level"/>.
		/// </para>
		/// <para>
		/// This method must not throw any exception to the caller.
		/// </para>
		/// </remarks>
		virtual public bool IsEnabledFor(Level level)
		{
			try
			{
				if (level != null)
				{
					if (m_hierarchy.IsDisabled(level))
					{
						return false;
					}
					return level >= this.EffectiveLevel;
				}
			}
			catch (Exception ex)
			{
				log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex);
			}
#if !NET_2_0 && !MONO_2_0 && !MONO_3_5 && !MONO_4_0 && !NETSTANDARD1_3
			catch
			{
				log4net.Util.LogLog.Error(declaringType, "Exception while logging");
			}
#endif
			return false;
		}

		/// <summary>
		/// Gets the <see cref="ILoggerRepository"/> where this 
		/// <c>Logger</c> instance is attached to.
		/// </summary>
		/// <value>
		/// The <see cref="ILoggerRepository" /> that this logger belongs to.
		/// </value>
		/// <remarks>
		/// <para>
		/// Gets the <see cref="ILoggerRepository"/> where this 
		/// <c>Logger</c> instance is attached to.
		/// </para>
		/// </remarks>
		public ILoggerRepository Repository
		{ 
			get { return m_hierarchy; }
		}

  		#endregion Implementation of ILogger

		/// <summary>
		/// Deliver the <see cref="LoggingEvent"/> to the attached appenders.
		/// </summary>
		/// <param name="loggingEvent">The event to log.</param>
		/// <remarks>
		/// <para>
		/// Call the appenders in the hierarchy starting at
		/// <c>this</c>. If no appenders could be found, emit a
		/// warning.
		/// </para>
		/// <para>
		/// This method calls all the appenders inherited from the
		/// hierarchy circumventing any evaluation of whether to log or not
		/// to log the particular log request.
		/// </para>
		/// </remarks>
		virtual protected void CallAppenders(LoggingEvent loggingEvent) 
		{
			if (loggingEvent == null)
			{
				throw new ArgumentNullException("loggingEvent");
			}

			int writes = 0;

			for(Logger c=this; c != null; c=c.m_parent) 
			{
				if (c.m_appenderAttachedImpl != null) 
				{
					// Protected against simultaneous call to addAppender, removeAppender,...
					c.m_appenderLock.AcquireReaderLock();
					try
					{
						if (c.m_appenderAttachedImpl != null) 
						{
							writes += c.m_appenderAttachedImpl.AppendLoopOnAppenders(loggingEvent);
						}
					}
					finally
					{
						c.m_appenderLock.ReleaseReaderLock();
					}
				}

				if (!c.m_additive) 
				{
					break;
				}
			}
			
			// No appenders in hierarchy, warn user only once.
			//
			// Note that by including the AppDomain values for the currently running
			// thread, it becomes much easier to see which application the warning
			// is from, which is especially helpful in a multi-AppDomain environment
			// (like IIS with multiple VDIRS).  Without this, it can be difficult
			// or impossible to determine which .config file is missing appender
			// definitions.
			//
			if (!m_hierarchy.EmittedNoAppenderWarning && writes == 0) 
			{
				m_hierarchy.EmittedNoAppenderWarning = true;
				LogLog.Debug(declaringType, "No appenders could be found for logger [" + Name + "] repository [" + Repository.Name + "]");
				LogLog.Debug(declaringType, "Please initialize the log4net system properly.");
				try
				{
					LogLog.Debug(declaringType, "    Current AppDomain context information: ");
					LogLog.Debug(declaringType, "       BaseDirectory   : " + SystemInfo.ApplicationBaseDirectory);
#if !(NETCF || NETSTANDARD1_3)
					LogLog.Debug(declaringType, "       FriendlyName    : " + AppDomain.CurrentDomain.FriendlyName);
					LogLog.Debug(declaringType, "       DynamicDirectory: " + AppDomain.CurrentDomain.DynamicDirectory);
#endif
				}
				catch(System.Security.SecurityException)
				{
					// Insufficient permissions to display info from the AppDomain
				}
			}
		}

		/// <summary>
		/// Closes all attached appenders implementing the <see cref="IAppenderAttachable"/> interface.
		/// </summary>
		/// <remarks>
		/// <para>
		/// Used to ensure that the appenders are correctly shutdown.
		/// </para>
		/// </remarks>
		virtual public void CloseNestedAppenders() 
		{
			m_appenderLock.AcquireWriterLock();
			try
			{
				if (m_appenderAttachedImpl != null)
				{
					AppenderCollection appenders = m_appenderAttachedImpl.Appenders;
					foreach(IAppender appender in appenders)
					{
						if (appender is IAppenderAttachable)
						{
							appender.Close();
						}
					}
				}
			}
			finally
			{
				m_appenderLock.ReleaseWriterLock();
			}
		}

		/// <summary>
		/// This is the most generic printing method. This generic form is intended to be used by wrappers
		/// </summary>
		/// <param name="level">The level of the message to be logged.</param>
		/// <param name="message">The message object to log.</param>
		/// <param name="exception">The exception to log, including its stack trace.</param>
		/// <remarks>
		/// <para>
		/// Generate a logging event for the specified <paramref name="level"/> using
		/// the <paramref name="message"/>.
		/// </para>
		/// </remarks>
		virtual public void Log(Level level, object message, Exception exception) 
		{
			if (IsEnabledFor(level))
			{
                ForcedLog(declaringType, level, message, exception);
			}
		}

		/// <summary>
		/// Creates a new logging event and logs the event without further checks.
		/// </summary>
		/// <param name="callerStackBoundaryDeclaringType">The declaring type of the method that is
		/// the stack boundary into the logging system for this call.</param>
		/// <param name="level">The level of the message to be logged.</param>
		/// <param name="message">The message object to log.</param>
		/// <param name="exception">The exception to log, including its stack trace.</param>
		/// <remarks>
		/// <para>
		/// Generates a logging event and delivers it to the attached
		/// appenders.
		/// </para>
		/// </remarks>
		virtual protected void ForcedLog(Type callerStackBoundaryDeclaringType, Level level, object message, Exception exception) 
		{
			CallAppenders(new LoggingEvent(callerStackBoundaryDeclaringType, this.Hierarchy, this.Name, level, message, exception));
		}

		/// <summary>
		/// Creates a new logging event and logs the event without further checks.
		/// </summary>
		/// <param name="logEvent">The event being logged.</param>
		/// <remarks>
		/// <para>
		/// Delivers the logging event to the attached appenders.
		/// </para>
		/// </remarks>
		virtual protected void ForcedLog(LoggingEvent logEvent) 
		{
			// The logging event may not have been created by this logger
			// the Repository may not be correctly set on the event. This
			// is required for the appenders to correctly lookup renderers etc...
			logEvent.EnsureRepository(this.Hierarchy);

			CallAppenders(logEvent);
		}

		#region Private Static Fields

        /// <summary>
        /// The fully qualified type of the Logger class.
        /// </summary>
        private readonly static Type declaringType = typeof(Logger);

		#endregion Private Static Fields

		#region Private Instance Fields

		/// <summary>
		/// The name of this logger.
		/// </summary>
		private readonly string m_name;  

		/// <summary>
		/// The assigned level of this logger. 
		/// </summary>
		/// <remarks>
		/// <para>
		/// The <c>level</c> variable need not be 
		/// assigned a value in which case it is inherited 
		/// form the hierarchy.
		/// </para>
		/// </remarks>
		private Level m_level;

		/// <summary>
		/// The parent of this logger.
		/// </summary>
		/// <remarks>
		/// <para>
		/// The parent of this logger. 
		/// All loggers have at least one ancestor which is the root logger.
		/// </para>
		/// </remarks>
		private Logger m_parent;

		/// <summary>
		/// Loggers need to know what Hierarchy they are in.
		/// </summary>
		/// <remarks>
		/// <para>
		/// Loggers need to know what Hierarchy they are in.
		/// The hierarchy that this logger is a member of is stored
		/// here.
		/// </para>
		/// </remarks>
		private Hierarchy m_hierarchy;

		/// <summary>
		/// Helper implementation of the <see cref="IAppenderAttachable"/> interface
		/// </summary>
		private log4net.Util.AppenderAttachedImpl m_appenderAttachedImpl;

		/// <summary>
		/// Flag indicating if child loggers inherit their parents appenders
		/// </summary>
		/// <remarks>
		/// <para>
		/// Additivity is set to true by default, that is children inherit
		/// the appenders of their ancestors by default. If this variable is
		/// set to <c>false</c> then the appenders found in the
		/// ancestors of this logger are not used. However, the children
		/// of this logger will inherit its appenders, unless the children
		/// have their additivity flag set to <c>false</c> too. See
		/// the user manual for more details.
		/// </para>
		/// </remarks>
		private bool m_additive = true;

		/// <summary>
		/// Lock to protect AppenderAttachedImpl variable m_appenderAttachedImpl
		/// </summary>
		private readonly ReaderWriterLock m_appenderLock = new ReaderWriterLock();
  
		#endregion
	}
}
