// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

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

namespace Microsoft.AspNetCore.Razor.Language
{
	public sealed class ItemCollection : ICollection<KeyValuePair<object, object>>, ICollection
	{
		private readonly Dictionary<object, object> _inner;

		public ItemCollection()
		{
			_inner = new Dictionary<object, object>();
		}

		public object this[object key]
		{
			get
			{
				if ( key == null )
				{
					throw new ArgumentNullException( nameof( key ) );
				}

				_inner.TryGetValue( key, out var value );
				return value;
			}
			set
			{
				if ( key == null )
				{
					throw new ArgumentNullException( nameof( key ) );
				}

				_inner[key] = value;
			}
		}

		public int Count => _inner.Count;

		public bool IsReadOnly => _inner != null;

		bool ICollection.IsSynchronized => ((ICollection)_inner).IsSynchronized;

		object ICollection.SyncRoot => ((ICollection)_inner).SyncRoot;

		public void Add( KeyValuePair<object, object> item )
		{
			if ( item.Key == null )
			{
				throw new ArgumentException( Resources.KeyMustNotBeNull, nameof( item ) );
			}

			((ICollection<KeyValuePair<object, object>>)_inner).Add( item );
		}

		public void Add( object key, object value )
		{
			if ( key == null )
			{
				throw new ArgumentNullException( nameof( key ) );
			}

			_inner.Add( key, value );
		}

		public void Clear()
		{
			_inner.Clear();
		}

		public bool Contains( KeyValuePair<object, object> item )
		{
			if ( item.Key == null )
			{
				throw new ArgumentException( Resources.KeyMustNotBeNull, nameof( item ) );
			}

			return ((ICollection<KeyValuePair<object, object>>)_inner).Contains( item );
		}

		public void CopyTo( KeyValuePair<object, object>[] array, int arrayIndex )
		{
			if ( array == null )
			{
				throw new ArgumentNullException( nameof( array ) );
			}

			if ( arrayIndex < 0 || arrayIndex > array.Length )
			{
				throw new ArgumentOutOfRangeException( nameof( arrayIndex ) );
			}
			else if ( array.Length - arrayIndex < Count )
			{
				throw new ArgumentOutOfRangeException( nameof( arrayIndex ) );
			}

			((ICollection<KeyValuePair<object, object>>)_inner).CopyTo( array, arrayIndex );
		}

		public IEnumerator<KeyValuePair<object, object>> GetEnumerator()
		{
			return _inner.GetEnumerator();
		}

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

		public bool Remove( KeyValuePair<object, object> item )
		{
			if ( item.Key == null )
			{
				throw new ArgumentException( Resources.KeyMustNotBeNull, nameof( item ) );
			}

			return ((ICollection<KeyValuePair<object, object>>)_inner).Remove( item );
		}

		void ICollection.CopyTo( Array array, int index )
		{
			((ICollection)_inner).CopyTo( array, index );
		}
	}
}
