namespace Hims.Api
{
    using CorePush.Apple;
    using CorePush.Google;
    using Extensions;
    using Hangfire;
    using Hangfire.MemoryStorage;
    using Hims.Api.Models.PushNotifications.Service;
    using IdentityServer4.EntityFramework.DbContexts;
    using Infrastructure.Configurations.Middleware;
    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.EntityFrameworkCore;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    using Middleware;

    /// <summary>
    /// The startup.
    /// </summary>
    public class Startup
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="Startup"/> class.
        /// </summary>
        /// <param name="configuration">
        /// The configuration.
        /// </param>
        public Startup(IConfiguration configuration) => this.Configuration = configuration;

        /// <summary>
        /// Gets the configuration.
        /// </summary>
        public IConfiguration Configuration { get; }

        /// <summary>
        /// The configure services.
        /// </summary>
        /// <param name="services">
        /// The services.
        /// </param>
        public void ConfigureServices(IServiceCollection services)
        {
            services.RegisterServices();

            services.AddTransient<INotificationService, NotificationService>();
            services.AddHttpClient<FcmSender>();
            services.AddHttpClient<ApnSender>();

            services.Configure<IISServerOptions>(options =>
            {
                options.MaxRequestBodySize = long.MaxValue;
            });

            services.AddHangfire(configuration => configuration.UseMemoryStorage());
            services.AddHangfireServer();

            ConfigurationMiddleware.ConfigureServices(services, this.Configuration);
            AuthenticationMiddleware.ConfigureServices(services, this.Configuration);
            SwaggerMiddleware.ConfigureServices(services, this.Configuration);
        }

        /// <summary>
        /// The configure.
        /// </summary>
        /// <param name="app">
        /// The app.
        /// </param>
        /// <param name="env">
        /// The env.
        /// </param>
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())
            {
                serviceScope.ServiceProvider.GetRequiredService<PersistedGrantDbContext>().Database.Migrate();
                serviceScope.ServiceProvider.GetRequiredService<ConfigurationDbContext>().Database.Migrate();
            }

            var assembly = this.GetType().Assembly;
            app.Register(env, this.Configuration, assembly);
        }
    }
}