using AuthStudy.Authentication.Basic.Events;

using Microsoft.AspNetCore.Authentication;

namespace AuthStudy.Authentication.Basic
{
    public class BasicAuthenticationOptions : AuthenticationSchemeOptions
    {
        private string _realm = string.Empty;

        /// <summary>
        /// 创建用默认值初始化的选项的实例
        /// </summary>
        public BasicAuthenticationOptions()
        {
        }

        /// <summary>
        /// 获取或设置在WWW-Authenticate标头中发送的 Realm
        /// </summary>
        /// <remarks>
        /// Realm值(区分大小写)与正在访问的服务器的规范根URL相结合,定义了保护空间。
        /// 这些领域允许将服务器上受保护的资源划分为一组保护空间,每个空间都有自己的身份验证方案和/或授权数据库。
        /// </remarks>
        public string Realm
        {
            get
            {
                return _realm;
            }

            set
            {
                if (!string.IsNullOrEmpty(value) && !IsAscii(value))
                {
                    throw new ArgumentException("Realm must be US ASCII");
                }

                _realm = value;
            }
        }


        /// <summary>
        ///  获取或设置一个标志,该标志指示是否将在未经授权的响应上取消WWW-Authenticate标头
        /// </summary>
        /// <remarks>
        ///  身份验证方案控制浏览器UI,并允许浏览器以正确的方式进行身份验证,弹出一个允许输入用户名和密码的UI
        ///  有些用户可能希望对JavaScript XMLHttpRequest请求抑制这种行为
        ///  将此标志设置为True将抑制WWW-Authenticate标头,从而抑制浏览器登录提示,只需发送401状态代码,您就必须对自己做出反应。
        /// </remarks>
        public bool SuppressWWWAuthenticateHeader
        {
            get; set;
        }

        /// <summary>
        /// 获取或设置一个标志,该标志指示处理程序是否会提示对HTTP请求进行身份验证
        /// </summary>
        public bool AllowInsecureProtocol
        {
            get; set;
        } = true;

        /// <summary>
        /// 事件
        /// </summary>
        public new BasicAuthenticationEvents? Events

        {
            get { return (BasicAuthenticationEvents?)base.Events; }

            set { base.Events = value; }
        }


        /// <summary>
        /// 判断给定的字符串是否全部是ASCII字符
        /// </summary>
        private static bool IsAscii(string input)
        {
            foreach (char c in input)
            {
                if (c < 32 || c >= 127)
                {
                    return false;
                }
            }

            return true;
        }
    }
}