using System.Collections.Concurrent; using System.Linq; using System; using System.Collections.Generic; using System.Threading.Tasks; using Sony.Filtr.Contracts.Definitions; using Sony.Filtr.Contracts.Entities; using Sony.Filtr.Core.LastModified; using Sony.Filtr.DistributedCaching; namespace Sony.Filtr.Core.EditorialPlaylists { public class EditorialPlaylistStatsManager { private readonly EditorialPlaylistStatsFactory _editorialStatsPlaylistFactory; private readonly DistributedCacheHandler _cacheHandler; private readonly LastModifiedManager _lastModifiedManager; public EditorialPlaylistStatsManager(EditorialPlaylistStatsFactory editorialStatsPlaylistFactory, DistributedCacheHandler cacheHandler, LastModifiedManager lastModifiedManager) { _editorialStatsPlaylistFactory = editorialStatsPlaylistFactory; _cacheHandler = cacheHandler; _lastModifiedManager = lastModifiedManager; } //public void AddEditorialPlaylistSubscriptionStatistic(IEnumerable editorialPlaylists) //{ // _editorialPlaylistFactory.AddPlaylistSubscriberStatistics(editorialPlaylists); //} public async Task AddEditorialPlaylistSubscriptionStatisticAsync(List editorialPlaylists) { await _editorialStatsPlaylistFactory.AddPlaylistSubscriberStatisticsAsync(editorialPlaylists); } //public Dictionary GetIndivualEditorialPlaylistSubscriptionStatistic(IEnumerable playlistIDs, DateTime? startDate = null, DateTime? endDateTime = null) //{ // return _editorialPlaylistFactory.GetIndividualPlaylistSubscriptionStatistic(playlistIDs, startDate, endDateTime); //} //public Dictionary GetCombinedEditorialPlaylistSubscriptionStatistic(IEnumerable playlistIDs, DateTime? startDate = null, DateTime? endDateTime = null) //{ // return _editorialStatsPlaylistFactory.GetCombinedPlaylistSubscriptionStatistic(playlistIDs, startDate, endDateTime); //} //public List GetEditorialPlaylistSubscriptionStatistic(IEnumerable playlists, DateTime? startDate = null, DateTime? endDateTime = null) //{ // return _editorialPlaylistFactory.GetPlaylistSubscriptionStatistic(playlists, startDate, endDateTime); //} public async Task> GetCombinedEditorialPlaylistSubscriptionStatisticAsync(List playlists, DateTime? startDate = null, DateTime? endDateTime = null) { DateTime realStartDate = startDate.HasValue ? startDate.Value : DateTime.Now.AddDays(-15); var stats = await _editorialStatsPlaylistFactory.GetCombinedPlaylistStatsAsync(playlists, realStartDate, endDateTime); return stats; } public async Task> GetCombinedPlaylistStatsAsync(string spotifyUsername, DateTime? startDate = null, DateTime? endDate = null) { return await _editorialStatsPlaylistFactory.GetCombinedPlaylistStatsAsync(spotifyUsername, startDate, endDate); } public async Task> GetPlaylistStatsAsync(List playlists) { return await GetPlaylistStatsAsync(playlists, DateTime.Today.AddDays(-2)); } //TODO: NEED TO REVERT TRUE TO FALSE ONCE CACHE HANDLER WILL BE FIXED public async Task> GetPlaylistStatsAsync(IEnumerable playlistsIds, DateTime startDate, DateTime? endDateParam = null, bool ignoreCache = true) { DateTime endDateTime; if (endDateParam == null) { endDateTime = GetLatestStatsImportDate(); } else { endDateTime = endDateParam.Value; } List cachedStats = new List(); if (!ignoreCache) { cachedStats = GetCachedPlaylistStats(playlistsIds, startDate, endDateTime); } List allStats = new List(); var nonCachedPlaylists = playlistsIds.Except(cachedStats.Select(p => p.PlaylistId)).ToList(); cachedStats.ForEach(allStats.Add); if (nonCachedPlaylists.Any()) { var stats = (await _editorialStatsPlaylistFactory.GetStatsAsync(nonCachedPlaylists.Distinct().ToList(), startDate, endDateTime)).GroupBy(s => s.PlaylistId).ToDictionary(k => k.Key, v => v.ToList()); foreach (var stat in stats) { allStats.AddRange(stat.Value); var cacheKey = BuildCacheKey(stat.Key, startDate, endDateTime); _cacheHandler.Put(cacheKey, stat.Value); } } return allStats.ToList(); } public async Task> GetPlaylistStatsAsync(List playlists, DateTime startDate, DateTime? endDateParam = null) { List editorialPlaylistStats = new List(); var playlistStats = await GetPlaylistStatsAsync(playlists.Select(p => p.SpotifyLink.ExtractPlaylistID()).ToList(), startDate, endDateParam); var playliststatsDic = playlistStats.GroupBy(k => k.PlaylistId).ToDictionary(k=> k.Key, v=> v.ToList()); foreach (var editorialPlaylist in playlists) { List playlistStat; var playlistId = editorialPlaylist.SpotifyLink.ExtractPlaylistID(); if (playliststatsDic.TryGetValue(playlistId, out playlistStat)) { editorialPlaylistStats.Add(new EditorialPlaylistWithStats() { Playlist = editorialPlaylist, Stats = playlistStat, }); } else { editorialPlaylistStats.Add(new EditorialPlaylistWithStats() { Playlist = editorialPlaylist, Stats = new List(), }); } } return editorialPlaylistStats; } private DateTime GetLatestStatsImportDate() { return _lastModifiedManager.GetLastModifyDate(null, EntityType.PlaylistStats); } private List GetCachedPlaylistStats(IEnumerable playlistIds, DateTime startDate, DateTime endDateTime) { ConcurrentBag stats = new ConcurrentBag(); var keys = playlistIds.Distinct().Select(p => BuildCacheKey(p, startDate, endDateTime)); var results = _cacheHandler.Get(keys); foreach (var playlistId in playlistIds) { var key = BuildCacheKey(playlistId, startDate, endDateTime); if (results.ContainsKey(key)) { var playlistStat = results[key] as List; if (playlistStat != null) playlistStat.ForEach(stats.Add); } } return stats.ToList(); } private string BuildCacheKey(string playlistId, DateTime startDate, DateTime endDateTime) { return "EditorialPlaylistStats-1.4:" + playlistId + ":" + startDate.ToString("yyyy-MM-dd") + ":" + endDateTime.ToString("yyyy-MM-dd-HH:mm"); } } }