using Cortex.Mediator.DependencyInjection;
using Serilog;
using Serilog.Events;
using Cortex.Mediator.Commands;
using Cortex.Mediator.Queries;
using CortexMediatorDemo.API.CQRS.Commands;
using CortexMediatorDemo.API.CQRS.PipelineBehaviors;
using CortexMediatorDemo.API.CQRS.Queries;
using CortexMediatorDemo.API.Domain;
using CortexMediatorDemo.API.Services;
using Cortex.Mediator.Behaviors;
using Cortex.Mediator.Notifications;
using CortexMediatorDemo.API.CQRS.NotificationHandlers;

var builder = WebApplication.CreateBuilder(args);

Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Information()
    .MinimumLevel.Override("Microsoft", LogEventLevel.Information)
    .Enrich.FromLogContext()
    .WriteTo.File("Logs/log-.txt", rollingInterval: RollingInterval.Day)
    .CreateLogger();

builder.Host.UseSerilog();

// Add services to the container.
builder.Services.AddTransient<INotificationService, NotificationService>();

// register the commands, queries and the cortex mediator
builder.Services.AddScoped<ICommandHandler<BookPurchaseCommand>, BookPurchaseCommandHandler>();
builder.Services.AddScoped<IQueryHandler<BookByIdQuery, Book>, BookByIdQueryHandler>();
builder.Services.AddScoped(typeof(ICommandPipelineBehavior<>), typeof(LoggingPipelineBehavior<>));
builder.Services.AddScoped(typeof(IQueryPipelineBehavior<,>), typeof(LoggingPipelineBehavior<,>));
builder.Services.AddScoped(typeof(ICommandPipelineBehavior<>), typeof(NotificationPipelineBehavior<>));

#region Some comments to explain the use of the open generic types
// When registering these as services using , we use `<>` and `<,>`
// to tell the dependency injection system that these are open generic types,
// and it should create the appropriate closed generic types when needed.
// The number of commas inside the angle brackets corresponds to one less than
// the number of type parameters (so no commas for one parameter, one comma for
// two parameters, etc.).
#endregion

builder.Services.AddCortexMediator(
    builder.Configuration,
    [typeof(Program)],
    options => 
    {
        // Register the pipeline behaviors (not required if none comment out)
    }
);

builder.Services.AddControllers();
// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
builder.Services.AddOpenApi();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.MapOpenApi();
}

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();