using System;
using System.Threading;
using System.Threading.Tasks;
using Interfaces;

namespace IrDaemonNotifier
{
    // TODO: The irDaemon will support tcp connections so that it will publish tokens
    // TODO: as they get received rather than need to request them.
    public class IrDaemonTransponderUtilities : ITransponderUtilityProvider
    {
        private readonly ILoggerService _logger;
        private int _lastScannedId = -1;
        private readonly object _lastScanedLock = new object();
        private readonly Thread _idRefreshThread;
        private bool _killRefreshThread;

        public IrDaemonTransponderUtilities(ILoggerService logger)
        {
            _logger = logger;
            _idRefreshThread = new Thread(IrDaemonInterrogation)
            {
                IsBackground = true,
                Name = "Ir Daemon Id Update Thread",
                Priority = ThreadPriority.BelowNormal
            };
            _killRefreshThread = false;
            _idRefreshThread.Start();
        }

        private void IrDaemonInterrogation()
        {
            while (!_killRefreshThread)
            {
                try
                {
                    var communicator = new IrDaemonCommunicator(_logger);
                    var lastId = communicator.RequestData<int>(Commands.Properties.GetLastToken);
                    lock (_lastScanedLock)
                    {
                        _lastScannedId = lastId;
                    }
                    Thread.Sleep(500);
                }
                catch (Exception e)
                {
                    _logger.Error(e);
                }
            }
        }

        ~IrDaemonTransponderUtilities()
        {
            _killRefreshThread = true;
            if (_idRefreshThread.IsAlive)
            {
                _idRefreshThread.Abort();
            }
        }

        public Task<int> GetLastScannedIdAsync()
        {
            return Task.Run(()=>GetLastId());
        }

        public PluginDetails GetPluginDetails()
        {
            return Resources.Details;
        }

        private int GetLastId()
        {
            lock (_lastScanedLock)
            {
                return _lastScannedId;
            }
        }
    }
}