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

using System.IO;

using Model.Entities.Base;
using Model.Entities.Files.FS_Entities;
using Model.Entities.Users;
using Model.UnitsOfWork;
using Model.Tools;

namespace Model.Entities.Files.Repo
{

    public class Repo_SRootDirectory : Base_FS_Repository<SRootDirectory>
    {
        readonly ConfigTools ConfigTools = ConfigTools.Get();

        public Repo_SRootDirectory(UOW UOW) : base(UOW, Enum_BaseDirectoryEntity.RootDirectory) { }


        protected override void Validation_Create(SRootDirectory elem)
        {
            if (string.IsNullOrEmpty(elem.Name))
                throw Repo_Exception<SRootDirectory>.Factory(this, elem, Repo_Exceptions.Name_is_null_or_empty);

            if (elem.Parent != null)
                throw Repo_Exception<SRootDirectory>.Factory(this, elem, Repo_Exceptions.Parent_is_null);

            if (All.FirstOrDefault(e => e.Name == elem.Name) != null)
                throw Repo_Exception<SRootDirectory>.Factory(this, elem, Repo_Exceptions.Name_already_exists_in_parents);

            var exs = Directory.Exists(elem.PhysicalPath);
            if (!Directory.Exists(elem.PhysicalPath))
            {
                try
                {
                    Directory.CreateDirectory(elem.PhysicalPath);
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
        }
        public override SRootDirectory Create(SRootDirectory elem)
        {
            var dir = base.Create(elem);

            var groups = UOW.Repo_Group.All_List;
            foreach (var e in groups)
            {
                var permission = (e.Name == EnumDefaultGroups.Администраторы.ToString()) 
                    ? Permission.Factory_AllPermission(dir) 
                    : Permission.Factory_NoPermission(dir);

                e.DirectoryPermissions.AddOrUpdate(permission);
                UOW.Repo_Group.Update(e);
            }

            RootToConfig();

            return dir;
        }

        protected override void Validation_Update(SRootDirectory old, SRootDirectory elem)
        {
            throw new Exception();

            //if (elem.Parent != null)
            //    throw new Exception();

            //if (old.Name != elem.Name && All.FirstOrDefault(e => e.Name == elem.Name) != null)
            //{                
            //    throw new Exception();
            //}

            //try
            //{
            //    Directory.Move(old.PhysicalPath, elem.PhysicalPath);
            //}
            //catch (Exception ex)
            //{
            //    throw ex;
            //}
        }

        protected override void Validation_Delete(SRootDirectory elem)
        {
            if (elem.Items.Count() != 0)
                throw new Exception();

            try
            {
                Directory.Delete(elem.PhysicalPath);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        public override void Delete(SRootDirectory elem)
        {
            var id = elem.ID;
            base.Delete(elem);

            var groups = UOW.Repo_Group.All_List;
            foreach (var e in groups)
            {
                e.DirectoryPermissions.Remove(id);
                UOW.Repo_Group.Update(e);
            }
        }


        public override void DeleteInList(FS_Item elem)
        {
            var id = elem.ID;
            base.DeleteInList(elem);

            var groups = UOW.Repo_Group.All_List;
            foreach (var e in groups)
            {
                e.DirectoryPermissions.Remove(id);
                UOW.Repo_Group.Update(e);
            }

            RootToConfig();
        }

        private void RootToConfig()
        {
            if (ConfigTools.Data.WriteNewRootDir)
            {
                ConfigTools.Data.RootDirs = UOW.Repo_SRootDirectory
                    .All_List
                    .Select(e => e.PhysicalPath)
                    .ToList();

                ConfigTools.HaveChanges = true;
            }
        }

    }
}
