using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using System.Timers;
using Aitex.Core.RT.Event;
namespace Aitex.Core.Account
{
    public enum AuthorizationStatusEnum
    {
        NoAuthorization,
        Authorizing,
        Granted,
        Rejected,
    }
    
    public static class Authorization
    {
        public static string Module { get; set; }
        static Authorization()
        {
            Module = "System";
            AuthorizedAccount = string.Empty;
            AuthorizedIP = string.Empty;
            AuthorizingAccount = string.Empty;
            AuthorizingIP = string.Empty;            
    //        Update();
            _timer = new Timer(3 * 60*1000);//3 minutes
            _timer.AutoReset = false;
            _timer.Elapsed += new ElapsedEventHandler(Timer_Elapsed);
        }
        static void Timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            if (_status == AuthorizationStatusEnum.Authorizing)
            {               
                Grant(true);
            }
        }        
        public static AuthorizationStatusEnum Status
        {
            get
            {
                return _status;
            }
        }
        public static bool IsAuthorizedAccount(string accountId, string ip)
        {
            if (string.IsNullOrWhiteSpace(AuthorizedAccount))
            {
                EV.PostMessage(Module, EventEnum.AccountWithoutAuthorization, accountId);
                return false;
            }
            if (ip == Utilities.Network.LocalIP && AuthorizedIP == Aitex.Core.Utilities.Network.LocalIP) return true;
            if (AuthorizedAccount != accountId)
            {
                EV.PostMessage(Module, EventEnum.AccountWithoutAuthorization, accountId);
                return false;
            }
            return true;
        }
        static bool CanAutoAuthorize(string accountId, string ip)
        {
            return string.IsNullOrWhiteSpace(AuthorizedAccount)     //未有授权用户
                    || (ip == Aitex.Core.Utilities.Network.LocalIP)                             //申请IP来自服务器同一地址
                    || (accountId == AuthorizedAccount);            //已授权账户
                 //|| (AuthorizedIP == ServerIP && ip == ServerIP)  //本地IP已授权,且本地账户申请权限 
        }
        public static string AuthorizedAccount
        {
            get;
            private set;
        }
        public static string AuthorizedIP
        {
            get;
            private set;
        }
        public static string AuthorizingAccount
        {
            get;
            private set;
        }
        public static string AuthorizingIP
        {
            get;
            private set;
        }
        /// 
        /// User applies operation & control authorization
        /// 
        /// client user
        /// client ip
        public static void Request(string accountId, string ip)
        {
            EV.PostMessage(Module,  EventEnum.OperationAuthorization, string.Format("{0} 在申请操控权", accountId));
            if (CanAutoAuthorize(accountId, ip))
            {
                AuthorizedAccount = accountId;
                AuthorizedIP = ip;
                EV.PostMessage(Module, EventEnum.OperationAuthorization, string.Format("{0} 获得操控权", AuthorizedAccount));
                _status = AuthorizationStatusEnum.Granted;
                Update();
                return;
            }
            AuthorizingAccount = accountId;
            AuthorizingIP = ip;
            _status = AuthorizationStatusEnum.Authorizing;
            Update();
            _timer.Start();
        }
        /// 
        /// Authorizing user aborts this authorization operation.
        /// 
        public static void Abort()
        {
            _timer.Stop();
            _status = AuthorizationStatusEnum.NoAuthorization;
            AuthorizingAccount = string.Empty;
            AuthorizingIP = string.Empty;
            Update();
        }
        /// 
        /// Authorized user grants or rejects the authorization
        /// 
        /// True: granted   False: Rejected
        public static void Grant(bool isGranted)
        {
            _timer.Stop();
            if (_status == AuthorizationStatusEnum.Granted) return;
            if (isGranted)
            {
                AuthorizedAccount = AuthorizingAccount;
                AuthorizedIP = AuthorizingIP;
                _status = AuthorizationStatusEnum.Granted;
                EV.PostMessage(Module, EventEnum.OperationAuthorization, string.Format("{0} 获得操控权", AuthorizedAccount));
            }
            else
            {
                _status = AuthorizationStatusEnum.Rejected;
                EV.PostMessage(Module, EventEnum.OperationAuthorization, string.Format("{0} 拒绝转交操控权", AuthorizedAccount));
            }
            Update();
        }
        public static void Exit(string accountId)
        {            
            if (accountId == AuthorizedAccount)
            {
                AuthorizedAccount = string.Empty;
                AuthorizedIP = string.Empty;  
              
                Abort();            
            }
            else if (accountId == AuthorizingAccount)
            {
                Abort();
            }
        }
        #region private
        static Timer _timer = new Timer();
        static AuthorizationStatusEnum _status = AuthorizationStatusEnum.NoAuthorization;
        static void Update()
        {
            //ViewModelManager.UpdateAttribute(ChamberSet.Transfer, "Authorization", "AuthorizedAccount", AuthorizedAccount);
            //ViewModelManager.UpdateAttribute(ChamberSet.Transfer, "Authorization", "AuthorizedIP", AuthorizedIP);
            //ViewModelManager.UpdateAttribute(ChamberSet.Transfer, "Authorization", "AuthorizingAccount", AuthorizingAccount);
            //ViewModelManager.UpdateAttribute(ChamberSet.Transfer, "Authorization", "AuthorizingIP", AuthorizingIP);
            //ViewModelManager.UpdateAttribute(ChamberSet.Transfer, "Authorization", "AuthorizationStatus", Status.ToString());
            //ViewModelManager.UpdateAttribute(ChamberSet.Transfer, "Authorization", "ServerIP", Aitex.Core.Utilities.Network.Network.LocalIP);
        }
        #endregion
    }
}