using System.IO.Pipes;

namespace ZB.MOM.WW.OtOpcUa.Driver.Galaxy.TestSupport.Probes;

/// <summary>
///     Verifies the <c>OtOpcUaGalaxyHost</c> named-pipe endpoint is accepting connections —
///     the handshake the Proxy performs at boot. A clean pipe connect without sending any
///     framed message proves the Host service is listening; we disconnect immediately so we
///     don't consume a session slot.
/// </summary>
/// <remarks>
///     Default pipe name matches the installer script's <c>OTOPCUA_GALAXY_PIPE</c> default.
///     Override when the Host service was installed with a non-default name (custom deployments).
/// </remarks>
public static class NamedPipeProbe
{
    public const string DefaultGalaxyHostPipeName = "OtOpcUaGalaxy";

    public static async Task<PrerequisiteCheck> CheckGalaxyHostPipeAsync(
        string? pipeName = null, CancellationToken ct = default)
    {
        pipeName ??= DefaultGalaxyHostPipeName;
        try
        {
            using var client = new NamedPipeClientStream(
                serverName: ".",
                pipeName: pipeName,
                direction: PipeDirection.InOut,
                options: PipeOptions.Asynchronous);
            using var cts = CancellationTokenSource.CreateLinkedTokenSource(ct);
            cts.CancelAfter(TimeSpan.FromSeconds(2));
            await client.ConnectAsync(cts.Token);

            return new PrerequisiteCheck("pipe:OtOpcUaGalaxyHost", PrerequisiteCategory.OtOpcUaService,
                PrerequisiteStatus.Pass,
                $@"Pipe \\.\pipe\{pipeName} accepted a connection — OtOpcUaGalaxyHost is listening.");
        }
        catch (OperationCanceledException)
        {
            return new PrerequisiteCheck("pipe:OtOpcUaGalaxyHost", PrerequisiteCategory.OtOpcUaService,
                PrerequisiteStatus.Fail,
                $@"Pipe \\.\pipe\{pipeName} not connectable within 2s — OtOpcUaGalaxyHost service isn't running. " +
                "Start with: sc.exe start OtOpcUaGalaxyHost");
        }
        catch (TimeoutException)
        {
            return new PrerequisiteCheck("pipe:OtOpcUaGalaxyHost", PrerequisiteCategory.OtOpcUaService,
                PrerequisiteStatus.Fail,
                $@"Pipe \\.\pipe\{pipeName} connect timed out — service may be starting or stuck. " +
                "Check: sc.exe query OtOpcUaGalaxyHost");
        }
        catch (Exception ex)
        {
            return new PrerequisiteCheck("pipe:OtOpcUaGalaxyHost", PrerequisiteCategory.OtOpcUaService,
                PrerequisiteStatus.Fail,
                $@"Pipe \\.\pipe\{pipeName} connect failed: {ex.GetType().Name}: {ex.Message}");
        }
    }
}
