using Microsoft.EntityFrameworkCore; using SharedLibraryCore.Helpers; using SharedLibraryCore.Interfaces; using Stats.Dtos; using System; using System.Linq; using System.Threading.Tasks; using Data.Abstractions; using Data.Models.Client.Stats; namespace Stats.Helpers { /// /// implementation for IResourceQueryHelper /// used to obtain client statistics information /// public class StatsResourceQueryHelper : IResourceQueryHelper { private readonly IDatabaseContextFactory _contextFactory; public StatsResourceQueryHelper(IDatabaseContextFactory databaseContextFactory) { _contextFactory = databaseContextFactory; } /// public async Task> QueryResource(StatsInfoRequest query) { var result = new ResourceQueryHelperResult(); await using var context = _contextFactory.CreateContext(enableTracking: false); // we need to get the ratings separately because there's not explicit FK var ratings = await context.Set() .Where(_ratingHistory => _ratingHistory.ClientId == query.ClientId) .SelectMany(_ratingHistory => _ratingHistory.Ratings.Where(_rating => _rating.ServerId != null && _rating.Newest) .Select(_rating => new { _rating.ServerId, _rating.Ranking, _rating.When })) .ToListAsync(); var iqStats = context.Set() .Where(_stats => _stats.ClientId == query.ClientId) .Select(_stats => new StatsInfoResult { Name = _stats.Client.CurrentAlias.Name, ServerId = _stats.ServerId, Kills = _stats.Kills, Deaths = _stats.Deaths, Performance = Math.Round(_stats.EloRating * 1/3.0 + _stats.Skill * 2/3.0, 2), ScorePerMinute = _stats.SPM, LastPlayed = _stats.UpdatedAt ?? _stats.Client.LastConnection, TotalSecondsPlayed = _stats.TimePlayed, ServerGame = _stats.Server.GameName.ToString(), ServerName = _stats.Server.HostName, }); var queryResults = await iqStats.ToListAsync(); // add the rating query's results to the full query foreach(var eachResult in queryResults) { var rating = ratings.FirstOrDefault(_rating => _rating.ServerId == eachResult.ServerId); eachResult.Ranking = rating?.Ranking ?? 0; eachResult.LastPlayed = rating?.When ?? eachResult.LastPlayed; } result.Results = queryResults; result.RetrievedResultCount = queryResults.Count; result.TotalResultCount = result.RetrievedResultCount; return result; } } }