﻿using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Bogosoft.Storage
{
    /// <summary>
    /// Provides a means of deleting a single entity at a time.
    /// </summary>
    /// <typeparam name="T">The type of the entity that can be deleted.</typeparam>
    public interface IDelete<T>
    {
        /// <summary>Delete a single entity.</summary>
        /// <param name="entity">An entity to delete.</param>
        /// <returns>
        /// A value indicating whether or not the delete operation succeeded.
        /// </returns>
        Task<Boolean> DeleteAsync(T entity);
    }

    /// <summary>Provides a means of deleting entities from an underlying data source.</summary>
    /// <typeparam name="TEntity">The type of the entity that can be deleted.</typeparam>
    /// <typeparam name="TId">
    /// The type of a property of the entity type that guarantees the uniqueness
    /// of an instance of that entity type.
    /// </typeparam>
    public interface IDelete<TEntity, TId>
    {
        /// <summary>Delete a collection of specified entities.</summary>
        /// <param name="entities">A collection of entities to delete.</param>
        /// <returns>
        /// A collection of values corresponding to the unique identifiers of the entities
        /// that were successfully deleted. Implementers SHOULD return an empty collection
        /// in the event that no deletion was successful.
        /// </returns>
        /// <remarks>
        /// Implementers should freely interpret what a "deletion" looks like
        /// in the underlying data source.
        /// </remarks>
        /// <exception cref="EntityUndefinedException{T}">
        /// Implementers MAY choose to throw an <see cref="EntityUndefinedException{T}"/>
        /// in the event that the given entity does not currently exist in the underlying
        /// data source.
        /// </exception>
        Task<IEnumerable<TId>> DeleteAsync(IEnumerable<TEntity> entities);
    }
}