using System;
using Newtonsoft.Json;
using System.Globalization;
using WingInterfaceLibrary.Enum;
using System.Collections.Concurrent;
using System.Threading.Tasks;
using WingServerCommon.Log;
using System.Threading;

namespace WingDeviceService.Common
{
    internal class DeviceHeartRateManager
    {
        private ConcurrentDictionary<string, DeviceHeartRateDTO> _devices = new ConcurrentDictionary<string, DeviceHeartRateDTO>();
        private Func<string, bool, bool> OnSetOnlineState;

        public DeviceHeartRateManager(Func<string, bool, bool> setOnlineState)
        {
            OnSetOnlineState = setOnlineState;
            StartCheckClients();
        }

        /// <summary>
        /// 加入检测集合
        /// </summary>
        /// <param name="token"></param>
        public void AddOrUpdate(string token)
        {
            _devices.AddOrUpdate(token, new DeviceHeartRateDTO(token), (k, v) =>
            {
                v.Activate();
                return v;
            });
        }

        /// <summary>
        /// 设备心跳有效期验证
        /// </summary>
        private void StartCheckClients()
        {
            Logger.WriteLineInfo($"DeviceHeartRateManager start check clients");
            Task.Run(async () =>
            {
                while (true)
                {
                    await Task.Delay(1 * 60 * 1000);
                    foreach (var token in _devices.Keys)
                    {
                        var heartRate = _devices[token];
                        heartRate.DeActivate();
                        try
                        {
                            if (heartRate.LeftTime < 0)
                            {
                                OnSetOnlineState?.Invoke(token, false);
                            }
                        }
                        catch (Exception ex)
                        {
                            Logger.WriteLineWarn($"check device token {token} err, {ex}");
                        }
                        finally
                        {
                            if (heartRate.LeftTime < 0)
                            {
                                _devices.TryRemove(token, out _);
                            }
                        }
                    }
                }
            });
            Logger.WriteLineInfo($"DeviceHeartRateManager finished");
        }
    }

    internal class DeviceHeartRateDTO
    {
        public DeviceHeartRateDTO(string token)
        {
            Token = token;
        }

        private volatile int _livingTime = 0;
        private readonly int _clientLifecycle = 10; //10 minutes 

        public string Token { get; set; }

        public int LeftTime => _clientLifecycle - _livingTime;

        /// <summary>
        /// Reset the living time.
        /// </summary>
        public virtual void Activate()
        {
            _livingTime = 0;
        }

        /// <summary>
        /// Deactive the session.
        /// </summary>
        public virtual void DeActivate()
        {
            _livingTime++;
        }
    }
}