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

using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
using System.IO;
using System.Xml.Serialization;

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

namespace Model.Entities.Users
{

    [Serializable]
    public class Permission
    {
        public int DirectoryID { set; get; }
        [XmlIgnore]
        public SRootDirectory RootDirectory { set; get; }


        /// <summary>
        /// Скачать файл из папки
        /// </summary>
        public bool CanDownload { set; get; }

        /// <summary>
        /// Загрузить файл в папку
        /// </summary>
        public bool CanUpload { set; get; }

        /// <summary>
        /// Папка доступна к просмотру
        /// </summary>
        public bool CanOpen { set; get; }


        public static Permission Factory_AllPermission(SRootDirectory directory)
        {
            return new Permission()
            {
                DirectoryID = directory.ID,
                RootDirectory = directory,
                CanDownload = true,
                CanOpen = true,
                CanUpload = true
            };
        }

        public static Permission Factory_NoPermission(SRootDirectory directory)
        {
            return new Permission()
            {
                DirectoryID = directory.ID,
                RootDirectory = directory,
                CanDownload = false,
                CanOpen = false,
                CanUpload = false
            };
        }

    }

    [Serializable]
    public class DirectoryPermissions
    {
        /// <summary>
        /// key - Directory ID
        /// </summary>
        Dictionary<int, Permission> _Permissions { set; get; } = new Dictionary<int, Permission>();
        public IReadOnlyDictionary<int, Permission> Permissions => _Permissions;


        public Permission AddOrUpdate(Permission permission)
        {
            if (_Permissions.ContainsKey(permission.DirectoryID))
                _Permissions[permission.DirectoryID] = permission;
            else
                _Permissions.Add(permission.DirectoryID, permission);

            return permission;
        }
        public Permission Get(int GroupID)
        {
            return _Permissions[GroupID];
        }
        public void Remove(int GroupID)
        {
            _Permissions.Remove(GroupID);
        }

        public string Export()
        {
            XmlSerializer formatter = new XmlSerializer(typeof(Permission[]));

            using (StringWriter wr = new StringWriter())
            {
                formatter.Serialize(wr, _Permissions.Values.ToArray());
                return wr.ToString();
            }
        }
        public void Import(string val)
        {
            XmlSerializer formatter = new XmlSerializer(typeof(Permission[]));

            using (StringReader rd = new StringReader(val))
            {
                var data = (Permission[])formatter.Deserialize(rd);
                _Permissions.Clear();
                foreach (var elem in data)
                    _Permissions.Add(elem.DirectoryID, elem);
            }
        }

    }


    public class Group : BaseEntity
    {
        [Required]
        public string Name { set; get; }

        public virtual List<User> Users { set; get; } = new List<User>();

        [NotMapped]
        public DirectoryPermissions DirectoryPermissions { private set; get; } = new DirectoryPermissions();
        [Column("XML_Permissions")]
        public string XML_Permissions
        {
            set => DirectoryPermissions.Import(value);
            get => DirectoryPermissions.Export();
        }
    }
}
