using qdr.fnd.core.pqueue.Configuration;
using qdr.fnd.core.pqueue.Enums;
using qdr.fnd.core.pqueue.Storages;
using qdr.fnd.core.pqueue.test.Mocks;
using Quadarax.Foundation.Core.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace qdr.fnd.core.pqueue.test
{
    /// <summary>
    /// Complex test class for <see cref="Mocks.PsQueueMock"/> <see langword="class"/>.
    /// </summary>
    public class PsQueueTest
    {
        #region *** Queue Fields ***    
        private string _queueName;
        private ILogger? _logger;
        private PsQueueConfiguration? _configuration;
        private IPsQueueStorage? _storageProvider;
        #endregion

        #region *** Queue Item Fields ***
        private string _id = "id";
        private string _owner = "owner";
        private string _ownerRef = "ownerRef";
        private string _providerClass = "providerClass";
        private DateTime _created = DateTime.Now;
        private PsStatusEnum _status = PsStatusEnum.New;
        private bool _statusTrancient = false;
        private string _statusMessage = "message";

        #endregion

        [SetUp]
        public void Setup()
        {
            _queueName = "queueName";
            _logger = new LoggerMock();
            _configuration = new PsQueueConfiguration();
            _storageProvider = new MemoryStorageProvider(_logger);
        }

        [Test(TestOf=typeof(PsQueue))]
        public void ConstructorOk()
        {
            var queue = CreateQueue();
            Assert.IsFalse(queue.IsRunning);
        }

        [Test(TestOf=typeof(PsQueue))]
        public void ConstructorFail()
        {
            Assert.Throws<ArgumentNullException>(() => new PsQueueMock(string.Empty, _configuration!, _storageProvider!, _logger!));
            Assert.Throws<ArgumentNullException>(() => new PsQueueMock(_queueName, null!, _storageProvider!, _logger!));
            Assert.Throws<ArgumentNullException>(() => new PsQueueMock(_queueName, _configuration!, null!, _logger!));
        }

        [Test(TestOf=typeof(PsQueue))]
        public void ValidateItemIdOk()
        {
            var queue = CreateQueue();
            queue.TestValidateItemId("aaa");
            Assert.Throws<ArgumentNullException>(() => queue.TestValidateItemId(string.Empty));
            Assert.Throws<ArgumentNullException>(() => queue.TestValidateItemId(null!));
        }

        [Test(TestOf=typeof(PsQueue))]
        public void ValidateEmitterOk()
        {
            var queue = CreateQueue();
            queue.TestValidateEmitter("aaa");
            Assert.Throws<ArgumentNullException>(() => queue.TestValidateEmitter(string.Empty));
            Assert.Throws<ArgumentNullException>(() => queue.TestValidateEmitter(null!));
        }

        [Test(TestOf=typeof(PsQueue))]
        public void ValidateItemOk()
        {
            var queue = CreateQueue();
            var item = CreaeQueueItem(_id);
            queue.TestValidateItem(item);


        }

        private PsQueueMock CreateQueue()
        {
            return new PsQueueMock(_queueName, _configuration!, _storageProvider!, _logger!);
        }

        private PsQueueItem CreaeQueueItem(string id)
        {
            var item = new PsQueueItem(id, _owner,_ownerRef,_providerClass,_created);
            return item;
        }
    }
}
