#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 System.Net;
using System.Net.Sockets;
using System.Text;
using System.IO;
using System.Threading;
#if NETSTANDARD1_3
using System.Threading.Tasks;
#endif
using log4net.Layout;
using log4net.Core;
using log4net.Util;

namespace log4net.Appender 
{
	/// <summary>
	/// Appender that allows clients to connect via Telnet to receive log messages
	/// </summary>
	/// <remarks>	
	/// <para>
	/// The TelnetAppender accepts socket connections and streams logging messages
	/// back to the client.  
	/// The output is provided in a telnet-friendly way so that a log can be monitored 
	/// over a TCP/IP socket.
	/// This allows simple remote monitoring of application logging.
	/// </para>
	/// <para>
	/// The default <see cref="Port"/> is 23 (the telnet port).
	/// </para>
	/// </remarks>
	/// <author>Keith Long</author>
	/// <author>Nicko Cadell</author>
	public class TelnetAppender : AppenderSkeleton 
	{
		private SocketHandler m_handler;
		private int m_listeningPort = 23;

		#region Constructor

		/// <summary>
		/// Default constructor
		/// </summary>
		/// <remarks>
		/// <para>
		/// Default constructor
		/// </para>
		/// </remarks>
		public TelnetAppender()
		{
		}

		#endregion

	    #region Private Static Fields

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

	    #endregion Private Static Fields

		/// <summary>
		/// Gets or sets the TCP port number on which this <see cref="TelnetAppender"/> will listen for connections.
		/// </summary>
		/// <value>
		/// An integer value in the range <see cref="IPEndPoint.MinPort" /> to <see cref="IPEndPoint.MaxPort" /> 
		/// indicating the TCP port number on which this <see cref="TelnetAppender"/> will listen for connections.
		/// </value>
		/// <remarks>
		/// <para>
		/// The default value is 23 (the telnet port).
		/// </para>
		/// </remarks>
		/// <exception cref="ArgumentOutOfRangeException">The value specified is less than <see cref="IPEndPoint.MinPort" /> 
		/// or greater than <see cref="IPEndPoint.MaxPort" />.</exception>
		public int Port
		{
			get
			{
				return m_listeningPort;
			}
			set
			{
				if (value < IPEndPoint.MinPort || value > IPEndPoint.MaxPort)
				{
					throw log4net.Util.SystemInfo.CreateArgumentOutOfRangeException("value", (object)value,
						"The value specified for Port is less than " + 
						IPEndPoint.MinPort.ToString(NumberFormatInfo.InvariantInfo) + 
						" or greater than " + 
						IPEndPoint.MaxPort.ToString(NumberFormatInfo.InvariantInfo) + ".");
				}
				else
				{
					m_listeningPort = value;
				}
			}
		}

		#region Override implementation of AppenderSkeleton

		/// <summary>
		/// Overrides the parent method to close the socket handler
		/// </summary>
		/// <remarks>
		/// <para>
		/// Closes all the outstanding connections.
		/// </para>
		/// </remarks>
		protected override void OnClose()  
		{
			base.OnClose();

			if (m_handler != null)
			{
				m_handler.Dispose();
				m_handler = null;
			}
		}

		/// <summary>
		/// This appender requires a <see cref="Layout"/> to be set.
		/// </summary>
		/// <value><c>true</c></value>
		/// <remarks>
		/// <para>
		/// This appender requires a <see cref="Layout"/> to be set.
		/// </para>
		/// </remarks>
		protected override bool RequiresLayout
		{
			get { return true; }
		}

		/// <summary>
		/// Initialize the appender based on the options set.
		/// </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>
		/// Create the socket handler and wait for connections
		/// </para>
		/// </remarks>
		public override void ActivateOptions() 
		{
			base.ActivateOptions();
			try 
			{
				LogLog.Debug(declaringType, "Creating SocketHandler to listen on port ["+m_listeningPort+"]");
				m_handler = new SocketHandler(m_listeningPort);
			}
			catch(Exception ex) 
			{
				LogLog.Error(declaringType, "Failed to create SocketHandler", ex);
				throw;
			}
		}

