public async Task <GetDetailedCustomerPageResponse> Handle(GetDetailedCustomerPageRequest request, CancellationToken cancellationToken) { if (!_validator.Validate(request).IsValid) { return(new GetDetailedCustomerPageResponse(new [] { new Error("InvalidRequest", "Parameters are incorrect.") })); } var applianceInfoTask = _applianceService.GetApplianceInfo(request.CustomerGuid); var applianceTask = _applianceService.GetCustomerAppliances(request.CustomerGuid); var responseTask = _applianceService.GetCustomerApplianceHistory(request.CustomerGuid, request.Interval, request.IntervalOffset); await Task.WhenAll(responseTask, applianceInfoTask, applianceTask); var applianceMap = applianceTask.Result.ToDictionary(x => x.ApplianceId, x => x); var applianceInfo = applianceInfoTask.Result; var response = responseTask.Result; if (response == null) { return(new GetDetailedCustomerPageResponse(new [] { new Error("CouldNotFetchData", "Remote Api did not return any data") })); } var skips = SkipsDictionary[request.Interval]; var startTime = DateTimeOffset.FromUnixTimeSeconds(response.Timestamps.FirstOrDefault()); var intervalStart = response.Timestamps.Count - skips * (request.IntervalOffset + 1); if (intervalStart < 0) { return(new GetDetailedCustomerPageResponse(new [] { new Error("InvalidRequest", $"Invalid {nameof(request.IntervalOffset)} parameter: {request.IntervalOffset}.") })); } var intervalStop = intervalStart + skips - 1; var intervalStartTime = DateTimeOffset.FromUnixTimeSeconds(response.Timestamps[intervalStart]); var intervalStopTime = DateTimeOffset.FromUnixTimeSeconds(response.Timestamps[intervalStop]); var endTime = DateTimeOffset.FromUnixTimeSeconds(response.Timestamps.LastOrDefault()); var dataPointFreq = response.Timestamps.Count / 60; var appliances = response.ApplianceTypes.SelectMany(x => x.Appliances, (p, c) => { return(new ApplianceUsageDto { Appliance = applianceMap.ContainsKey((int)c.ApplianceId) ? applianceMap[(int)c.ApplianceId] : null, TotalAverageUsage = (short?)c.CalculateTotalAverage(), CurrentAverageUsage = (short?)c.PowerConsumption.Skip(intervalStart) .Take(intervalStop - intervalStart).Average(x => x ?? 0), UsagePoints = c.GetIntervalEveryNthPoint(dataPointFreq) }); }).ToList(); _applianceService.AddApplianceInfo(appliances.Select(x => x.Appliance), applianceInfo); return(new GetDetailedCustomerPageResponse(new CustomerDetailedPageDto { StartTime = startTime, StartTimeInterval = intervalStartTime, EndTimeInterval = intervalStopTime, EndTime = endTime, Appliances = appliances, DataPointEvery = response.Timestamps[dataPointFreq] - response.Timestamps[0] })); }