using System; using System.Collections.Generic; 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.Authentication; using Tango.FSE.Common.BugReporting; using Tango.FSE.Common.Connection; using Tango.FSE.Common.FileSystem; using Tango.FSE.Common.Insights; using Tango.FSE.Common.MachineUpdates; using Tango.Insights; using Tango.PPC.Shared.Insights; using Tango.Transport; namespace Tango.FSE.UI.Insights { public class DefaultInsightsProvider : ExtendedObject, IInsightsProvider { private DateTime? minDate; private IMachineProvider MachineProvider { get; set; } [TangoInject] private IAuthenticationProvider AuthenticationProvider { get; set; } [TangoInject] private IFileSystemProvider FileSystemProvider { get; set; } [TangoInject] private FSEServicesContainer Services { get; set; } [TangoInject] public IBugReporter BugReporter { get; set; } [TangoInject] public IMachineUpdatesProvider MachineUpdatesProvider { get; set; } public DefaultInsightsProvider(IMachineProvider machineProvider) { MachineProvider = machineProvider; MachineProvider.MachineDisconnected += MachineProvider_MachineDisconnected; } private void MachineProvider_MachineDisconnected(object sender, MachineDisconnectedEventArgs e) { minDate = null; } public async Task GetInsights(DateTime startDateUTC, DateTime endTimeUTC) { InsightsHandler handler = null; var response = await MachineProvider.MachineOperator.SendGenericRequest(new InsightsRequest() { StartDateUTC = startDateUTC, EndDateUTC = endTimeUTC, IncludeStatuses = true, IncludeEvents = true, IncludeApplicationExceptions = true }, new TransportRequestConfig() { Timeout = TimeSpan.FromMinutes(1), }); var insightsFilePath = TemporaryManager.CreateImaginaryFile(".insights"); var fileSystemHandler = await FileSystemProvider.Download(response.InisightsFilePath, true, insightsFilePath, true); handler = new InsightsHandler(() => { fileSystemHandler.Abort(); }); fileSystemHandler.StatusChanged += (x, status) => { if (status == FileSystemHandlerStatus.Downloading) { handler.Status = InsightsHandlerStatus.Downloading; } else if (status == FileSystemHandlerStatus.Completed) { Task.Factory.StartNew(() => { try { handler.Progress = new TangoProgress("Composing insights..."); handler.Status = InsightsHandlerStatus.Composing; var package = new InsightsPackage(); var insightsFile = InsightsFile.FromFile(insightsFilePath); int progress = 0; foreach (var frame in insightsFile.Frames) { if (handler.Status == InsightsHandlerStatus.Aborted) { return; } package.Frames.Add(new InsightsReadyFrame(frame)); progress++; handler.Progress = new TangoProgress("Composing insights...", false, progress, insightsFile.Frames.Count); } handler.Progress = new TangoProgress("Composing insights..."); progress = 0; var eventTypes = Services.MachineEventsService.GetAllEventTypes().Result; Dictionary eventsDictionary = new Dictionary(); foreach (var eventType in eventTypes) { eventsDictionary.Add(eventType.Code, eventType); } foreach (var ev in insightsFile.Events.OrderBy(xx => xx.Time)) { if (handler.Status == InsightsHandlerStatus.Aborted) { return; } EventType eventType = eventsDictionary[ev.EventCode]; package.Events.Add(new InsightsReadyEvent() { Time = ev.Time, EventType = eventType, Description = ev.Description, }); progress++; handler.Progress = new TangoProgress("Composing insights...", false, progress, insightsFile.Events.Count); } foreach (var machineStatus in insightsFile.Statuses) { package.Statuses.Add(new InsightsReadyStatus() { Time = machineStatus.Time, Status = machineStatus.Status }); } foreach (var appException in insightsFile.ApplicationExceptions) { package.ApplicationExceptions.Add(new InsightsReadyApplicationException() { Time = appException.Time, Exception = appException.Exception, IsApplicationCrash = appException.IsApplicationCrash }); } if (AuthenticationProvider.CurrentUser.HasPermission(Permissions.FSE_ModifyBugReport)) { try { var bugs = BugReporter.GetConnectedMachineBugs(startDateUTC, endTimeUTC).Result; package.Bugs = bugs.Select(bug => new InsightsReadyBug() { Time = bug.CreatedDate, Bug = bug }).ToList(); } catch (Exception ex) { LogManager.Log(ex, "Error retrieving connected machine bugs for insights."); } } try { var updates = MachineUpdatesProvider.GetUpdates().Result; foreach (var update in updates.Updates.Where(y => y.StartDate >= startDateUTC && y.LastUpdated <= endTimeUTC).OrderBy(xx => xx.LastUpdated)) { package.Updates.Add(new InsightsReadyUpdate() { Time = update.LastUpdated, Update = update }); } } catch (Exception ex) { LogManager.Log(ex, "Error getting machine updates for insights."); } handler.RaiseCompleted(package); } catch (Exception ex) { handler.RaiseFailed(ex); } finally { try { var result = MachineProvider.MachineOperator.SendGenericRequest(new InsightsDownloadCompletedRequest() { InisightsFilePath = response.InisightsFilePath }).Result; } catch { } } }); } else if (status == FileSystemHandlerStatus.Failed) { handler.RaiseFailed(fileSystemHandler.FailedException); } }; fileSystemHandler.ProgressChanged += (x, e) => { e.Progress.Message = "Getting insights from the remote machine..."; handler.Progress = e.Progress; }; return handler; } public async Task GetInsightsMinDate() { if (minDate != null) { return minDate; } var response = await MachineProvider.MachineOperator.SendGenericRequest(new InsightsMinDateRequest(), new TransportRequestConfig() { Timeout = TimeSpan.FromSeconds(10) }); minDate = response.MinDate; return minDate; } } }