using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;

namespace Wierszowki.Core.Interfaces
{
    /// <summary>
    /// Contact for the Repository pattern
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public interface IRepository<T>
      where T : IIdentifiable
    {
        /// <summary>
        /// Returns a count of the items in the repository
        /// </summary>
        int Count();

        /// <summary>
        /// Returns a count of the items in the repository which match the supplied lambda
        /// </summary>
        /// <param name="expression">A lambda expression which will be evaluated against the repository</param>
        int Count(Expression<Func<T, bool>> expression);

        /// <summary>
        /// Adds a new entity in to the repository
        /// </summary>
        void Insert(T entity);

        /// <summary>
        /// Removes the specified entity from the repository
        /// </summary>
        void Delete(T entity);

        /// <summary>
        /// Saves the specified entity back to the repository
        /// </summary>
        void Update(T entity);

        /// <summary>
        /// Finds a single instance of an entity matching a unique identifier.
        /// </summary>
        T FindOne(int id);

        /// <summary>
        /// Finds a single instance of an entity matching a lambda expression
        /// </summary>
        /// <returns>The first entity which matches the expession</returns>
        T FindOne(Expression<Func<T, bool>> expression);

        /// <summary>
        /// Tries the find one.
        /// </summary>
        /// <param name="expression">The expression.</param>
        /// <param name="entity">The entity.</param>
        /// <returns></returns>
        bool TryFindOne(Expression<Func<T, bool>> expression, out T entity);

        /// <summary>
        /// Tries the find one.
        /// </summary>
        /// <param name="expression">The expression.</param>
        /// <returns></returns>
        bool Exists(Expression<Func<T, bool>> expression);

        /// <summary>
        /// Finds all entities in the repository
        /// </summary>
        /// <returns></returns>
        IList<T> FindAll();

        /// <summary>
        /// Finds all entities matching a lambda expression
        /// </summary>
        /// <param name="expression">The expression.</param>
        /// <returns></returns>
        IList<T> FindAll(Expression<Func<T, bool>> expression);

        /// <summary>
        /// Returns a requeryable set of all entities in the repository
        /// </summary>
        IQueryable<T> Find();

        /// <summary>
        /// Returns a requeryable set of all entities in the repository matching a unique identifier
        /// </summary>
        IQueryable<T> Find(int id);

        /// <summary>
        /// Returns a requeryable set of all entities in the repository matching a lambda expression
        /// </summary>
        IQueryable<T> Find(Expression<Func<T, bool>> expression);
    }
}