// Copyright © Selmo Technology GmbH. All Rights Reserved

using Novus.Connectivity.Plc;

namespace SelmoStudio.Hmi.Server.Shared.Model
{
    internal class DeviceConnectionCache
    {
        #region Connection Lost Handling

        internal Dictionary<DeviceId, DateTimeOffset> DeviceConnectionTimestamps { get; } = new();

        internal List<DeviceId> DeviceConnections { get; } = new();

        internal List<DeviceId> DeviceConnectionsLost { get; } = new();

        internal void UpdateConnectionStates(params DeviceConnectionInfo[] connectionInfos)
        {
            DeviceConnections.Clear();
            DeviceConnectionsLost.Clear();

            foreach (var connectionInfo in connectionInfos)
            {
                HandleDeviceConnection(connectionInfo.DeviceId, connectionInfo.IsConnectionActive);
            }
        }

        internal void SetTimestamp(DeviceId deviceId, DateTimeOffset timestamp)
        {
            if (DeviceConnectionTimestamps.ContainsKey(deviceId))
            {
                DeviceConnectionTimestamps[deviceId] = timestamp;
            }
            else
            {
                DeviceConnectionTimestamps.Add(deviceId, timestamp);
            }
        }

        internal const int AllowedConnectionTimeoutInSeconds = 2;

        private void HandleDeviceConnection(DeviceId deviceId, bool isConnected)
        {
            if (!DeviceConnectionTimestamps.ContainsKey(deviceId))
            {
                DeviceConnectionTimestamps[deviceId] = DateTimeOffset.MinValue;
            }

            var currentTimestamp = DateTimeOffset.Now;
            if (isConnected)
            {
                SetTimestamp(deviceId, currentTimestamp);
                DeviceConnections.Add(deviceId);
            }
            else
            {
                var allowedMin = currentTimestamp.AddSeconds(-AllowedConnectionTimeoutInSeconds);
                var lastTimeConnected = DeviceConnectionTimestamps[deviceId];
                if (lastTimeConnected <= allowedMin)
                {
                    DeviceConnectionsLost.Add(deviceId);
                }
                else
                {
                    DeviceConnections.Add(deviceId);
                }
            }
        }

        #endregion Connection Lost Handling
    }
}