using qdr.fnd.core.pqueue.Configuration;
using qdr.fnd.core.pqueue.Enums;
using qdr.fnd.core.pqueue.Exceptions;
using qdr.fnd.core.pqueue.Process;
using qdr.fnd.core.pqueue.Storages;
using Quadarax.Foundation.Core.Data;
using Quadarax.Foundation.Core.Logging;
using Quadarax.Foundation.Core.Object;
using Quadarax.Foundation.Core.Value.Generators;

namespace qdr.fnd.core.pqueue
{
    public class PsQueue : DisposableObject
    {
        #region *** Properties ***
        public string Name { get; }
        public bool IsRunning { get; private set; }
        public PsQueueConfiguration Configuration { get;}

        public event PsQueueStatusChangedEventHandler? ProcessItemStatusChanged;
        #endregion

        #region *** Private Fields ***
        private ILog _log;
        private TinyHash _hashGenerator;
        protected IPsQueueStorage? _storage;
        #endregion

        #region *** Constructors ***

        public PsQueue(string queueName, PsQueueConfiguration configuration,IPsQueueStorage storageProvider, ILogger logger)
        {
            _hashGenerator = new TinyHash(5);
            if (string.IsNullOrEmpty(queueName))
                queueName = "PSQUEUE" + _hashGenerator.NewId();

            Name = queueName;
            IsRunning = false;
            Configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
            _storage = storageProvider ?? throw new ArgumentNullException(nameof(storageProvider));
            _log = logger.GetLogger(queueName);
        }

        #endregion

        #region *** Public Operations ***
        public void Start()
        {
            if (IsRunning) throw new PSQueueException(PSQueueException.ErrorCodes.PsQueueIsRunning);
            _log.Log(LogSeverityEnum.Info, $"{Name}:queue started.");
        }
        public void Stop()
        {
            if (!IsRunning) throw new PSQueueException(PSQueueException.ErrorCodes.PsQueueIsRunning);
            _log.Log(LogSeverityEnum.Info, $"{Name}:queue stopped.");
        }

        public string EnQueue(IPsQueueItemDescriptor item)
        {
            throw new NotImplementedException();
        }
        public bool Dequeue(string itemId, bool force)
        {
            throw new NotImplementedException();
        }

        public IQueryable<IPsQueueItem> Query(string? owner, string? ownerRef, params Tuple<bool,PsStatusEnum>[] status)
        {
            throw new NotImplementedException();
        }

        public IPsQueueItem? Get(string itemId)
        {
            throw new NotImplementedException();
        }

        public bool Postpone(string itemId, TimeSpan postpone)
        {
            throw new NotImplementedException();
        }

        public bool Reset(string itemId)
        {
            throw new NotImplementedException();
        }

        public bool SetPriority(string itemId, int priority)
        {
            throw new NotImplementedException();
        }

        public IEnumerable<IPsQueueItem> GetWorkingItems()
        {
            throw new NotImplementedException();
        }
        #endregion


        #region *** Private Operations ***
        protected override void OnDisposing()
        {
            if(IsRunning)
                Stop();

            ProcessItemStatusChanged = null;
            _storage = null;
            //TODO: Implement OnDisposing
        }
        #endregion
    }
}
