using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Tango.BL.Entities;
using Tango.BL.Enumerations;
using Tango.Core;
using Tango.Core.DI;
using Tango.FSE.BL;
using Tango.FSE.Common.FSEApplication;
using Tango.FSE.Common.Notifications;
using Tango.Integration.Operation;
using Tango.PMR.Diagnostics;
namespace Tango.FSE.Common.Connection
{
///
/// Represents the default machine events state provider.
///
///
public class FSEMachineEventsStateProvider : ExtendedObject, IMachineEventsStateProvider
{
private static Dictionary _eventTypesGuids;
private bool _initialized;
[TangoInject(TangoInjectMode.WhenAvailable)]
private FSEServicesContainer Services { get; set; }
[TangoInject(TangoInjectMode.WhenAvailable)]
private INotificationProvider NotificationProvider { get; set; }
private ReadOnlyObservableCollection _events;
///
/// Gets the current machine events.
///
public ReadOnlyObservableCollection Events
{
get
{
return _events;
}
private set
{
_events = value;
RaisePropertyChangedAuto();
RaisePropertyChanged(nameof(HasEvents));
}
}
///
/// Gets or sets a value indicating whether this instance has events.
///
public bool HasEvents
{
get
{
return Events.Count > 0;
}
}
///
/// Occurs when new events are available.
///
public event EventHandler> NewEvents;
///
/// Occurs when a new events states has been received.
///
public event EventHandler> EventsReceived;
///
/// Occurs when old events has been resolved.
///
public event EventHandler> EventsResolved;
///
/// Occurs when the collection of current events has changed.
///
public event EventHandler> EventsChanged;
///
/// Initializes a new instance of the class.
///
public FSEMachineEventsStateProvider()
{
TangoIOC.Default.Inject(this);
Events = new ReadOnlyObservableCollection(new ObservableCollection(new Collection()));
}
///
/// Initializes this events state provider only if it was not initialized yet.
/// Will retrieve all event types and perform caching and mapping between PMR and DB.
///
public async void Init()
{
if (_initialized) return;
_eventTypesGuids = new Dictionary();
try
{
var eventTypes = await Services.MachineEventsService.GetAllEventTypes();
foreach (var type in eventTypes)
{
try
{
_eventTypesGuids.Add((EventTypes)type.Code, type);
}
catch (Exception ex)
{
LogManager.Log(ex, $"Error initializing event type '{type.Name}'.");
}
}
_initialized = true;
}
catch (Exception ex)
{
LogManager.Log(ex, "Error initializing FSE machine events state provider.");
NotificationProvider.PushErrorReportingSnackbar(ex, "Events Initialization", "Error initializing machine events definitions.");
}
}
///
/// Applies the collection of events received from the machine operator.
///
/// The events.
public void ApplyEvents(IEnumerable events)
{
List receivedEvents = new List();
foreach (var ev in events)
{
MachinesEvent machineEvent = new MachinesEvent();
machineEvent.DateTime = DateTime.UtcNow;
machineEvent.Description = ev.Message;
if (_eventTypesGuids.ContainsKey((EventTypes)ev.Type))
{
machineEvent.EventType = _eventTypesGuids[(EventTypes)ev.Type];
}
else
{
machineEvent.EventType = _eventTypesGuids[EventTypes.APPLICATION_INFORMATION];
}
receivedEvents.Add(machineEvent);
}
List newEvents = receivedEvents.Where(x => !Events.ToList().Exists(y => y.Type == x.Type)).ToList();
List oldEvents = Events.Where(x => !receivedEvents.Exists(y => y.Type == x.Type)).ToList();
List activeEvents = Events.ToList();
foreach (var oldEvent in oldEvents)
{
oldEvent.ResolvedDateTime = DateTime.UtcNow;
activeEvents.Remove(oldEvent);
}
foreach (var newEvent in newEvents)
{
activeEvents.Add(newEvent);
}
Events = new ReadOnlyObservableCollection(new ObservableCollection(activeEvents));
if (newEvents.Count > 0)
{
OnNewEvents(newEvents);
}
if (oldEvents.Count > 0)
{
OnEventsResolved(oldEvents);
}
if (newEvents.Count > 0 || oldEvents.Count > 0)
{
OnEventsChanged(_events);
}
OnEventsReceived(Events);
RaisePropertyChanged(nameof(HasEvents));
}
///
/// Called when the new has been events
///
/// The events.
protected virtual void OnNewEvents(IEnumerable events)
{
NewEvents?.Invoke(this, events);
}
///
/// Called when the events has been received
///
/// The events.
protected virtual void OnEventsReceived(IEnumerable events)
{
EventsReceived?.Invoke(this, events);
}
///
/// Called when the events has been resolved
///
/// The events.
protected virtual void OnEventsResolved(IEnumerable events)
{
EventsResolved?.Invoke(this, events);
}
///
/// Called when the events has been changed
///
/// The events.
protected virtual void OnEventsChanged(IEnumerable events)
{
EventsChanged?.Invoke(this, events);
}
///
/// Resets the current events tracking.
///
public void Reset()
{
Events = new ReadOnlyObservableCollection(new ObservableCollection(new List()));
RaisePropertyChanged(nameof(Events));
OnEventsChanged(new List());
}
}
}