		/// <summary>
		/// Writes the logging event to each connected client.
		/// </summary>
		/// <param name="loggingEvent">The event to log.</param>
		/// <remarks>
		/// <para>
		/// Writes the logging event to each connected client.
		/// </para>
		/// </remarks>
		protected override void Append(LoggingEvent loggingEvent) 
		{
			if (m_handler != null && m_handler.HasConnections)
			{
				m_handler.Send(RenderLoggingEvent(loggingEvent));
			}
		}

		#endregion

		#region SocketHandler helper class

		/// <summary>
		/// Helper class to manage connected clients
		/// </summary>
		/// <remarks>
		/// <para>
		/// The SocketHandler class is used to accept connections from
		/// clients.  It is threaded so that clients can connect/disconnect
		/// asynchronously.
		/// </para>
		/// </remarks>
		protected class SocketHandler : IDisposable
		{			
			private const int MAX_CONNECTIONS = 20;

			private Socket m_serverSocket;
			private ArrayList m_clients = new ArrayList();

			/// <summary>
			/// Class that represents a client connected to this handler
			/// </summary>
			/// <remarks>
			/// <para>
			/// Class that represents a client connected to this handler
			/// </para>
			/// </remarks>
			protected class SocketClient : IDisposable
			{
				private Socket m_socket;
				private StreamWriter m_writer;

				/// <summary>
				/// Create this <see cref="SocketClient"/> for the specified <see cref="Socket"/>
				/// </summary>
				/// <param name="socket">the client's socket</param>
				/// <remarks>
				/// <para>
				/// Opens a stream writer on the socket.
				/// </para>
				/// </remarks>
				public SocketClient(Socket socket)
				{
					m_socket = socket;

					try
					{
						m_writer = new StreamWriter(new NetworkStream(socket));
					}
					catch
					{
						Dispose();
						throw;
					}
				}

				/// <summary>
				/// Write a string to the client
				/// </summary>
				/// <param name="message">string to send</param>
				/// <remarks>
				/// <para>
				/// Write a string to the client
				/// </para>
				/// </remarks>
				public void Send(String message)
				{
					m_writer.Write(message);
					m_writer.Flush();
				}

				#region IDisposable Members

				/// <summary>
				/// Cleanup the clients connection
				/// </summary>
				/// <remarks>
				/// <para>
				/// Close the socket connection.
				/// </para>
				/// </remarks>
				public void Dispose()
				{
					try
					{
						if (m_writer != null)
						{
							m_writer.Close();
							m_writer = null;
						}
					}
					catch { }

					if (m_socket != null)
					{
						try
						{
							m_socket.Shutdown(SocketShutdown.Both);
						}
						catch { }

						try
						{
							m_socket.Close();
						}
						catch { }

						m_socket = null;
					}
				}

				#endregion
			}
		
			/// <summary>
			/// Opens a new server port on <paramref ref="port"/>
			/// </summary>
			/// <param name="port">the local port to listen on for connections</param>
			/// <remarks>
			/// <para>
			/// Creates a socket handler on the specified local server port.
			/// </para>
			/// </remarks>
			public SocketHandler(int port)
			{
				m_serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

				m_serverSocket.Bind(new IPEndPoint(IPAddress.Any, port));
				m_serverSocket.Listen(5);
				AcceptConnection();
			}

			private void AcceptConnection()
			{
#if NETSTANDARD1_3
				m_serverSocket.AcceptAsync().ContinueWith(OnConnect, TaskScheduler.Default);
#else
				m_serverSocket.BeginAccept(new AsyncCallback(OnConnect), null);
#endif
			}

