using e_suite.UnitTestCore;
using Moq;
using RabbitMQ.Client;
using System.Text;

namespace e_suite.Messaging.Common.UnitTests.Helpers;

public class DatabaseMessageSenderTestBase : TestBase
{
    protected Mock<IChannel> Channel { get; set; } = new Mock<IChannel>();
    protected string? Body = null;

    protected DatabaseMessageSender DatabaseMessageSender { get; set; } = null!;

    public override async Task Setup()
    {
        await base.Setup();

        Channel.Setup(x => x.BasicPublishAsync(
            string.Empty,
            MessageQueueNames.Database,
            It.IsAny<bool>(),
            It.IsAny<BasicProperties>(),
            It.IsAny<ReadOnlyMemory<byte>>(),
            It.IsAny<CancellationToken>()
            ))
            .Returns(ValueTask.CompletedTask)
            .Callback<string, string, bool, IReadOnlyBasicProperties, ReadOnlyMemory<byte>, CancellationToken>(
                (exchange, routingKey, mandatory, basicProperties, body, cancellationToken) =>
                {
                    Body = Encoding.UTF8.GetString(body.ToArray());
                });

        var connection = new Mock<IConnection>();
        connection.Setup(x => x.CreateChannelAsync(It.IsAny<CreateChannelOptions>(), It.IsAny<CancellationToken>()))
            .ReturnsAsync(Channel.Object);

        var connectionFactoryMock = new Mock<IRabbitMqConnectionFactory>();
        connectionFactoryMock.Setup(x => x.CreateConnection()).Returns(connection.Object);

        DatabaseMessageSender = new DatabaseMessageSender(_configuration, connectionFactoryMock.Object);
    }

    public virtual Task TearDown()
    {
        DatabaseMessageSender.Dispose();
        return Task.CompletedTask;
    }
}

public class SigmaImportMessageSenderTestBase : TestBase
{
    protected Mock<IChannel> Channel { get; set; } = new Mock<IChannel>();
    protected string? Body = null;

    protected SigmaImportMessageSender SigmaImportMessageSender { get; set; } = null!;

    public override async Task Setup()
    {
        await base.Setup();

        Channel.Setup(x => x.BasicPublishAsync(
            string.Empty,
            MessageQueueNames.SigmaImport,
            It.IsAny<bool>(),
            It.IsAny<BasicProperties>(),
            It.IsAny<ReadOnlyMemory<byte>>(),
            It.IsAny<CancellationToken>()))
                .Returns(ValueTask.CompletedTask)
                .Callback<string, string, bool, IReadOnlyBasicProperties, ReadOnlyMemory<byte>, CancellationToken>((
                exchange,
                routineKey,
                   mandatory,
               basicProperties,
              body,
                 cancellationToken
                    ) =>
                    {
                        Body = Encoding.UTF8.GetString(body.ToArray());
                    });

        var connection = new Mock<IConnection>();
        connection.Setup(x => x.CreateChannelAsync(It.IsAny<CreateChannelOptions>(), It.IsAny<CancellationToken>()))
            .ReturnsAsync(Channel.Object);

        var connectionFactoryMock = new Mock<IRabbitMqConnectionFactory>();
        connectionFactoryMock.Setup(x => x.CreateConnection()).Returns(connection.Object);

        SigmaImportMessageSender = new SigmaImportMessageSender(_configuration, connectionFactoryMock.Object);
    }

    public virtual Task TearDown()
    {
        SigmaImportMessageSender.Dispose();
        return Task.CompletedTask;
    }
}