예제 #1
0
        /// <inheritdoc />
        public async Task <IReadOnlyCollection <StageSweep> > GetSweepsAsync(
            Game game,
            bool untied,
            DateTime?startDate,
            DateTime?endDate,
            Stage?stage)
        {
            if (startDate > endDate)
            {
                throw new ArgumentOutOfRangeException(nameof(startDate), startDate,
                                                      $"{nameof(startDate)} is greater than {nameof(endDate)}.");
            }

            var fullEntries = new List <EntryDto>();

            foreach (var locStage in game.GetStages())
            {
                var entries = await _readRepository
                              .GetEntriesAsync(locStage)
                              .ConfigureAwait(false);

                fullEntries.AddRange(entries);
            }

            var entriesGroups = fullEntries
                                .Where(e => e.Date.HasValue)
                                .GroupBy(e => (e.Stage, e.Level))
                                .ToDictionary(e => e.Key, e => e.ToList());

            var playerKeys = await GetPlayersInternalAsync().ConfigureAwait(false);

            var sweepsRaw = new ConcurrentBag <(long playerId, DateTime date, Stage stage)>();

            var dates = SystemExtensions
                        .LoopBetweenDates(
                startDate ?? Extensions.GetEliteFirstDate(game),
                endDate ?? ServiceProviderAccessor.ClockProvider.Now,
                DateStep.Day)
                        .GroupBy(d => d.DayOfWeek)
                        .ToDictionary(d => d.Key, d => d);

            var tasks = new List <Task>();

            foreach (var dow in SystemExtensions.Enumerate <DayOfWeek>())
            {
                tasks.Add(Task.Run(() =>
                {
                    foreach (var currentDate in dates[dow])
                    {
                        foreach (var stg in game.GetStages())
                        {
                            if (stage == null || stg == stage)
                            {
                                sweepsRaw.AddRange(
                                    GetPotentialSweeps(untied, entriesGroups, currentDate, stg));
                            }
                        }
                    }
                }));
            }

            await Task.WhenAll(tasks).ConfigureAwait(false);

            var finalSweeps = new List <StageSweep>();

            foreach (var(playerId, date, locStage) in sweepsRaw.OrderBy(f => f.date))
            {
                var sweepMatch = finalSweeps.SingleOrDefault(s =>
                                                             s.Player.Id == playerId &&
                                                             s.Stage == locStage &&
                                                             s.EndDate == date);

                if (sweepMatch == null)
                {
                    sweepMatch = new StageSweep(date, locStage, playerKeys[playerId]);
                    finalSweeps.Add(sweepMatch);
                }

                sweepMatch.AddDay();
            }

            return(finalSweeps);
        }