using System.Data.Entity;
using System.Diagnostics;
using System.Linq;

namespace Rainbow.Data
{
    public class GenericRepository<T> : IRepository<T> where T : class
    {
        public GenericRepository(RainbowContext context)
        {
            Debug.Assert(context != null);

            Context = context;
            DbSet = context.Set<T>();
        }

        public IQueryable<T> List()
        {
            return DbSet;
        }

        public T GetById(int id)
        {
            return DbSet.Find(id);
        }

        public void Add(T entity)
        {
            var entry = Context.Entry(entity);
            if (entry.State != EntityState.Detached)
            {
                entry.State = EntityState.Added;
            }
            else
            {
                DbSet.Add(entity);
            }
        }

        public void Update(T entity)
        {
            var entry = Context.Entry(entity);
            if (entry.State == EntityState.Detached)
            {
                DbSet.Attach(entity);
            }
            entry.State = EntityState.Modified;
        }

        public void Delete(T entity)
        {
            var entry = Context.Entry(entity);
            if (entry.State != EntityState.Deleted)
            {
                entry.State = EntityState.Deleted;
            }
            else
            {
                DbSet.Attach(entity);
                DbSet.Remove(entity);
            }
        }

        public void Delete(int id)
        {
            var entity = GetById(id);
            Delete(entity);
        }

        public void Detach(T entity)
        {
            var entry = Context.Entry(entity);
            entry.State = EntityState.Detached;
        }

        protected DbSet<T> DbSet { get; set;}

        protected RainbowContext Context { get; set; }
    }
}
