using System;
using System.IO;
using System.Linq;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.ResponseCompression;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json.Serialization;
using Microsoft.IdentityModel.Tokens;
using Microsoft.AspNetCore.Authentication.JwtBearer;

using CommonHelpers;

namespace BookRegistry.Server {

//**************************************************************************************************
public class Startup {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
static HConsole CON => HConsole.StdConIO;
//==================================================================================================

public IConfiguration Configuration { get; }

//==================================================================================================

/// <exception cref="ArgumentNullException" />
public Startup(IConfiguration configuration) =>
   Configuration = HArgChecking.NN( configuration );

//==================================================================================================

// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
   new StartupData( Configuration ).ObtainConfigParameters();
   LocaleHlp.UpdateCulture();

   services.AddControllersWithViews();
   services.AddRazorPages();

   services.AddMvc().AddNewtonsoftJson();
   services.AddResponseCompression(opts =>
   {
      opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
         new[]{ "application/octet-stream" });
   });
   services.AddAuthentication( JwtBearerDefaults.AuthenticationScheme )
      .AddJwtBearer(options =>
      {
         options.RequireHttpsMetadata = false;
         options.TokenValidationParameters = new TokenValidationParameters
         {
            ValidateIssuer = true,
            ValidIssuer = AuthOptions.Issuer,
 
            ValidateAudience = true,
            ValidAudience = AuthOptions.Audience,
            ValidateLifetime = true,
            ClockSkew = TimeSpan.Zero,
 
            IssuerSigningKey = AuthOptions.GetSymmetricSecurityKey(),
            ValidateIssuerSigningKey = true
         };
      });
/*
   services.AddAuthorization(options =>
   {
      options.AddPolicy("",
         policy => policy.RequireClaim( "" ));
   });
*/
   PasswordMasking.Prepare();
   CON.PrintAlignedList(
      new[]{ "Server", "Database", "DB-language (tech.)", "Culture neutral" },
      new[]{ StartupData.ServerName, StartupData.DatabaseName,
             StartupData.DatabaseLanguage, StartupData.UseInvariantCulture.ToString() } );
}

//==================================================================================================

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
/*
   Program.SpecifyDevelopmentBehaviour( env.IsDevelopment() ||
      HString.Equals( env.EnvironmentName, "DebugExpose", true ) ); // case insensitive comparison
*/
   // Saved environment properties are used while static web assets feature doesn't work correctly:
   Program.SpecifyDevelopmentBehaviour( ProgramStart.IsDevelopmentEnvironment ||
      HString.Equals( ProgramStart.EnvironmentName, "DebugExpose", true ) ); // case insensitive comparison

   // This is in order to use fatal error message box in case of fatal breakdown.
   // Such system GUI-box is possible only in Win32-version of CommonHelpers library.
   // In any way, the library attempts to open such an error in browser
   // (specially prepared html-file in associated program).
   HProgram.SpecifyInteractsWithDesktop(
      Program.DevelopmentBehaviour && Program.IsDebugConfiguration );

   CON.PrintSplitter();
   CON.PrintDashAlignedList(
      new string[]{ "Current dir.", "Environment name", "Development" },
      new string[]{ Directory.GetCurrentDirectory(), ProgramStart.EnvironmentName,//env.EnvironmentName ?? "",
                    Program.DevelopmentBehaviour.ToString() } );
   CON.PrintShallowSplitter();

   app.UseResponseCompression();

   if ( Program.DevelopmentBehaviour )
   {
      app.UseDeveloperExceptionPage();
      app.UseWebAssemblyDebugging();
   }
   else
   {
      app.UseExceptionHandler( "/Error" );
      // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
      app.UseHsts();
   }

   app.UseHttpsRedirection();
   app.UseBlazorFrameworkFiles();
   app.UseStaticFiles();

   app.UseRouting();

   app.UseAuthentication();
   app.UseAuthorization();

   app.UseEndpoints(endpoints =>
   {
      endpoints.MapRazorPages();
      endpoints.MapControllers();
      endpoints.MapFallbackToFile( "index.html" );
   });
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // Startup
//**************************************************************************************************

} // BookRegistry.Server
