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

using Model.Entities.Base;
using Model.Entities.Files;
using Model.Entities.Files.FS_Entities;
using Model.Entities.Files.Repo;
using Model.Entities.Users;

namespace Model.UnitsOfWork
{
    public class UOW
    {
        public readonly Context context;

        public readonly Repo_SRootDirectory Repo_SRootDirectory;
        public readonly Repo_SDirectory Repo_SDirectory;
        public readonly Repo_SFile Repo_SFile;
        public readonly Repo_SFileUpload Repo_SFileUpload;
        public IQueryable<FS_Item> FS_Items => context.FS_Items;

        public readonly Repo_User Repo_User;
        public readonly Repo_Group Repo_Group;

        //public Base_FS_Repository<FS_Item> Repo_FS<T>() where T: FS_Item
        //{
        //    if (typeof(T).Name == "SFile")
        //    {
        //            return Repo_SFile;
        //    }

        //    throw new Exception();
        //}

        public UOW()
        {
            context = new Context();

            Repo_Group = new Repo_Group(this);
            Repo_User = new Repo_User(this);

            Repo_SRootDirectory = new Repo_SRootDirectory(this);
            Repo_SDirectory = new Repo_SDirectory(this);
            Repo_SFile = new Repo_SFile(this);
            Repo_SFileUpload = new Repo_SFileUpload(this);            
        }
        public UOW(bool clear)
        {
            context = new Context(clear);

            Repo_Group = new Repo_Group(this);
            Repo_User = new Repo_User(this);

            Repo_SRootDirectory = new Repo_SRootDirectory(this);
            Repo_SDirectory = new Repo_SDirectory(this);
            Repo_SFile = new Repo_SFile(this);
            Repo_SFileUpload = new Repo_SFileUpload(this);            
        }


        public FS_Item Create(FS_Item elem)
        {
            switch (elem.Type)
            {
                case Enum_BaseDirectoryEntity.File:
                    return Repo_SFile.Create((SFile)elem);
                case Enum_BaseDirectoryEntity.Directory:
                    return Repo_SDirectory.Create((SDirectory)elem);
                case Enum_BaseDirectoryEntity.RootDirectory:
                    return Repo_SRootDirectory.Create((SRootDirectory)elem);
                case Enum_BaseDirectoryEntity.UploadFile:
                    return Repo_SFileUpload.Create((SFileUpload)elem);
                default:
                    throw new Exception();
            }
        }
        public void Update(FS_Item elem)
        {
            switch (elem.Type)
            {
                case Enum_BaseDirectoryEntity.File:
                    Repo_SFile.Update((SFile)elem);
                    return;
                case Enum_BaseDirectoryEntity.Directory:
                    Repo_SDirectory.Update((SDirectory)elem);
                    return;
                case Enum_BaseDirectoryEntity.RootDirectory:
                    Repo_SRootDirectory.Update((SRootDirectory)elem);
                    return;
                case Enum_BaseDirectoryEntity.UploadFile:
                    Repo_SFileUpload.Update((SFileUpload)elem);
                    return;
                default:
                    throw new Exception();
            }
        }
        public void Delete(FS_Item elem)
        {
            switch (elem.Type)
            {
                case Enum_BaseDirectoryEntity.File:
                    Repo_SFile.Delete((SFile)elem);
                    return;
                case Enum_BaseDirectoryEntity.Directory:
                    Repo_SDirectory.Delete((SDirectory)elem);
                    return;
                case Enum_BaseDirectoryEntity.RootDirectory:
                    Repo_SRootDirectory.Delete((SRootDirectory)elem);
                    return;
                case Enum_BaseDirectoryEntity.UploadFile:
                    Repo_SFileUpload.Delete((SFileUpload)elem);
                    return;
                default:
                    throw new Exception();
            }
        }

        public static UOW InitRepo(bool Clear)
        {
            var uow = new UOW(Clear);

            uow.Repo_Group.RepoInit();
            uow.Repo_User.RepoInit();

            uow.Repo_SRootDirectory.RepoInit();
            uow.Repo_SDirectory.RepoInit();
            uow.Repo_SFile.RepoInit();
            uow.Repo_SFileUpload.RepoInit();

            return uow;
        }
    }
}
