public async Task <List <PortReport> > GetOverallDayStatistic(DateTime day)
        {
            var reports = await PortReports.Query()
                          .Where(report => report.Year == day.Year)
                          .Where(report => report.Month == day.Month)
                          .Where(report => report.Day == day.Day)
                          .GroupBy(report => report.Hour)
                          .Select(report => new
            {
                Hour     = report.Key,
                Inbound  = report.Sum(inner => inner.InboundTraffic),
                Outbound = report.Sum(inner => inner.OutboundTraffic)
            })
                          .ToListAsync();

            var hourRange = Enumerable.Range(0, 24);
            var result    = new List <PortReport>();

            foreach (var hour in hourRange)
            {
                var existing = reports.FirstOrDefault(report => report.Hour == hour);

                if (existing != null)
                {
                    result.Add(new PortReport
                    {
                        Day             = day.Day,
                        Year            = day.Year,
                        Hour            = existing.Hour,
                        Month           = day.Month,
                        InboundTraffic  = existing.Inbound,
                        OutboundTraffic = existing.Outbound
                    });
                }
                else
                {
                    result.Add(new PortReport
                    {
                        Day   = day.Day,
                        Year  = day.Year,
                        Hour  = hour,
                        Month = day.Month
                    });
                }
            }

            return(result);
        }
        public async Task <List <PortReport> > GetDayStatisticForPort(string snmpIpAddress, int portNumber, DateTime day)
        {
            var reports = await PortReports.Query()
                          .Where(report => report.SnmpIpAddress == snmpIpAddress)
                          .Where(report => report.PortNumber == portNumber)
                          .Where(report => report.Year == day.Year)
                          .Where(report => report.Month == day.Month)
                          .Where(report => report.Day == day.Day)
                          .ToListAsync();

            var hourRange = Enumerable.Range(0, 24);
            var result    = new List <PortReport>();

            foreach (var hour in hourRange)
            {
                var existing = reports.FirstOrDefault(report => report.Hour == hour);

                if (existing != null)
                {
                    result.Add(existing);
                }
                else
                {
                    result.Add(new PortReport
                    {
                        Day           = day.Day,
                        Year          = day.Year,
                        PortNumber    = portNumber,
                        SnmpIpAddress = snmpIpAddress,
                        Hour          = hour,
                        Month         = day.Month
                    });
                }
            }

            return(result);
        }
        public async Task WritePortReports(int year, int month, int day, int hour)
        {
            var startTime = new DateTime(year, month, day, hour, 0, 0);
            var endTime   = startTime.Add(new TimeSpan(1, 0, 0));

            var inboundHighscore = await SnmpStatisticsService
                                   .GetHighscore(int.MaxValue, startTime, endTime, TrafficType.Inbound);

            var outboundHighscore = await SnmpStatisticsService
                                    .GetHighscore(int.MaxValue, startTime, endTime, TrafficType.Outbound);

            if (inboundHighscore == null || outboundHighscore == null)
            {
                throw new Exception("high score failure :(");
            }

            var reports        = new List <PortReport>();
            var monitoredPorts = await MonitoredPorts.Query().ToListAsync();

            foreach (var monitoredPort in monitoredPorts)
            {
                var inboundStatistics = inboundHighscore
                                        .FirstOrDefault(
                    stats =>
                    stats.MonitoredPort.SnmpIpAddress == monitoredPort.SnmpIpAddress &&
                    stats.MonitoredPort.PortNumber == monitoredPort.PortNumber);
                var outboundStatistics = outboundHighscore
                                         .FirstOrDefault(
                    stats =>
                    stats.MonitoredPort.SnmpIpAddress == monitoredPort.SnmpIpAddress &&
                    stats.MonitoredPort.PortNumber == monitoredPort.PortNumber);

                if (inboundStatistics == null || outboundStatistics == null)
                {
                    continue;
                }

                var currentReport = new PortReport
                {
                    Day             = day,
                    Hour            = hour,
                    Month           = month,
                    Year            = year,
                    InboundTraffic  = inboundStatistics.InboundTraffic,
                    OutboundTraffic = outboundStatistics.OutboundTraffic,
                    PortNumber      = monitoredPort.PortNumber,
                    SnmpIpAddress   = monitoredPort.SnmpIpAddress
                };

                reports.Add(currentReport);
            }

            PortReports.InsertRange(reports);
            await Context.SaveAsync();

            var itemsToDelete = await CollectedTrafficDatas.Query()
                                .Where(data => data.TimeScanned >= startTime)
                                .Where(data => data.TimeScanned <= endTime)
                                .ToListAsync();

            itemsToDelete.ForEach(item => CollectedTrafficDatas.Delete(item));
            await Context.SaveAsync();
        }