using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using ZB.MOM.WW.LmxProxy.Client.Domain;

namespace ZB.MOM.WW.LmxProxy.Client.Tests.Fakes;

/// <summary>
/// Helper to create an LmxProxyClient wired to a FakeScadaService, bypassing real gRPC.
/// Uses reflection to set private fields since the client has no test seam for IScadaService injection.
/// </summary>
internal static class TestableClient
{
    /// <summary>
    /// Creates an LmxProxyClient with a fake service injected into its internal state,
    /// simulating a connected client.
    /// </summary>
    public static (LmxProxyClient Client, FakeScadaService Fake) CreateConnected(
        string sessionId = "test-session-123",
        ILogger<LmxProxyClient>? logger = null)
    {
        var fake = new FakeScadaService
        {
            ConnectResponseToReturn = new ConnectResponse
            {
                Success = true,
                SessionId = sessionId,
                Message = "OK"
            }
        };

        var client = new LmxProxyClient("localhost", 50051, "test-key", null, logger);

        // Use reflection to inject fake service and simulate connected state
        var clientType = typeof(LmxProxyClient);

        var clientField = clientType.GetField("_client",
            System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)!;
        clientField.SetValue(client, fake);

        var sessionField = clientType.GetField("_sessionId",
            System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)!;
        sessionField.SetValue(client, sessionId);

        var connectedField = clientType.GetField("_isConnected",
            System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)!;
        connectedField.SetValue(client, true);

        return (client, fake);
    }
}
