using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using ScadaLink.Communication.Grpc;

namespace ScadaLink.Communication.Tests.Grpc;

public class SiteStreamGrpcClientFactoryTests
{
    private readonly ILoggerFactory _loggerFactory = NullLoggerFactory.Instance;

    [Fact]
    public void GetOrCreate_ReturnsSameClientForSameSite()
    {
        using var factory = new SiteStreamGrpcClientFactory(_loggerFactory);

        var client1 = factory.GetOrCreate("site-a", "http://localhost:5100");
        var client2 = factory.GetOrCreate("site-a", "http://localhost:5100");

        Assert.Same(client1, client2);
    }

    [Fact]
    public void GetOrCreate_ReturnsDifferentClientsForDifferentSites()
    {
        using var factory = new SiteStreamGrpcClientFactory(_loggerFactory);

        var client1 = factory.GetOrCreate("site-a", "http://localhost:5100");
        var client2 = factory.GetOrCreate("site-b", "http://localhost:5200");

        Assert.NotSame(client1, client2);
    }

    [Fact]
    public async Task RemoveSite_DisposesClient()
    {
        var factory = new SiteStreamGrpcClientFactory(_loggerFactory);

        var client1 = factory.GetOrCreate("site-a", "http://localhost:5100");
        await factory.RemoveSiteAsync("site-a");

        // After removal, GetOrCreate should return a new instance
        var client2 = factory.GetOrCreate("site-a", "http://localhost:5100");
        Assert.NotSame(client1, client2);
    }

    [Fact]
    public async Task RemoveSite_NonExistent_DoesNotThrow()
    {
        var factory = new SiteStreamGrpcClientFactory(_loggerFactory);
        await factory.RemoveSiteAsync("does-not-exist"); // Should not throw
    }

    [Fact]
    public async Task DisposeAsync_DisposesAllClients()
    {
        var factory = new SiteStreamGrpcClientFactory(_loggerFactory);

        factory.GetOrCreate("site-a", "http://localhost:5100");
        factory.GetOrCreate("site-b", "http://localhost:5200");

        await factory.DisposeAsync();

        // After dispose, creating new clients should work (new instances)
        // This tests that Dispose doesn't throw
    }
}
