using IntegrationKSSS.WebService.Infrastructure.Cryptography;
using IntegrationKSSS.WebService.Infrastructure.Data;
using IntegrationKSSS.WebService.Infrastructure.Handlers;
using IntegrationKSSS.WebService.Infrastructure.Repositories;
using IntegrationKSSS.WebService.Infrastructure.Services;
using Microsoft.AspNetCore.Authentication;
using Microsoft.EntityFrameworkCore;
using NLog;
using NLog.Web;
using RouteHandler = IntegrationKSSS.WebService.Infrastructure.RouteHandlers.RouteHandler;
using IRouteHandler = IntegrationKSSS.WebService.Infrastructure.RouteHandlers.IRouteHandler;
using NLog.Config;
using ILogger = NLog.ILogger;
using Microsoft.AspNetCore.Authorization;

namespace IntegrationKSSS.WebService.Infrastructure.Configurations;

/// <summary>
/// Configuration of the WEB API
/// </summary>
public static class ApplicationConfiguration
{
    #region Methods
    /// <summary>
    /// Getting a logger
    /// </summary>
    /// <returns>Logger</returns>
    private static ILogger GetLogger()
    {
        string fileName = string.Empty;
#if DEBUG
        fileName = Path.GetFullPath(@"../../IntegrationKSSS/IntegrationKSSS.WebService/NLog.config");
#endif
#if !DEBUG
            fileName = $"{Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)}/NLog.config";
#endif


        LogManager.Configuration = new XmlLoggingConfiguration(fileName);
        return LogManager.GetCurrentClassLogger();
    }
    /// <summary>
    /// Adding middleware, services and functions
    /// </summary>
    /// <param name="webApplicationBuilder"></param>
    public static void RegisterBuilder(WebApplicationBuilder webApplicationBuilder)
    {
        var logger = GetLogger();

        try
        {
            webApplicationBuilder.Services.AddEndpointsApiExplorer();
            webApplicationBuilder.Logging.ClearProviders();
            webApplicationBuilder.Host.UseNLog();
            webApplicationBuilder.Services.AddSwaggerGen();
            webApplicationBuilder.Services.AddSingleton(logger);

            var connectionString = webApplicationBuilder.Configuration["ConnectionStrings:MicrosoftSqlServer"]
                                                        .DecryptString(AesConfiguration.Key, AesConfiguration.IV);
            webApplicationBuilder.Services.AddDbContext<RDnLDbContext>(options =>
                                                                       options.UseSqlServer(connectionString));
            webApplicationBuilder.Services.AddScoped<IAuthService, AuthService>();
            webApplicationBuilder.Services.AddScoped<IKsssRepository, KsssRepository>();
            webApplicationBuilder.Services.AddTransient<IRouteHandler, RouteHandler>();
            webApplicationBuilder.Services.AddAuthentication("BasicAuthentication")
                                          .AddScheme<AuthenticationSchemeOptions, BasicAuthenticationHandler>("BasicAuthentication", options => { });
            webApplicationBuilder.Services.AddAuthorization(options =>
            {
                options.AddPolicy("BasicAuthentication", new AuthorizationPolicyBuilder("BasicAuthentication").RequireAuthenticatedUser().Build());
            });
        }
        catch (Exception ex)
        {
            logger.Error(ex, "Stopped web api because of exception");
            throw;
        }
        finally
        {
            LogManager.Shutdown();
        }

    }
    /// <summary>
    /// Using middleware, services and functions
    /// </summary>
    /// <param name="webApplication"></param>
    public static void RegisterApplication(WebApplication webApplication)
    {
        if (webApplication.Environment.IsDevelopment())
        {
            webApplication.UseSwagger();
            webApplication.UseSwaggerUI();
        }
        webApplication.UseAuthentication();
        webApplication.UseAuthorization();
        webApplication.Services.GetServices<IRouteHandler>().ToList().ForEach(c => c.Register(webApplication));

    } 
    #endregion
}

