using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Model.Entities.Files;
using Model.UnitsOfWork;

namespace Model.Entities.Base
{
    public abstract class Base_FS_Repository<T> : BaseRepository<T> where T : FS_Item
    {
        protected DbSet<FS_Item> Set_Fs => context.Set<FS_Item>();
        protected readonly Enum_BaseDirectoryEntity RepoType;

        public override void RepoInit() { }
        public Base_FS_Repository(UOW UOW, Enum_BaseDirectoryEntity type) : base(UOW)
        {
            this.RepoType = type;
        }

        //public override T GetFromDBNoChange(T elem)
        //{
        //    using (var context = new Context())
        //    {
        //        var en = context.Set<FS_Item>().
        //            FirstOrDefault(e => e.ID == elem.ID);//.
        //                                                 //Include(e => e.Parent).
        //                                                 //FirstOrDefault();

        //        //context.Entry(en).Reference(e => e.Parent).Load();
        //        var p = en.PhysicalPath;

        //        return (T)en;
        //    }
        //}

        public override T Create(T elem)
        {
            if (elem.Type != RepoType)
                throw Repo_Exception<T>.Factory(this, elem, Repo_Exceptions.FSRepo_TypeException);

            return base.Create(elem);
        }

        public override void Update(T elem)
        {
            if (elem.Type != RepoType)
                throw Repo_Exception<T>.Factory(this, elem, Repo_Exceptions.FSRepo_TypeException);

            base.Update(elem);
        }

        public override void Delete(T elem)
        {
            if (elem.Type != RepoType)
                throw Repo_Exception<T>.Factory(this, elem, Repo_Exceptions.FSRepo_TypeException);

            base.Delete(elem);
        }


        /// <summary>
        /// Рекурсия
        /// Функция удаляет данные о файлах из базы, при этом не влияя на ФС
        /// Обычно вызывается при сканировании ФС, когда папка/файл из базы не найдена в ФС
        /// </summary>
        /// <param name="elem"></param>
        public virtual void DeleteInList(FS_Item elem)
        {
            _DeleteInList(elem);
            context.SaveChanges();
        }

        private void _DeleteInList(FS_Item elem)
        {
            var items = elem.Items;
            //При foreach вылетает exception изменение коллекции
            for (int i = 0; i < items.Count; i++)
            {
                DeleteInList(items[i]);
            }

            Set_Fs.Remove(elem);
        }

    }
}