			/// <summary>
			/// Sends a string message to each of the connected clients
			/// </summary>
			/// <param name="message">the text to send</param>
			/// <remarks>
			/// <para>
			/// Sends a string message to each of the connected clients
			/// </para>
			/// </remarks>
			public void Send(String message)
			{
				ArrayList localClients = m_clients;

				foreach (SocketClient client in localClients)
				{
					try
					{
						client.Send(message);
					}
					catch (Exception)
					{
						// The client has closed the connection, remove it from our list
						client.Dispose();
						RemoveClient(client);
					}
				}
			}

			/// <summary>
			/// Add a client to the internal clients list
			/// </summary>
			/// <param name="client">client to add</param>
			private void AddClient(SocketClient client)
			{
				lock(this)
				{
					ArrayList clientsCopy = (ArrayList)m_clients.Clone();
					clientsCopy.Add(client);
					m_clients = clientsCopy;
				}
			}

			/// <summary>
			/// Remove a client from the internal clients list
			/// </summary>
			/// <param name="client">client to remove</param>
			private void RemoveClient(SocketClient client)
			{
				lock(this)
				{
					ArrayList clientsCopy = (ArrayList)m_clients.Clone();
					clientsCopy.Remove(client);
					m_clients = clientsCopy;
				}
			}

			/// <summary>
			/// Test if this handler has active connections
			/// </summary>
			/// <value>
			/// <c>true</c> if this handler has active connections
			/// </value>
			/// <remarks>
			/// <para>
			/// This property will be <c>true</c> while this handler has
			/// active connections, that is at least one connection that 
			/// the handler will attempt to send a message to.
			/// </para>
			/// </remarks>
			public bool HasConnections
			{
				get
				{
					ArrayList localClients = m_clients;

					return (localClients != null && localClients.Count > 0);
				}
			}
			

#if NETSTANDARD1_3
			private void OnConnect(Task<Socket> acceptTask)
#else
			/// <summary>
			/// Callback used to accept a connection on the server socket
			/// </summary>
			/// <param name="asyncResult">The result of the asynchronous operation</param>
			/// <remarks>
			/// <para>
			/// On connection adds to the list of connections 
			/// if there are two many open connections you will be disconnected
			/// </para>
			/// </remarks>
			private void OnConnect(IAsyncResult asyncResult)
#endif
			{
				try
				{
#if NETSTANDARD1_3
					Socket socket = acceptTask.GetAwaiter().GetResult();
#else
					// Block until a client connects
					Socket socket = m_serverSocket.EndAccept(asyncResult);
#endif
					LogLog.Debug(declaringType, "Accepting connection from ["+socket.RemoteEndPoint.ToString()+"]");
					SocketClient client = new SocketClient(socket);

					int currentActiveConnectionsCount = m_clients.Count;
					if (currentActiveConnectionsCount < MAX_CONNECTIONS) 
					{
						try
						{
							client.Send("TelnetAppender v1.0 (" + (currentActiveConnectionsCount + 1) + " active connections)\r\n\r\n");
							AddClient(client);
						}
						catch
						{
							client.Dispose();
						}
					}
					else 
					{
						client.Send("Sorry - Too many connections.\r\n");
						client.Dispose();
					}
				}
				catch
				{
				}
				finally
				{
					if (m_serverSocket != null)
					{
						AcceptConnection();
					}
				}
			}

			#region IDisposable Members

			/// <summary>
			/// Close all network connections
			/// </summary>
			/// <remarks>
			/// <para>
			/// Make sure we close all network connections
			/// </para>
			/// </remarks>
			public void Dispose()
			{
				ArrayList localClients = m_clients;

				foreach (SocketClient client in localClients)
				{
					client.Dispose();
				}
				m_clients.Clear();

				Socket localSocket = m_serverSocket;
				m_serverSocket = null;
				try 
				{
					localSocket.Shutdown(SocketShutdown.Both);
				} 
				catch 
				{ 
				}

				try
				{
					localSocket.Close();
				}
				catch 
				{ 
				}			
			}

			#endregion
		}

		#endregion
	}
}
