#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;

namespace log4net.Plugin
{
	/// <summary>
	///	A strongly-typed collection of <see cref="IPlugin"/> objects.
	/// </summary>
	/// <author>Nicko Cadell</author>
	public class PluginCollection : ICollection, IList, IEnumerable
#if !NETSTANDARD1_3
		, ICloneable
#endif
	{
		#region Interfaces

		/// <summary>
		/// Supports type-safe iteration over a <see cref="PluginCollection"/>.
		/// </summary>
		/// <exclude/>
		public interface IPluginCollectionEnumerator
		{
			/// <summary>
			///	Gets the current element in the collection.
			/// </summary>
			IPlugin Current { get; }

			/// <summary>
			///	Advances the enumerator to the next element in the collection.
			/// </summary>
			/// <returns>
			///	<c>true</c> if the enumerator was successfully advanced to the next element;
			///	<c>false</c> if the enumerator has passed the end of the collection.
			/// </returns>
			/// <exception cref="InvalidOperationException">
			///	The collection was modified after the enumerator was created.
			/// </exception>
			bool MoveNext();

			/// <summary>
			///	Sets the enumerator to its initial position, before the first element in the collection.
			/// </summary>
			void Reset();
		}

		#endregion Interfaces

		private const int DEFAULT_CAPACITY = 16;

		#region Implementation (data)

		private IPlugin[] m_array;
		private int m_count = 0;
		private int m_version = 0;

		#endregion Implementation (data)

		#region Static Wrappers

		/// <summary>
		///	Creates a read-only wrapper for a <c>PluginCollection</c> instance.
		/// </summary>
		/// <param name="list">list to create a readonly wrapper arround</param>
		/// <returns>
		/// A <c>PluginCollection</c> wrapper that is read-only.
		/// </returns>
		public static PluginCollection ReadOnly(PluginCollection list)
		{
			if(list == null) throw new ArgumentNullException("list");

			return new ReadOnlyPluginCollection(list);
		}

		#endregion

		#region Constructors

		/// <summary>
		///	Initializes a new instance of the <c>PluginCollection</c> class
		///	that is empty and has the default initial capacity.
		/// </summary>
		public PluginCollection()
		{
			m_array = new IPlugin[DEFAULT_CAPACITY];
		}

		/// <summary>
		/// Initializes a new instance of the <c>PluginCollection</c> class
		/// that has the specified initial capacity.
		/// </summary>
		/// <param name="capacity">
		/// The number of elements that the new <c>PluginCollection</c> is initially capable of storing.
		/// </param>
		public PluginCollection(int capacity)
		{
			m_array = new IPlugin[capacity];
		}

		/// <summary>
		/// Initializes a new instance of the <c>PluginCollection</c> class
		/// that contains elements copied from the specified <c>PluginCollection</c>.
		/// </summary>
		/// <param name="c">The <c>PluginCollection</c> whose elements are copied to the new collection.</param>
		public PluginCollection(PluginCollection c)
		{
			m_array = new IPlugin[c.Count];
			AddRange(c);
		}

		/// <summary>
		/// Initializes a new instance of the <c>PluginCollection</c> class
		/// that contains elements copied from the specified <see cref="IPlugin"/> array.
		/// </summary>
		/// <param name="a">The <see cref="IPlugin"/> array whose elements are copied to the new list.</param>
		public PluginCollection(IPlugin[] a)
		{
			m_array = new IPlugin[a.Length];
			AddRange(a);
		}

		/// <summary>
		/// Initializes a new instance of the <c>PluginCollection</c> class
		/// that contains elements copied from the specified <see cref="IPlugin"/> collection.
		/// </summary>
		/// <param name="col">The <see cref="IPlugin"/> collection whose elements are copied to the new list.</param>
		public PluginCollection(ICollection col)
		{
			m_array = new IPlugin[col.Count];
			AddRange(col);
		}

		/// <summary>
		/// Type visible only to our subclasses
		/// Used to access protected constructor
		/// </summary>
		/// <exclude/>
		protected internal enum Tag
		{
			/// <summary>
			/// A value
			/// </summary>
			Default
		}

		/// <summary>
		/// Allow subclasses to avoid our default constructors
		/// </summary>
		/// <param name="tag"></param>
		/// <exclude/>
		protected internal PluginCollection(Tag tag)
		{
			m_array = null;
		}

		#endregion

		#region Operations (type-safe ICollection)

		/// <summary>
		/// Gets the number of elements actually contained in the <c>PluginCollection</c>.
		/// </summary>
		public virtual int Count
		{
			get { return m_count; }
		}

		/// <summary>
		/// Copies the entire <c>PluginCollection</c> to a one-dimensional
		/// <see cref="IPlugin"/> array.
		/// </summary>
		/// <param name="array">The one-dimensional <see cref="IPlugin"/> array to copy to.</param>
		public virtual void CopyTo(IPlugin[] array)
		{
			this.CopyTo(array, 0);
		}

		/// <summary>
		/// Copies the entire <c>PluginCollection</c> to a one-dimensional
		/// <see cref="IPlugin"/> array, starting at the specified index of the target array.
		/// </summary>
		/// <param name="array">The one-dimensional <see cref="IPlugin"/> array to copy to.</param>
		/// <param name="start">The zero-based index in <paramref name="array"/> at which copying begins.</param>
		public virtual void CopyTo(IPlugin[] array, int start)
		{
			if (m_count > array.GetUpperBound(0) + 1 - start)
			{
				throw new System.ArgumentException("Destination array was not long enough.");
			}

			Array.Copy(m_array, 0, array, start, m_count);
		}

		/// <summary>
		/// Gets a value indicating whether access to the collection is synchronized (thread-safe).
		/// </summary>
		/// <returns>false, because the backing type is an array, which is never thread-safe.</returns>
		public virtual bool IsSynchronized
		{
			get { return false; }
		}

		/// <summary>
		/// Gets an object that can be used to synchronize access to the collection.
		/// </summary>
		/// <value>
		/// An object that can be used to synchronize access to the collection.
		/// </value>
		public virtual object SyncRoot
		{
			get { return m_array; }
		}

		#endregion

		#region Operations (type-safe IList)

		/// <summary>
		/// Gets or sets the <see cref="IPlugin"/> at the specified index.
		/// </summary>
		/// <value>
		/// The <see cref="IPlugin"/> at the specified index.
		/// </value>
		/// <param name="index">The zero-based index of the element to get or set.</param>
		/// <exception cref="ArgumentOutOfRangeException">
		/// <para><paramref name="index"/> is less than zero.</para>
		/// <para>-or-</para>
		/// <para><paramref name="index"/> is equal to or greater than <see cref="PluginCollection.Count"/>.</para>
		/// </exception>
		public virtual IPlugin this[int index]
		{
			get
			{
				ValidateIndex(index); // throws
				return m_array[index];
			}
			set
			{
				ValidateIndex(index); // throws
				++m_version;
				m_array[index] = value;
			}
		}

		/// <summary>
		/// Adds a <see cref="IPlugin"/> to the end of the <c>PluginCollection</c>.
		/// </summary>
		/// <param name="item">The <see cref="IPlugin"/> to be added to the end of the <c>PluginCollection</c>.</param>
		/// <returns>The index at which the value has been added.</returns>
		public virtual int Add(IPlugin item)
		{
			if (m_count == m_array.Length)
			{
				EnsureCapacity(m_count + 1);
			}

			m_array[m_count] = item;
			m_version++;

			return m_count++;
		}

		/// <summary>
		/// Removes all elements from the <c>PluginCollection</c>.
		/// </summary>
		public virtual void Clear()
		{
			++m_version;
			m_array = new IPlugin[DEFAULT_CAPACITY];
			m_count = 0;
		}

		/// <summary>
		/// Creates a shallow copy of the <see cref="PluginCollection"/>.
		/// </summary>
		/// <returns>A new <see cref="PluginCollection"/> with a shallow copy of the collection data.</returns>
		public virtual object Clone()
		{
			PluginCollection newCol = new PluginCollection(m_count);
			Array.Copy(m_array, 0, newCol.m_array, 0, m_count);
			newCol.m_count = m_count;
			newCol.m_version = m_version;

			return newCol;
		}

		/// <summary>
		/// Determines whether a given <see cref="IPlugin"/> is in the <c>PluginCollection</c>.
		/// </summary>
		/// <param name="item">The <see cref="IPlugin"/> to check for.</param>
		/// <returns><c>true</c> if <paramref name="item"/> is found in the <c>PluginCollection</c>; otherwise, <c>false</c>.</returns>
		public virtual bool Contains(IPlugin item)
		{
			for (int i=0; i != m_count; ++i)
			{
				if (m_array[i].Equals(item))
				{
					return true;
				}
			}
			return false;
		}

		/// <summary>
		/// Returns the zero-based index of the first occurrence of a <see cref="IPlugin"/>
		/// in the <c>PluginCollection</c>.
		/// </summary>
		/// <param name="item">The <see cref="IPlugin"/> to locate in the <c>PluginCollection</c>.</param>
		/// <returns>
		/// The zero-based index of the first occurrence of <paramref name="item"/>
		/// in the entire <c>PluginCollection</c>, if found; otherwise, -1.
		/// </returns>
		public virtual int IndexOf(IPlugin item)
		{
			for (int i=0; i != m_count; ++i)
			{
				if (m_array[i].Equals(item))
				{
					return i;
				}
			}
			return -1;
		}

		/// <summary>
		/// Inserts an element into the <c>PluginCollection</c> at the specified index.
		/// </summary>
		/// <param name="index">The zero-based index at which <paramref name="item"/> should be inserted.</param>
		/// <param name="item">The <see cref="IPlugin"/> to insert.</param>
		/// <exception cref="ArgumentOutOfRangeException">
		/// <para><paramref name="index"/> is less than zero</para>
		/// <para>-or-</para>
		/// <para><paramref name="index"/> is equal to or greater than <see cref="PluginCollection.Count"/>.</para>
		/// </exception>
		public virtual void Insert(int index, IPlugin item)
		{
			ValidateIndex(index, true); // throws

			if (m_count == m_array.Length)
			{
				EnsureCapacity(m_count + 1);
			}

			if (index < m_count)
			{
				Array.Copy(m_array, index, m_array, index + 1, m_count - index);
			}

			m_array[index] = item;
			m_count++;
			m_version++;
		}

		/// <summary>
		/// Removes the first occurrence of a specific <see cref="IPlugin"/> from the <c>PluginCollection</c>.
		/// </summary>
		/// <param name="item">The <see cref="IPlugin"/> to remove from the <c>PluginCollection</c>.</param>
		/// <exception cref="ArgumentException">
		/// The specified <see cref="IPlugin"/> was not found in the <c>PluginCollection</c>.
		/// </exception>
		public virtual void Remove(IPlugin item)
		{
			int i = IndexOf(item);
			if (i < 0)
			{
				throw new System.ArgumentException("Cannot remove the specified item because it was not found in the specified Collection.");
			}
			++m_version;
			RemoveAt(i);
		}

		/// <summary>
		/// Removes the element at the specified index of the <c>PluginCollection</c>.
		/// </summary>
		/// <param name="index">The zero-based index of the element to remove.</param>
		/// <exception cref="ArgumentOutOfRangeException">
		/// <para><paramref name="index"/> is less than zero.</para>
		/// <para>-or-</para>
		/// <para><paramref name="index"/> is equal to or greater than <see cref="PluginCollection.Count"/>.</para>
		/// </exception>
		public virtual void RemoveAt(int index)
		{
			ValidateIndex(index); // throws

			m_count--;

			if (index < m_count)
			{
				Array.Copy(m_array, index + 1, m_array, index, m_count - index);
			}

			// We can't set the deleted entry equal to null, because it might be a value type.
			// Instead, we'll create an empty single-element array of the right type and copy it
			// over the entry we want to erase.
			IPlugin[] temp = new IPlugin[1];
			Array.Copy(temp, 0, m_array, m_count, 1);
			m_version++;
		}

		/// <summary>
		/// Gets a value indicating whether the collection has a fixed size.
		/// </summary>
		/// <value><c>true</c> if the collection has a fixed size; otherwise, <c>false</c>. The default is <c>false</c>.</value>
		public virtual bool IsFixedSize
		{
			get { return false; }
		}

		/// <summary>
		/// Gets a value indicating whether the IList is read-only.
		/// </summary>
		/// <value><c>true</c> if the collection is read-only; otherwise, <c>false</c>. The default is <c>false</c>.</value>
		public virtual bool IsReadOnly
		{
			get { return false; }
		}

		#endregion

		#region Operations (type-safe IEnumerable)

		/// <summary>
		/// Returns an enumerator that can iterate through the <c>PluginCollection</c>.
		/// </summary>
		/// <returns>An <see cref="Enumerator"/> for the entire <c>PluginCollection</c>.</returns>
		public virtual IPluginCollectionEnumerator GetEnumerator()
		{
			return new Enumerator(this);
		}

		#endregion

		#region Public helpers (just to mimic some nice features of ArrayList)

		/// <summary>
		/// Gets or sets the number of elements the <c>PluginCollection</c> can contain.
		/// </summary>
		/// <value>
		/// The number of elements the <c>PluginCollection</c> can contain.
		/// </value>
		public virtual int Capacity
		{
			get
			{
				return m_array.Length;
			}
			set
			{
				if (value < m_count)
				{
					value = m_count;
				}

				if (value != m_array.Length)
				{
					if (value > 0)
					{
						IPlugin[] temp = new IPlugin[value];
						Array.Copy(m_array, 0, temp, 0, m_count);
						m_array = temp;
					}
					else
					{
						m_array = new IPlugin[DEFAULT_CAPACITY];
					}
				}
			}
		}

		/// <summary>
		/// Adds the elements of another <c>PluginCollection</c> to the current <c>PluginCollection</c>.
		/// </summary>
		/// <param name="x">The <c>PluginCollection</c> whose elements should be added to the end of the current <c>PluginCollection</c>.</param>
		/// <returns>The new <see cref="PluginCollection.Count"/> of the <c>PluginCollection</c>.</returns>
		public virtual int AddRange(PluginCollection x)
		{
			if (m_count + x.Count >= m_array.Length)
			{
				EnsureCapacity(m_count + x.Count);
			}

			Array.Copy(x.m_array, 0, m_array, m_count, x.Count);
			m_count += x.Count;
			m_version++;

			return m_count;
		}

		/// <summary>
		/// Adds the elements of a <see cref="IPlugin"/> array to the current <c>PluginCollection</c>.
		/// </summary>
		/// <param name="x">The <see cref="IPlugin"/> array whose elements should be added to the end of the <c>PluginCollection</c>.</param>
		/// <returns>The new <see cref="PluginCollection.Count"/> of the <c>PluginCollection</c>.</returns>
		public virtual int AddRange(IPlugin[] x)
		{
			if (m_count + x.Length >= m_array.Length)
			{
				EnsureCapacity(m_count + x.Length);
			}

			Array.Copy(x, 0, m_array, m_count, x.Length);
			m_count += x.Length;
			m_version++;

			return m_count;
		}

		/// <summary>
		/// Adds the elements of a <see cref="IPlugin"/> collection to the current <c>PluginCollection</c>.
		/// </summary>
		/// <param name="col">The <see cref="IPlugin"/> collection whose elements should be added to the end of the <c>PluginCollection</c>.</param>
		/// <returns>The new <see cref="PluginCollection.Count"/> of the <c>PluginCollection</c>.</returns>
		public virtual int AddRange(ICollection col)
		{
			if (m_count + col.Count >= m_array.Length)
			{
				EnsureCapacity(m_count + col.Count);
			}

			foreach(object item in col)
			{
				Add((IPlugin)item);
			}

			return m_count;
		}

		/// <summary>
		/// Sets the capacity to the actual number of elements.
		/// </summary>
		public virtual void TrimToSize()
		{
			this.Capacity = m_count;
		}

		#endregion

		#region Implementation (helpers)

		/// <exception cref="ArgumentOutOfRangeException">
		/// <para><paramref name="i"/> is less than zero.</para>
		/// <para>-or-</para>
		/// <para><paramref name="i"/> is equal to or greater than <see cref="PluginCollection.Count"/>.</para>
		/// </exception>
		private void ValidateIndex(int i)
		{
			ValidateIndex(i, false);
		}

		/// <exception cref="ArgumentOutOfRangeException">
		/// <para><paramref name="i"/> is less than zero.</para>
		/// <para>-or-</para>
		/// <para><paramref name="i"/> is equal to or greater than <see cref="PluginCollection.Count"/>.</para>
		/// </exception>
		private void ValidateIndex(int i, bool allowEqualEnd)
		{
			int max = (allowEqualEnd) ? (m_count) : (m_count-1);
			if (i < 0 || i > max)
			{
				throw log4net.Util.SystemInfo.CreateArgumentOutOfRangeException("i", (object)i, "Index was out of range. Must be non-negative and less than the size of the collection. [" + (object)i + "] Specified argument was out of the range of valid values.");
			}
		}

		private void EnsureCapacity(int min)
		{
			int newCapacity = ((m_array.Length == 0) ? DEFAULT_CAPACITY : m_array.Length * 2);
			if (newCapacity < min)
			{
				newCapacity = min;
			}

			this.Capacity = newCapacity;
		}

		#endregion

		#region Implementation (ICollection)

		void ICollection.CopyTo(Array array, int start)
		{
			Array.Copy(m_array, 0, array, start, m_count);
		}

		#endregion

		#region Implementation (IList)

		object IList.this[int i]
		{
			get { return (object)this[i]; }
			set { this[i] = (IPlugin)value; }
		}

		int IList.Add(object x)
		{
			return this.Add((IPlugin)x);
		}

		bool IList.Contains(object x)
		{
			return this.Contains((IPlugin)x);
		}

		int IList.IndexOf(object x)
		{
			return this.IndexOf((IPlugin)x);
		}

		void IList.Insert(int pos, object x)
		{
			this.Insert(pos, (IPlugin)x);
		}

		void IList.Remove(object x)
		{
			this.Remove((IPlugin)x);
		}

		void IList.RemoveAt(int pos)
		{
			this.RemoveAt(pos);
		}

		#endregion

		#region Implementation (IEnumerable)

		IEnumerator IEnumerable.GetEnumerator()
		{
			return (IEnumerator)(this.GetEnumerator());
		}

		#endregion Implementation (IEnumerable)

		#region Nested enumerator class

		/// <summary>
		/// Supports simple iteration over a <see cref="PluginCollection"/>.
		/// </summary>
		/// <exclude/>
		private sealed class Enumerator : IEnumerator, IPluginCollectionEnumerator
		{
			#region Implementation (data)

			private readonly PluginCollection m_collection;
			private int m_index;
			private int m_version;

			#endregion Implementation (data)

			#region Construction

			/// <summary>
			/// Initializes a new instance of the <c>Enumerator</c> class.
			/// </summary>
			/// <param name="tc"></param>
			internal Enumerator(PluginCollection tc)
			{
				m_collection = tc;
				m_index = -1;
				m_version = tc.m_version;
			}

			#endregion

			#region Operations (type-safe IEnumerator)

			/// <summary>
			/// Gets the current element in the collection.
			/// </summary>
			/// <value>
			/// The current element in the collection.
			/// </value>
			public IPlugin Current
			{
				get { return m_collection[m_index]; }
			}

			/// <summary>
			/// Advances the enumerator to the next element in the collection.
			/// </summary>
			/// <returns>
			/// <c>true</c> if the enumerator was successfully advanced to the next element;
			/// <c>false</c> if the enumerator has passed the end of the collection.
			/// </returns>
			/// <exception cref="InvalidOperationException">
			/// The collection was modified after the enumerator was created.
			/// </exception>
			public bool MoveNext()
			{
				if (m_version != m_collection.m_version)
				{
					throw new System.InvalidOperationException("Collection was modified; enumeration operation may not execute.");
				}

				++m_index;
				return (m_index < m_collection.Count);
			}

			/// <summary>
			/// Sets the enumerator to its initial position, before the first element in the collection.
			/// </summary>
			public void Reset()
			{
				m_index = -1;
			}

			#endregion

			#region Implementation (IEnumerator)

			object IEnumerator.Current
			{
				get { return this.Current; }
			}

			#endregion
		}

		#endregion

		#region Nested Read Only Wrapper class

		/// <exclude/>
		private sealed class ReadOnlyPluginCollection : PluginCollection
		{
			#region Implementation (data)

			private readonly PluginCollection m_collection;

			#endregion

			#region Construction

			internal ReadOnlyPluginCollection(PluginCollection list) : base(Tag.Default)
			{
				m_collection = list;
			}

			#endregion

			#region Type-safe ICollection

			public override void CopyTo(IPlugin[] array)
			{
				m_collection.CopyTo(array);
			}

			public override void CopyTo(IPlugin[] array, int start)
			{
				m_collection.CopyTo(array,start);
			}
			public override int Count
			{
				get { return m_collection.Count; }
			}

			public override bool IsSynchronized
			{
				get { return m_collection.IsSynchronized; }
			}

			public override object SyncRoot
			{
				get { return this.m_collection.SyncRoot; }
			}

			#endregion

			#region Type-safe IList

			public override IPlugin this[int i]
			{
				get { return m_collection[i]; }
				set { throw new NotSupportedException("This is a Read Only Collection and can not be modified"); }
			}

			public override int Add(IPlugin x)
			{
				throw new NotSupportedException("This is a Read Only Collection and can not be modified");
			}

			public override void Clear()
			{
				throw new NotSupportedException("This is a Read Only Collection and can not be modified");
			}

			public override bool Contains(IPlugin x)
			{
				return m_collection.Contains(x);
			}

			public override int IndexOf(IPlugin x)
			{
				return m_collection.IndexOf(x);
			}

			public override void Insert(int pos, IPlugin x)
			{
				throw new NotSupportedException("This is a Read Only Collection and can not be modified");
			}

			public override void Remove(IPlugin x)
			{
				throw new NotSupportedException("This is a Read Only Collection and can not be modified");
			}

			public override void RemoveAt(int pos)
			{
				throw new NotSupportedException("This is a Read Only Collection and can not be modified");
			}

			public override bool IsFixedSize
			{
				get { return true; }
			}

			public override bool IsReadOnly
			{
				get { return true; }
			}

			#endregion

			#region Type-safe IEnumerable

			public override IPluginCollectionEnumerator GetEnumerator()
			{
				return m_collection.GetEnumerator();
			}

			#endregion

			#region Public Helpers

			// (just to mimic some nice features of ArrayList)
			public override int Capacity
			{
				get { return m_collection.Capacity; }
				set { throw new NotSupportedException("This is a Read Only Collection and can not be modified"); }
			}

			public override int AddRange(PluginCollection x)
			{
				throw new NotSupportedException("This is a Read Only Collection and can not be modified");
			}

			public override int AddRange(IPlugin[] x)
			{
				throw new NotSupportedException("This is a Read Only Collection and can not be modified");
			}

			#endregion
		}

		#endregion
	}
}
