using System;
using System.Threading.Tasks;
using System.Threading.Channels;
using Sentry;
using Sledgemapper.Messages;
using TinyMessenger;

namespace Sledgemapper
{
    public class ChannelsQueue
    {
        public TinyMessengerHub Messenger { get; }
        private readonly ChannelWriter<Action> _writer;

        public ChannelsQueue(TinyMessenger.TinyMessengerHub messenger)
        {
            Messenger = messenger;
            var channel = Channel.CreateUnbounded<Action>(new UnboundedChannelOptions() { SingleReader = true });
            var reader = channel.Reader;
            _writer = channel.Writer;

            Task.Run(async () =>
                {
                    while (await reader.WaitToReadAsync())
                    {
                        // Fast loop around available jobs
                        while (reader.TryRead(out var job))
                        {
                            try
                            {
                                job.Invoke();
                            }
                            catch (Exception ex)
                            {
                                SentrySdk.CaptureException(ex);
                                messenger.Publish(new ErrorMessage(this, ex.Message));
                            }
                        }
                    }
                });
        }

        public void Enqueue(Action job)
        {
            _writer.TryWrite(job);
        }

        public void Stop()
        {
            _writer.Complete();
        }
    }
}
