﻿using System;
using System.Threading;
using System.Threading.Tasks;

namespace DotPulsar.Internal
{
    public sealed class Executor : IAsyncDisposable
    {
        private readonly AsyncLock _lock;
        private readonly Func<Exception, CancellationToken, Task> _onException;

        public Executor(Func<Exception, CancellationToken, Task> onException)
        {
            _lock = new AsyncLock();
            _onException = onException;
        }

        public async ValueTask DisposeAsync() => await _lock.DisposeAsync();

        public async Task Execute(Action action, CancellationToken cancellationToken)
        {
            using (await _lock.Lock(cancellationToken))
            {
                while (true)
                {
                    try
                    {
                        action();
                        return;
                    }
                    catch (Exception exception)
                    {
                        await _onException(exception, cancellationToken);
                    }

                    cancellationToken.ThrowIfCancellationRequested();
                }
            }
        }

        public async Task Execute(Func<Task> func, CancellationToken cancellationToken)
        {
            using (await _lock.Lock(cancellationToken))
            {
                while (true)
                {
                    try
                    {
                        await func();
                        return;
                    }
                    catch (Exception exception)
                    {
                        await _onException(exception, cancellationToken);
                    }

                    cancellationToken.ThrowIfCancellationRequested();
                }
            }
        }

        public async Task<TResult> Execute<TResult>(Func<TResult> func, CancellationToken cancellationToken)
        {
            using (await _lock.Lock(cancellationToken))
            {
                while (true)
                {
                    try
                    {
                        return func();
                    }
                    catch (Exception exception)
                    {
                        await _onException(exception, cancellationToken);
                    }

                    cancellationToken.ThrowIfCancellationRequested();
                }
            }
        }

        public async Task<TResult> Execute<TResult>(Func<Task<TResult>> func, CancellationToken cancellationToken)
        {
            using (await _lock.Lock(cancellationToken))
            {
                while (true)
                {
                    try
                    {
                        return await func();
                    }
                    catch (Exception exception)
                    {
                        await _onException(exception, cancellationToken);
                    }

                    cancellationToken.ThrowIfCancellationRequested();
                }
            }
        }

        public async ValueTask<TResult> Execute<TResult>(Func<ValueTask<TResult>> func, CancellationToken cancellationToken)
        {
            using (await _lock.Lock(cancellationToken))
            {
                while (true)
                {
                    try
                    {
                        return await func();
                    }
                    catch (Exception exception)
                    {
                        await _onException(exception, cancellationToken);
                    }

                    cancellationToken.ThrowIfCancellationRequested();
                }
            }
        }
    }
}
