using System;
using System.Collections.Generic;
using System.Diagnostics;

namespace FluentFTP {
	/// <summary>
	/// Used for transaction logging and debug information.
	/// </summary>
	/// <example>The following example illustrates how to assist in debugging
	/// FluentFTP by getting a transaction log from the server.
	/// <code source="..\Examples\Debug.cs" lang="cs" />
	/// </example>
	public static class FtpTrace {


#if !CORE
		static List<TraceListener> m_listeners = new List<TraceListener>();


		static bool m_flushOnWrite = false;

		/// <summary>
		/// Gets or sets whether the trace listeners should be flushed or not
		/// after writing to them. Default value is false.
		/// </summary>
		public static bool FlushOnWrite {
			get {
				return m_flushOnWrite;
			}
			set {
				m_flushOnWrite = value;
			}
		}


		/// <summary>
		/// Add a TraceListner to the collection. You can use one of the predefined
		/// TraceListeners in the System.Diagnostics namespace, such as ConsoleTraceListener
		/// for logging to the console, or you can write your own deriving from 
		/// System.Diagnostics.TraceListener.
		/// </summary>
		/// <param name="listener">The TraceListener to add to the collection</param>
		public static void AddListener(TraceListener listener) {
			lock (m_listeners) {
				m_listeners.Add(listener);
			}
		}

		/// <summary>
		/// Remove the specified TraceListener from the collection
		/// </summary>
		/// <param name="listener">The TraceListener to remove from the collection.</param>
		public static void RemoveListener(TraceListener listener) {
			lock (m_listeners) {
				m_listeners.Remove(listener);
			}
		}

#endif

		/// <summary>
		/// Write to the TraceListeners.
		/// </summary>
		/// <param name="message">The message to write</param>
		/// <param name="args">Optional variables if using a format string similar to string.Format()</param>
		public static void Write(string message, params object[] args) {
			Write(string.Format(message, args));
		}

		/// <summary>
		/// Write to the TraceListeners
		/// </summary>
		/// <param name="message">The message to write</param>
		public static void Write(string message) {
#if !CORE
			TraceListener[] listeners;

			lock (m_listeners) {
				listeners = m_listeners.ToArray();
			}
#endif

#if DEBUG
			Debug.Write(message);
#endif

#if !CORE
			foreach (TraceListener t in listeners) {
				t.Write(message);

				if (m_flushOnWrite) {
					t.Flush();
				}
			}
#endif
		}

		/// <summary>
		/// Write to the TraceListeners.
		/// </summary>
		/// <param name="message">The message to write</param>
		/// <param name="args">Optional variables if using a format string similar to string.Format()</param>
		public static void WriteLine(string message, params object[] args) {
			Write(string.Format("{0}{1}", string.Format(message, args), Environment.NewLine));
		}

		/// <summary>
		/// Write to the TraceListeners
		/// </summary>
		/// <param name="message">The message to write</param>
		public static void WriteLine(string message) {
			Write(string.Format("{0}{1}", message, Environment.NewLine));
		}
	}
}