using System.IO.Pipes;

namespace ZB.MOM.WW.MxGateway.Worker.Tests.TestSupport;

/// <summary>
/// Creates the gateway-side <see cref="NamedPipeServerStream"/> the worker tests connect to, with an
/// explicit OS buffer so a test that stops draining the pipe cannot block its own writer forever.
/// </summary>
/// <remarks>
/// The <c>NamedPipeServerStream(string, PipeDirection, int, PipeTransmissionMode, PipeOptions)</c>
/// overload passes <c>inBufferSize: 0</c> and <c>outBufferSize: 0</c> to <c>CreateNamedPipe</c>, which
/// on Windows reserves no buffer at all: a write completes only once the peer reads it. Measured on a
/// Windows 10 host, the first 63-byte write to a non-reading peer never completed, against 65 520
/// bytes absorbed by the same pipe declared with 64 KiB buffers. A test-side write with no timeout
/// against a stopped reader therefore hangs the test method, and a test method that never returns
/// keeps xUnit from raising <c>ITestAssemblyFinished</c> — so <c>testhost</c> never exits even after
/// every other test has passed. This suite runs only on Windows, so it has no macOS Unix-domain-socket
/// buffer to hide behind. See the matching helper in the gateway test project.
/// </remarks>
internal static class TestNamedPipe
{
    /// <summary>
    /// The buffer reserved for each direction. Comfortably larger than any frame volume a test
    /// pushes at a stopped reader, and the size Windows itself uses for a typical named pipe.
    /// </summary>
    internal const int BufferBytes = 64 * 1024;

    /// <summary>Creates the gateway-side server pipe for <paramref name="pipeName"/>.</summary>
    /// <param name="pipeName">The pipe name the worker under test connects to.</param>
    /// <returns>An asynchronous, byte-mode server pipe with explicit buffers.</returns>
    internal static NamedPipeServerStream CreateServer(string pipeName)
    {
        return new NamedPipeServerStream(
            pipeName,
            PipeDirection.InOut,
            1,
            PipeTransmissionMode.Byte,
            PipeOptions.Asynchronous,
            BufferBytes,
            BufferBytes);
    }
}
