using System;
using Microsoft.Extensions.Logging;

namespace AyaNova.Api.ControllerHelpers
{




    /// <summary>
    /// Contains the current status of the server
    /// is injected everywhere for routes and others to check
    /// </summary>
    public class ApiServerState
    {

        //private ILogger log = AyaNova.Util.ApplicationLogging.CreateLogger<ApiServerState>();
        public enum ServerState
        {
            ///<summary>Unknown state, used for parsing</summary>
            UNKNOWN = 0,
            ///<summary>No access for anyone API completely locked down</summary>
            Closed = 1,
            ///<summary>Access only to API Operations routes</summary>
            OpsOnly = 2,
            ///<summary>Open for all users (default)</summary>
            Open = 3
        }

        private ServerState _currentState = ServerState.Closed;
        private ServerState _priorState = ServerState.Closed;
        private string _reason = string.Empty;
        private string _priorReason = string.Empty;
        private bool SYSTEM_LOCK = false;//really this is a license lock but not called that 

        public ApiServerState()
        {
        }



        internal void SetSystemLock(string reason)
        {
            //Lock down the server for license related issue
            //Still allows ops routes, treats as if server was set to closed even if they change it to open
            //only way to reset it is to fetch a valid license
            SetState(ServerState.OpsOnly, reason);
            SYSTEM_LOCK = true;
        }


        //WARNING: if in future this is used for anything other than a license then it will need to see if locked for another reason before unlocking
        //recommend putting a code number in the reason then looking to see if it has the matching code 
        internal void ClearSystemLock()
        {
            SYSTEM_LOCK = false;
            SetState(ServerState.Open, "");
        }

        /// <summary>
        /// Set the server state
        /// </summary>
        /// <param name="newState"></param>
        /// <param name="reason"></param>
        public void SetState(ServerState newState, string reason)
        {
            //No changes allowed during a system lock
            if (SYSTEM_LOCK) return;

            _reason = reason;//keep the reason even if the state doesn't change
            if (newState == _currentState) return;

            //Here we will likely need to trigger a notification to users if the state is going to be shutting down or is shut down
            _priorState = _currentState;//keep the prior state so it can be resumed easily
            _priorReason=_reason;//keep the original reason

            _currentState = newState;
        }

        /// <summary>
        /// Get the current state of the server
        /// </summary>
        /// <returns></returns>
        public ServerState GetState()
        {
            return _currentState;
        }

        /// <summary>
        /// Get the current reason for the state of the server
        /// </summary>
        /// <returns></returns>
        public string Reason
        {
            get
            {
                if (_currentState == ServerState.Open)
                {
                    return "";
                }
                else
                {
                    return $"Server state is: {_currentState.ToString()}, Reason: {_reason}";
                }
            }
        }


        public void SetOpsOnly(string reason)
        {
            //No changes allowed during a system lock
            if (SYSTEM_LOCK) return;
            SetState(ServerState.OpsOnly, reason);
        }


        public void SetClosed(string reason)
        {
            //No changes allowed during a system lock
            if (SYSTEM_LOCK) return;
            SetState(ServerState.Closed, reason);
        }

        public void SetOpen()
        {
            //No changes allowed during a system lock
            if (SYSTEM_LOCK) return;
            SetState(ServerState.Open, string.Empty);
        }

        public void ResumePriorState()
        {
            //No changes allowed during a system lock
            if (SYSTEM_LOCK) return;
            SetState(_priorState, _priorReason);
        }


        public bool IsOpsOnly
        {
            get
            {
                return _currentState == ServerState.OpsOnly;
            }
        }

        public bool IsOpen
        {
            get
            {
                return _currentState == ServerState.Open && !SYSTEM_LOCK;
            }
        }


        public bool IsClosed
        {
            get
            {
                return _currentState == ServerState.Closed || SYSTEM_LOCK;
            }
        }

        public bool IsOpenOrOpsOnly
        {
            get
            {
                return IsOpen || IsOpsOnly;
            }
        }

        public bool IsSystemLocked
        {
            get
            {
                return SYSTEM_LOCK;
            }
        }




    }//eoc


}//eons