using AyCode.Core.Serializers;
using AyCode.Core.Tests.TestModels;
using AyCode.Services.Server.SignalRs;
using AyCode.Services.SignalRs;

namespace AyCode.Services.Server.Tests.SignalRs.SignalRDatasources;

/// <summary>
/// Base class for SignalR DataSource tests with full round-trip coverage.
/// Tests the complete path: DataSource -> SignalRClient -> SignalRHub -> Service -> Response -> SignalRClient -> DataSource
/// Derived classes specify the serializer type and collection type.
/// </summary>
/// <typeparam name="TDataSource">The concrete DataSource type</typeparam>
/// <typeparam name="TIList">The inner list type (List or AcObservableCollection)</typeparam>
public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
    where TDataSource : AcSignalRDataSource<TestOrderItem_All_True, int, TIList>
    where TIList : class, IList<TestOrderItem_All_True>
{
    protected abstract AcSerializerOptions SerializerOption { get; }
    protected abstract TDataSource CreateDataSource(TestableSignalRClient2 client, SignalRCrudTags crudTags);
    
    protected TestLogger _logger = null!;
    protected TestableSignalRHub2 _hub = null!;
    protected TestableSignalRClient2 _client = null!;
    protected TestSignalRService2 _service = null!;
    protected SignalRCrudTags _crudTags = null!;

    [TestInitialize]
    public void Setup()
    {
        _logger = new TestLogger();

        _hub = new TestableSignalRHub2();
        _service = new TestSignalRService2();
        _client = new TestableSignalRClient2(_hub, _logger);

        _hub.SetSerializerType(SerializerOption);
        _hub.RegisterService(_service, _client);

        _crudTags = new SignalRCrudTags(
            TestSignalRTags.DataSourceGetAll,
            TestSignalRTags.DataSourceGetItem,
            TestSignalRTags.DataSourceAdd,
            TestSignalRTags.DataSourceUpdate,
            TestSignalRTags.DataSourceRemove
        );
    }
}