using Lookup.Interface;
using System.Collections.Generic;
using System.Runtime.Serialization;

namespace Lookup.Memory;

/// <summary>
/// <see cref="ILookup{TKey,TValue}"/>
/// implementation, storing data in <see cref="ICollection{T}"/>s
/// </summary>
/// <typeparam name="TKey">Type of the key referencing the <typeparamref name="TValue"/>s</typeparam>
/// <typeparam name="TValue">Type of the stored values, referenced by <typeparamref name="TKey"/></typeparam>
public class MemoryLookup<TKey, TValue> : Abstract.Lookup<TKey, TValue>
  where TKey : notnull
{
  #region Constructors

  /// <inheritdoc />
  public MemoryLookup()
  {
  }

  /// <inheritdoc />
  public MemoryLookup(IDictionary<TKey, ICollection<TValue>> dictionary) : base(dictionary)
  {
  }

  /// <inheritdoc />
  public MemoryLookup(
    IDictionary<TKey, ICollection<TValue>> dictionary, IEqualityComparer<TKey>? comparer
  ) : base(dictionary, comparer)
  {
  }

  /// <inheritdoc />
  public MemoryLookup(
    IEnumerable<KeyValuePair<TKey, ICollection<TValue>>> collection
  ) : base(collection)
  {
  }

  /// <inheritdoc />
  public MemoryLookup(
    IEnumerable<KeyValuePair<TKey, ICollection<TValue>>> collection,
    IEqualityComparer<TKey>? comparer
  ) : base(collection, comparer)
  {
  }

  /// <inheritdoc />
  public MemoryLookup(IEqualityComparer<TKey>? comparer) : base(comparer)
  {
  }

  /// <inheritdoc />
  public MemoryLookup(int capacity) : base(capacity)
  {
  }

  /// <inheritdoc />
  public MemoryLookup(int capacity, IEqualityComparer<TKey>? comparer) : base(capacity, comparer)
  {
  }

  /// <inheritdoc />
  public MemoryLookup(SerializationInfo info, StreamingContext context) : base(info, context)
  {
  }

  #endregion

  #region Overrides of Lookup<TKey,ICollection<TValue>>

  /// <inheritdoc />
  public override ICollection<TValue> Add(TKey key)
  {
    base.Add(key, new List<TValue>());
    return this[key];
  }

  /// <inheritdoc cref="Add(TKey)" />
  public ICollection<TValue> Add(TKey key, int collectionCapacity)
  {
    base.Add(key, new List<TValue>(collectionCapacity));
    return this[key];
  }

  #endregion
}