namespace RioJoy.Core.Compat;

/// <summary>
/// net48/net40 bridge for the handful of Task-era statics the code uses. On
/// net40 (the Windows XP flavor) these come from Microsoft.Bcl.Async's
/// <c>TaskEx</c>, and <c>SemaphoreSlim.WaitAsync</c> doesn't exist at all —
/// there the wait blocks briefly instead, which at 9600 baud (tiny writes,
/// rare contention) costs nothing measurable.
/// </summary>
internal static class TaskCompat
{
#if NET40
    public static Task Run(Action action) => TaskEx.Run(action);

    public static Task Delay(TimeSpan delay, CancellationToken cancellationToken) =>
        TaskEx.Delay(delay, cancellationToken);

    public static Task<Task> WhenAny(IEnumerable<Task> tasks) => TaskEx.WhenAny(tasks);

    public static Task WhenAll(IEnumerable<Task> tasks) => TaskEx.WhenAll(tasks);

    public static Task WaitAsync(SemaphoreSlim semaphore, CancellationToken cancellationToken)
    {
        semaphore.Wait(cancellationToken); // net40: no WaitAsync; block (see class doc)
        return TaskEx.FromResult(true);
    }
#else
    public static Task Run(Action action) => Task.Run(action);

    public static Task Delay(TimeSpan delay, CancellationToken cancellationToken) =>
        Task.Delay(delay, cancellationToken);

    public static Task<Task> WhenAny(IEnumerable<Task> tasks) => Task.WhenAny(tasks);

    public static Task WhenAll(IEnumerable<Task> tasks) => Task.WhenAll(tasks);

    public static Task WaitAsync(SemaphoreSlim semaphore, CancellationToken cancellationToken) =>
        semaphore.WaitAsync(cancellationToken);
#endif
}
