using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ContactLibrary;
using DAL.Interfaces;
using DAL.Repositories;

namespace DAL
{
    public class UOW : IUOW, IDisposable
    {
        private IDbContext DbContext { get; set; }
        protected IEFRepositoryProvider RepositoryProvider { get; set; }

        public UOW(IEFRepositoryProvider repositoryProvider, IDbContext dbContext)
        {
            DbContext = dbContext;

            repositoryProvider.DbContext = dbContext;
            RepositoryProvider = repositoryProvider;
        }

        // UoW main feature - atomic commit at the end of work
        public void Commit()
        {
            ((DbContext)DbContext).SaveChanges();
        }

        //standard repos
        //public IEFRepository<Person> Persons { get { return GetStandardRepo<Person>(); } }
        public IEFRepository<Contact> Contacts { get { return GetStandardRepo<Contact>(); } }
        public IEFRepository<ContactType> ContactTypes { get { return GetStandardRepo<ContactType>(); } }

        // repo with custom methods
        // add it also in EFRepositoryFactories.cs, in method GetCustomFactories

        public IUserRepository Users { get { return GetRepo<IUserRepository>(); } }
        public IUserRoleRepository UserRoles { get { return GetRepo<IUserRoleRepository>(); } }
        public IRoleRepository Roles { get { return GetRepo<IRoleRepository>(); } }
        public IUserClaimRepository UserClaims { get { return GetRepo<IUserClaimRepository>(); } }
        public IUserLoginRepository UserLogins { get { return GetRepo<IUserLoginRepository>(); } }



        // calling standard EF repo provider
        private IEFRepository<T> GetStandardRepo<T>() where T : class
        {
            return RepositoryProvider.GetRepositoryForEntityType<T>();
        }

        // calling custom repo provier
        private T GetRepo<T>() where T : class
        {
            return RepositoryProvider.GetRepository<T>();
        }

        #region IDisposable
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
        protected virtual void Dispose(bool disposing)
        {
            if (!disposing) return;
            if (DbContext != null)
            {
                ((DbContext)DbContext).Dispose();
            }
        }

        #endregion

    }
}
