using System;
using System.IO;
using System.Reflection;
using AutoMapper;
using InternshipSystem.Api.Controllers;
using InternshipSystem.Api.Extensions;
using InternshipSystem.Api.ModelBinders;
using InternshipSystem.Api.Options;
using InternshipSystem.Api.Security;
using InternshipSystem.Api.Services;
using InternshipSystem.Core;
using InternshipSystem.Repository;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;

namespace InternshipSystem.Api
{
    public class Startup
    {
        private IConfiguration Configuration { get; }
        
        public Startup(IConfiguration configuration) =>
            Configuration = configuration;

        public void ConfigureServices(IServiceCollection services)
        {
            services
                .Configure<SecurityOptions>(Configuration.GetSection("SecurityOptions"));
            
            services
                .AddStudentAuthentication()
                .AddAuthorization(o =>
                {
                    o.AddPolicy(Policies.RegisteredOnly, policy => policy.RequireClaim("Edition"));
                })
                .AddHttpClient<GutCasClient>();

            services
                .AddDbContext<InternshipDbContext>(o =>
                    o.UseNpgsql(Configuration.GetConnectionString("InternshipDatabase")))
                .AddDbContext<InternshipPractiseSupervisorDbContext>(o =>
                    o.UseNpgsql(Configuration.GetConnectionString("InternshipDatabase")))
                .AddScoped<DatabaseFiller>()
                .AddScoped<IInternshipService, InternshipService>()
                .AddScoped<JwtTokenService>()
                .AddAutoMapper(cfg => cfg.AddProfile<ApiProfile>());
            
            services
                .AddSwaggerGen(options =>
                {
                    options.SwaggerDoc("v1", new OpenApiInfo {Title = "InternshipSystem Api - TEST", Version = "v1"});
                    var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
                    var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
                    options.IncludeXmlComments(xmlPath);
                })
                .AddControllers(o => { o.ModelBinderProviders.Insert(0, new UserBinderProvider()); });
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            
            app
                .UseHttpsRedirection()
                .UseRouting()
                .UseAuthentication()
                .UseAuthorization()
                .UseCors()
                .UseEndpoints(endpoints =>
                {
                    endpoints.MapControllers();
                })
                .UseSwagger()
                .UseSwaggerUI(options => options.SwaggerEndpoint(Path.Join(Configuration.GetValue<string>("ApiPrefix"), "/swagger/v1/swagger.json"), "InternshipSystem Api"));
        }
    }
}