using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace Sockeye.Util
{
    internal static class TaskUtil
    {
        ///<summary>
        ///Usage:
        ///await WithTimeoutAfterStart(ctoken => SomeOperationAsync(ctoken), TimeSpan.FromMilliseconds(n));
        ///in callee call this regularly    ctoken.ThrowIfCancellationRequested();
        ///and pass the ctoken into any time consuming system methods called in turn
        ///</summary>
        public static async Task WithTimeoutAfterStart(Func<CancellationToken, Task> operation, TimeSpan timeout)
        {
            //https://stackoverflow.com/a/23478628/8939
            var source = new CancellationTokenSource();
            var task = operation(source.Token);
            source.CancelAfter(timeout);
            await task;
        }


        ///<summary>
        ///fire and forget a task but bubble up any exceptions with optional ignore some
        ///</summary>
        public static async void Forget(this Task task, params Type[] acceptableExceptions)
        {
            //https://stackoverflow.com/a/22864616/8939
            try
            {
                await task.ConfigureAwait(false);
            }
            catch (Exception ex)
            {                
                if (!acceptableExceptions.Contains(ex.GetType()))
                    throw;
            }
        }

    }//eoc

}//eons