using Femto.Common.Domain;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;

namespace Femto.Common.Infrastructure;

public static class DbContextDomainExtensions
{
    public static async Task EmitDomainEvents(this DbContext context, ILogger logger, IPublisher publisher, CancellationToken cancellationToken)
    {
        var domainEvents = context
            .ChangeTracker.Entries<Entity>()
            .SelectMany(e =>
            {
                var events = e.Entity.DomainEvents;
                e.Entity.ClearDomainEvents();
                return events;
            })
            .ToList();

        logger.LogTrace("loaded {Count} domain events", domainEvents.Count);

        foreach (var domainEvent in domainEvents)
        {
            logger.LogTrace(
                "publishing {Type} domain event {Id}",
                domainEvent.GetType().Name,
                domainEvent.EventId
            );
            await publisher.Publish(domainEvent, cancellationToken);
        }

    }
}