using ZB.MOM.WW.GalaxyRepository;

namespace ZB.MOM.WW.MxGateway.IntegrationTests.Galaxy;

[Collection(LiveResourcesCollection.Name)]
[Trait("Category", "LiveGalaxy")]
public sealed class GalaxyRepositoryLiveTests
{
    /// <summary>Verifies that the Galaxy Repository can establish a live connection to the ZB database.</summary>
    /// <returns>A task that represents the asynchronous operation.</returns>
    [LiveGalaxyRepositoryFact]
    public async Task TestConnection_AgainstZb_Succeeds()
    {
        ZB.MOM.WW.GalaxyRepository.GalaxyRepository repository = CreateRepository();

        bool ok = await repository.TestConnectionAsync(CancellationToken.None);

        Assert.True(ok, "TestConnectionAsync should return true against the ZB database.");
    }

    /// <summary>Verifies that the last deploy time can be retrieved from the ZB database.</summary>
    /// <returns>A task that represents the asynchronous operation.</returns>
    [LiveGalaxyRepositoryFact]
    public async Task GetLastDeployTime_AgainstZb_ReturnsTimestamp()
    {
        ZB.MOM.WW.GalaxyRepository.GalaxyRepository repository = CreateRepository();

        DateTime? lastDeploy = await repository.GetLastDeployTimeAsync(CancellationToken.None);

        Assert.NotNull(lastDeploy);
    }

    /// <summary>Verifies that the hierarchy can be retrieved from the ZB database.</summary>
    /// <returns>A task that represents the asynchronous operation.</returns>
    [LiveGalaxyRepositoryFact]
    public async Task GetHierarchy_AgainstZb_ReturnsObjects()
    {
        ZB.MOM.WW.GalaxyRepository.GalaxyRepository repository = CreateRepository();

        List<GalaxyHierarchyRow> rows = await repository.GetHierarchyAsync(CancellationToken.None);

        Assert.NotEmpty(rows);
        Assert.All(rows, row =>
        {
            Assert.True(row.GobjectId > 0);
            Assert.False(string.IsNullOrEmpty(row.TagName));
            Assert.False(string.IsNullOrEmpty(row.BrowseName));
        });
    }

    /// <summary>Verifies that object attributes can be retrieved from the ZB database.</summary>
    /// <returns>A task that represents the asynchronous operation.</returns>
    [LiveGalaxyRepositoryFact]
    public async Task GetAttributes_AgainstZb_ReturnsAtLeastOneAttribute()
    {
        ZB.MOM.WW.GalaxyRepository.GalaxyRepository repository = CreateRepository();

        List<GalaxyAttributeRow> rows = await repository.GetAttributesAsync(CancellationToken.None);

        Assert.NotEmpty(rows);
        Assert.All(rows, row =>
        {
            Assert.True(row.GobjectId > 0);
            Assert.False(string.IsNullOrEmpty(row.AttributeName));
            Assert.False(string.IsNullOrEmpty(row.FullTagReference));
        });
    }

    private static ZB.MOM.WW.GalaxyRepository.GalaxyRepository CreateRepository() => new(new GalaxyRepositoryOptions
    {
        ConnectionString = LiveGalaxyRepositoryFactAttribute.ConnectionString,
        CommandTimeoutSeconds = 30,
    });
}
