using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using BS.Shared;

namespace BeWo.Data.Entities
{
	public class ApplicationUser : BeWoEntityBase
	{
		public static string PropertyName_Employee = "Employee";

		public static string PropertyName_HashedPassword = "HashedPassword";

		public static string PropertyName_Salt = "Salt";

		public static string PropertyName_LoginName = "LoginName";

		public static string PropertyName_SettingList = "SettingList";

		public static string PropertyName_UserGroups = "UserGroups";

		public static string PropertyName_ResetPasswordInfos = "ResetPasswordInfos";

        public static string PropertyName_Zeitstempel = "TimeStamp";

		private readonly byte[] _Rc2IV = {35, 138, 177, 253, 227, 63, 2, 27};

		private readonly byte[] _Rc2Key = {174, 130, 219, 185, 185, 221, 96, 50, 37, 212, 81, 121, 71, 206, 130, 153};

		private Employee _Employee;

		private string _HashedPassword;

		private string _LoginName;
		private IList<ResetPasswordInfo> _ResetPasswordInfos;

		private string _Salt;

		private IList<Settings> _SettingList;

		private IList<UserGroup> _UserGroups;

        private DateTime? _Zeitstempel;


		public ApplicationUser()
		{
			_Tid = TableID.ApplicationUser;
		}

		public virtual Employee Employee
		{
			get { return _Employee; }

			set
			{
				if (AreDifferent(_Employee, value))
				{
					_Employee = value;
				}
			}
		}

		public virtual string HashedPassword
		{
			get { return _HashedPassword; }

			set
			{
				if (AreDifferent(_HashedPassword, value))
				{
					_HashedPassword = value;
				}
			}
		}

		public virtual string LoginName
		{
			get { return _LoginName; }

			set
			{
				if (AreDifferent(_LoginName, value))
				{
					_LoginName = value;
				}
			}
		}

		public virtual string Salt
		{
			get { return _Salt; }

			set
			{
				if (AreDifferent(_Salt, value))
				{
					_Salt = value;
				}
			}
		}

		public virtual string RC2EncryptedHash
		{
			get
			{
				string lResult = string.Empty;
				var lRc2CSP = new RC2CryptoServiceProvider();
				ICryptoTransform lEncryptor = lRc2CSP.CreateEncryptor(_Rc2Key, _Rc2IV);

				using (var msEncrypt = new MemoryStream())
				{
					using (var csEncrypt = new CryptoStream(msEncrypt, lEncryptor, CryptoStreamMode.Write))
					{
						byte[] toEncrypt = Encoding.UTF8.GetBytes(HashedPassword);

						csEncrypt.Write(toEncrypt, 0, toEncrypt.Length);
						csEncrypt.FlushFinalBlock();

						byte[] encrypted = msEncrypt.ToArray();
						lResult = BitConverter.ToString(encrypted);
					}
				}
				if (!String.IsNullOrEmpty(lResult))
					lResult = lResult.Replace("-", "").ToLower();

				return lResult;
			}
		}

		public virtual IList<Settings> SettingList
		{
			get { return _SettingList ?? (_SettingList = new List<Settings>()); }

			set
			{
				if (AreDifferent(_SettingList, value))
				{
					_SettingList = value;
				}
			}
		}

		public virtual IList<UserGroup> UserGroups
		{
			get { return _UserGroups ?? (_UserGroups = new List<UserGroup>()); }

			set
			{
				if (AreDifferent(_UserGroups, value))
				{
					_UserGroups = value;
				}
			}
		}

		public virtual IList<ResetPasswordInfo> ResetPasswordInfos
		{
			get { return _ResetPasswordInfos ?? (_ResetPasswordInfos = new List<ResetPasswordInfo>()); }

			set
			{
				if (AreDifferent(_ResetPasswordInfos, value))
					_ResetPasswordInfos = value;
			}
		}

		public virtual void ChangePassword(string pPassword)
		{
			var lMD5 = new MD5CryptoServiceProvider();
			string lHash = BitConverter.ToString(lMD5.ComputeHash(Encoding.UTF8.GetBytes(String.Format("{0}_{1}_{2}", Salt, pPassword, "o238rRndguK4Fh8dsfkhwon54H8n3qo4itv8nz3o4LvnzQs0npmwEp"))));
			lHash = BitConverter.ToString(lMD5.ComputeHash(Encoding.UTF8.GetBytes(lHash)));
			HashedPassword = lHash;
		}

		public virtual bool CheckRC2Password(string pRC2Hash)
		{
			return pRC2Hash.Equals(RC2EncryptedHash);
		}

		public virtual void InitSalt()
		{
			var lMD5 = new MD5CryptoServiceProvider();
			string lHash = BitConverter.ToString(lMD5.ComputeHash(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString())));

			Salt = lHash;
		}

        public virtual DateTime? Zeitstempel
        {
            get { return _Zeitstempel; }

            set
            {
                if (AreDifferent(_Zeitstempel, value))
                {
                    _Zeitstempel = value;
                }
            }
        }
	}
}