using System;
using System.Text;
using System.Web;
using System.Net;
using System.Security.Principal;
using Microsoft.Extensions.Logging;
using NLog.Config;
using System.IO;
using NLog;

namespace ProfitGroup.SampleService.Core.Middlewares
{
    /// <summary>
    /// Представляет промежуточное ПО для базовой аутентификации.
    /// </summary>
    public class BasicAuthMiddleware : IHttpModule
    {

        private static NLog.ILogger Logger
        {
            get
            {
                var loggerConfig = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "nlog.config");
                LogManager.Setup().LoadConfigurationFromFile(loggerConfig);
                LogManager.Configuration = new XmlLoggingConfiguration(loggerConfig);

                return LogManager.GetCurrentClassLogger();
            }
        }
        //private readonly ILogger _logger;

        //public BasicAuthMiddleware(ILoggerFactory loggerFactory)
        //{
        //    _logger = loggerFactory.CreateLogger(typeof(BasicAuthMiddleware));
        //}

        /// <summary>
        /// Инициализирует промежуточное ПО и подписывает обработчик события аутентификации запроса.
        /// </summary>
        public void Init(HttpApplication context)
        {
            context.AuthenticateRequest += OnAuthenticateRequest;
        }

        /// <summary>
        /// Освобождает ресурсы, используемые промежуточным ПО.
        /// </summary>
        public void Dispose()
        {

        }

        /// <summary>
        /// Обработчик события аутентификации запроса.
        /// </summary>
        private void OnAuthenticateRequest(object sender, EventArgs e)
        {
            var context = ((HttpApplication)sender).Context;
            var authHeader = context.Request.Headers["Authorization"];

            if (string.IsNullOrEmpty(authHeader) || !authHeader.StartsWith("Basic"))
            {
                Logger.Error("Авторизация пропущена. Передан пустой Basic Auth Header");
                return;
            }

            var encodedCredentials = authHeader.Substring("Basic".Length).Trim();
            var credentialsBytes = Convert.FromBase64String(encodedCredentials);
            var credentials = Encoding.ASCII.GetString(credentialsBytes);
            var usernamePassword = credentials.Split(':');

            if (usernamePassword.Length != 2) return;

            var username = usernamePassword[0];
            var password = usernamePassword[1];

            if (IsUserValid(username, password))
            {
                Logger.Info("Успешная авторизация");
                context.User = new GenericPrincipal(new GenericIdentity(username), null);
            }
            else
            {
                Logger.Error("Ошибка авторизации, неверный логин или пароль");
                context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
                context.Response.AddHeader("WWW-Authenticate", "Basic realm=\"Your Realm\"");
                context.Response.End();
            }
        }

        /// <summary>
        /// Проверяет, является ли пользователь допустимым.
        /// </summary>
        private bool IsUserValid(string username, string password)
        {
            // ToDo: Сменить пароль при переносе решения
            
            // APP02
            return username == "S4test" && password == "Era7%agEr12#L";
                        
            // Productive
            // return username == "S4test" && password == "lMxeTqMIH04R8mCE"; 
        }
    }
}
