namespace RioJoy.Core.Serial;

/// <summary>
/// Opens the right <see cref="IRioTransport"/> for an endpoint string. A COM
/// port name ("COM3") opens a <see cref="SerialPortTransport"/>; a
/// <c>pipe:name</c> endpoint ("pipe:vrio") opens a
/// <see cref="NamedPipeTransport"/> to <c>\\.\pipe\name</c> — the same
/// endpoint syntax vRIO's own connection picker uses, so a profile can point
/// at the emulator with <c>RioComPort = "pipe:vrio"</c> and no com0com pair.
/// </summary>
public static class RioTransportFactory
{
    /// <summary>Endpoint prefix selecting the named-pipe transport.</summary>
    public const string PipeScheme = "pipe:";

    /// <summary>True when <paramref name="endpoint"/> names a pipe rather than a COM port.</summary>
    public static bool IsPipe(string endpoint) =>
        endpoint is not null
        && endpoint.StartsWith(PipeScheme, StringComparison.OrdinalIgnoreCase);

    /// <summary>
    /// Open <paramref name="endpoint"/>. <paramref name="baudRate"/> applies
    /// to COM ports only — a pipe has no wire rate (the peer paces itself).
    /// </summary>
    public static IRioTransport Open(string endpoint, int baudRate = SerialPortTransport.BaudRate)
    {
        if (string.IsNullOrWhiteSpace(endpoint)) throw new ArgumentException("Value cannot be null or whitespace.", nameof(endpoint));

        return IsPipe(endpoint)
            ? new NamedPipeTransport(endpoint.Substring(PipeScheme.Length))
            : (IRioTransport)new SerialPortTransport(endpoint, baudRate);
    }
}
