using System;
using System.Collections.Generic;

namespace Lookup.Interface;

/// <summary>
/// Common interface for <see cref="ILookup"/>s,
/// storing data as key-value pairs
/// </summary>
public interface ILookup
{
}

/// <summary>
/// Common interface for <see cref="ILookup{TKey, TValue}"/>s,
/// storing data as <typeparamref name="TKey"/>-<typeparamref name="TValue"/> pairs
/// </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 interface ILookup<TKey, TValue>
  : ILookup,
    IDictionary<TKey, ICollection<TValue>>,
    IDisposable
{
  /// <summary>
  /// Adds a key to the <see cref="ILookup"/>
  /// </summary>
  /// <param name="key">
  /// The <typeparamref name="TKey"/> to add
  /// </param>
  /// <returns>
  /// The new <see cref="ICollection{TValue}"/>
  /// to store <typeparamref name="TValue"/>s in
  /// </returns>
  ICollection<TValue> Add(TKey key);

  /// <summary>
  /// Adds a <typeparamref name="TValue"/> to an existing collection
  /// referenced by <typeparamref name="TKey"/> in the <see cref="ILookup"/>
  /// </summary>
  public void Add(TKey key, TValue value);

  /// <summary>
  /// Adds multiple <typeparamref name="TValue"/>s to
  /// an existing <see cref="ICollection{TValue}"/>
  /// referenced by <typeparamref name="TKey"/> in
  /// the <see cref="ILookup"/>
  /// </summary>
  public void AddRange(TKey key, IEnumerable<TValue> values);

  /// <summary>
  /// Removes a <typeparamref name="TValue"/> from
  /// an existing <see cref="ICollection{TValue}"/>
  /// referenced by <typeparamref name="TKey"/> in
  /// the <see cref="ILookup"/>
  /// </summary>
  public bool Remove(TKey key, TValue value);

  /// <summary>
  /// Gets an existing <see cref="ICollection{TValue}"/> referenced by
  /// <typeparamref name="TKey"/> or creates it, if it does not already exist
  /// </summary>
  /// <param name="key">
  /// The <typeparamref name="TKey"/> to add
  /// </param>
  /// <returns>
  /// The <see cref="ICollection{TValue}"/> to
  /// store <typeparamref name="TValue"/>s in
  /// </returns>
  public ICollection<TValue> GetOrAdd(TKey key);
}