using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using AsbCloudApp.Data.SAUB;
using AsbCloudApp.Repositories;
using AsbCloudDb.Model;
using AsbCloudInfrastructure.Background;
using AsbCloudInfrastructure.Services.SAUB;
using Microsoft.Extensions.DependencyInjection;
using NSubstitute;
using Xunit;

namespace AsbCloudInfrastructure.Tests.Services.SAUB;

public class TelemetryDataSaubCacheTests
{
    private static object _lock = new object();
    private const int idTelemetry = 1;

    private readonly IEnumerable<TelemetryDataSaubDto> fakeTelemetries = new[]
    {
        new TelemetryDataSaubDto()
    };

    private readonly IServiceProvider serviceProviderMock = Substitute.For<IServiceProvider>();

    private readonly TelemetryDataCache<TelemetryDataSaubDto> telemetryDataCache;
    private readonly Type telemetryDataCacheType;

    public TelemetryDataSaubCacheTests()
    {
        serviceProviderMock.GetService<BackgroundWorker>().Returns(new BackgroundWorker(serviceProviderMock));
        telemetryDataCache = TelemetryDataCache<TelemetryDataSaubDto>.GetInstance<TelemetryDataSaub>(serviceProviderMock);
        telemetryDataCacheType = telemetryDataCache.GetType();

    }

    [Fact]
    public void AddRange_ShouldReturn_AddedElementToCache()
    {
        //arrange
        telemetryDataCache.AddRange(idTelemetry, fakeTelemetries);
        
        telemetryDataCacheType
        .GetField("isLoading", BindingFlags.NonPublic | BindingFlags.Instance)!
        .SetValue(telemetryDataCache, false);

        //act
        var lastTelemetry = telemetryDataCache.GetLastOrDefault(idTelemetry);

        //assert
        Assert.Equal(lastTelemetry, fakeTelemetries.Last());
    }

    [Fact]
    public void AddRange_ShouldReturn_NotAddedToCache()
    {
        //arrange
        telemetryDataCache.AddRange(idTelemetry, fakeTelemetries);
        telemetryDataCacheType
            .GetField("isLoading", BindingFlags.NonPublic | BindingFlags.Instance)!
            .SetValue(telemetryDataCache, true);

        //act
        var lastTelemetry = telemetryDataCache.GetLastOrDefault(idTelemetry);

        //assert
        Assert.Null(lastTelemetry);
    }
}