using MediatR;
using MediatR.Pipeline;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Netmash.Extensions.Caching;
using Netmash.Extensions.Swagger;
using Netmash.Extensions.Swagger.Constants;
using Netmash.Infrastructure.DatabaseMigration;
using Netmash.Infrastructure.DatabaseMigration.Constants;
using Netmash.Security.Authentication.Tuitio;
using NetworkResurrector.Agent.Wrapper;
using NetworkResurrector.Api.Application;
using NetworkResurrector.Api.Authorization;
using NetworkResurrector.Api.Domain.Data;
using NetworkResurrector.Server.Wrapper;
using Newtonsoft.Json;

namespace NetworkResurrector.Api.Extensions
{
    public static class StartupExtensions
    {
        public static void ConfigureServices(this IServiceCollection services, IConfiguration configuration)
        {
            services.AddControllers()
                .AddNewtonsoftJson(o => o.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc);

            // Add basic authentication 
            services.AddTuitioAuthentication(configuration.GetSection("Tuitio")["BaseAddress"]);

            // Add authorization
            services.AddLocalAuthorization();

            // Add cache service
            services.AddCacheService();

            // MediatR
            services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblyContaining<Application.Queries.GetMachines>());
            services.AddScoped(typeof(IPipelineBehavior<,>), typeof(RequestPreProcessorBehavior<,>));
            services.AddScoped(typeof(IPipelineBehavior<,>), typeof(RequestPostProcessorBehavior<,>));

            // AutoMapper
            services.AddAutoMapper(typeof(Application.Mappings.MappingProfile).Assembly);

            // Swagger
            services.AddSwagger("NetworkResurrector API", AuthorizationType.Tuitio);

            // Add network resurrector server services
            services.UseResurrectorServices(configuration.GetSection("NetworkResurrectorServer")["BaseAddress"]);

            // Add network resurrector agent services
            services.UseResurrectorAgentServices();

            // Data access
            services.AddMigration(DatabaseType.SQLServer, MetadataLocation.Database);
            services.AddDataAccess();

            // Application services
            services.AddApplicationServices();

            // Messaging
            services.AddMessageBus(configuration);
        }

        public static void Configure(this IApplicationBuilder app)
        {
            // global cors policy
            app.UseCors(x => x.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
            app.UseExceptionHandler("/error");

            app.UseRouting();
            app.UseAuthentication();
            app.UseAuthorization();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
            app.ConfigureSwagger("NetworkResurrector API");

            app.UseMigration();
        }
    }
}
