using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Sony.Filtr.Contracts.Definitions; using Sony.Filtr.Contracts.Entities; using Sony.Filtr.Contracts.Entities.Genre; using Sony.Filtr.DistributedCaching; using Sony.Filtr.PlaylistGeneration.Data; using Sony.Filtr.Utility.Extensions; namespace Sony.Filtr.PlaylistGeneration.Caching { public class DistributedCacheProvider : ICacheProvider { private readonly DistributedCacheHandler _distributedCacheHandler; public DistributedCacheProvider(DistributedCacheHandler distributedCacheHandler) { _distributedCacheHandler = distributedCacheHandler; } private string GetArtistCacheKey(string artistName) { return "Filtr.Artist:" + typeof(Artist) + ":" + Artist.Version + artistName.ToLowerInvariant(); } private string GetTopTracksCacheKey(Artist artist) { return "Filtr.TopTracks:" + typeof(Track) + ":" + Track.Version + ":" + artist.Name.ToLowerInvariant(); } private string GetSimilarArtistsCacheKey(string artistName) { return "Filtr.SimilarArtists:" + "1.2:" + typeof(SimilarArtistMatch) + SimilarArtistMatch.Version + ":" + artistName.ToLowerInvariant(); } private string GetArtistGenreCacheKey(Application application, Artist artist) { return "Filtr.ArtistGenres:" + typeof(GenreMatch) + ":" + GenreMatch.Version + ":" + application.ID + ":" + artist.Name.ToLowerInvariant(); } private string GetGenreArtistsCacheKey(Genre genre) { return "Filtr.GenreArtists:" + typeof(SimilarArtistMatch) + ":" + SimilarArtistMatch.Version + ":" + genre.Name.ToLowerInvariant(); } private string GetArtistTagsCacheKey(string artistName) { return "Filtr.ArtistTags:" + typeof(Tag) + ":" + Tag.Version + ":" + artistName.ToLowerInvariant(); } public List FetchSimilarArtistsFromCache(string artistName) { var similarArtists = _distributedCacheHandler.Get(GetSimilarArtistsCacheKey(artistName)) as IEnumerable; if (similarArtists != null) return similarArtists.Where(a=> a.Artist != null).ToList(); return null; } public void CacheSimilarArtists(Artist artist, List similarArtists) { _distributedCacheHandler.Put(GetSimilarArtistsCacheKey(artist.Name), similarArtists); } public Track CacheTrack(Track track) { return null; } public Track FetchTrackFromCache(string artistName, string title) { return null; } public void CacheArtist(Artist artist) { _distributedCacheHandler.Put(GetArtistCacheKey(artist.Name), artist); } public Artist FetchArtistFromCache(string artistName) { return _distributedCacheHandler.Get(GetArtistCacheKey(artistName)) as Artist; } public async Task> FetchArtistsFromCacheAsync(List artistNames) { ConcurrentBag artists = new ConcurrentBag(); foreach (var artistName in artistNames) { var artist = _distributedCacheHandler.Get(GetArtistCacheKey(artistName)) as Artist; if (artist != null) artists.Add(artist); } return artists.ToList(); } public void CacheTopTracks(Artist artist, IEnumerable tracks) { _distributedCacheHandler.Put(GetTopTracksCacheKey(artist), tracks.ToList()); } //public List FetchTopTracksFromCacheAsync(Artist artist) //{ // var tracks = DistributedCacheHandler.Instance.Get(GetTopTracksCacheKey(artist)) as List; // if (tracks == null || !tracks.Any()) // return null; // return tracks; //} public void CacheGenreMatch(Application application, Artist artist, IEnumerable genres) { _distributedCacheHandler.Put(GetArtistGenreCacheKey(application, artist), genres.ToList()); } public List FetchGenreMatchFromCache(Application application, Artist artistName) { return _distributedCacheHandler.Get(GetArtistGenreCacheKey(application, artistName)) as List; } public async Task>> FetchArtistsTagsFromCacheAsync(List artists) { ConcurrentDictionary> allArtistTags = new ConcurrentDictionary>(); await artists.ForEachAsync(4, async artist => { var artistResult = await FetchArtistTagsFromCacheAsync(artist); if (artistResult != null) { allArtistTags.TryAdd(artist, artistResult); } }); return allArtistTags.ToDictionary(k=> k.Key, v=> v.Value); } public void CacheGenreArtists(Genre genre, IEnumerable artists) { _distributedCacheHandler.Put(GetGenreArtistsCacheKey(genre), artists.ToList()); } public List FetchGenreArtists(Genre genre) { return _distributedCacheHandler.Get(GetGenreArtistsCacheKey(genre)) as List; } public void CacheArtistTags(string artist, List tags) { _distributedCacheHandler.Put(GetArtistTagsCacheKey(artist), tags); } public async Task> FetchArtistTagsFromCacheAsync(string artist) { return _distributedCacheHandler.Get(GetArtistTagsCacheKey(artist)) as List; } public string GetCacheProviderName() { return "MusicMatch.PlaylistGeneration.Caching.DistributedCacheProvider"; } public async Task>> FetchTopTrackForTagAsync(string tag) { var cacheKey = GetTopTracksForTagCacheKey(tag); return _distributedCacheHandler.Get(cacheKey) as List>; } private static string GetTopTracksForTagCacheKey(string tag) { return "Filtr.TopTracksForTag:" + typeof(RankedItem) + ":" + Track.Version + ":" + tag.ToLowerInvariant(); } public async Task CacheTopTrackForTagAsync(string tag, List> topTracks) { var cacheKey = GetTopTracksForTagCacheKey(tag); _distributedCacheHandler.Put(cacheKey, topTracks); } public async Task CacheTrackTagsAsync(Track track, List tags) { _distributedCacheHandler.PutList(GetTrackTagsCacheKey(track), tags); } public async Task> FetchTrackTagsFromCacheAsync(Track track) { return _distributedCacheHandler.GetList(GetTrackTagsCacheKey(track)); } public async Task>> FetchExtendedTopTracksForArtistsAsync(List artists, ServiceType serviceType) { ConcurrentDictionary> allArtistTracks = new ConcurrentDictionary>(); await artists.ForEachAsync(5, async artist => { var artistTracks = await FetchExtendedTopTracksForArtistAsync(artist, serviceType); if (artistTracks != null) allArtistTracks.TryAdd(artist, artistTracks); }); return allArtistTracks.ToDictionary(k=> k.Key, v=> v.Value); } private static string GetTrackTagsCacheKey(Track track) { return "Filtr.TrackTags:" + typeof(Tag) + ":" + Tag.Version + ":" + track.ArtistName + ":" + track.Name; } public Task> FetchExtendedTopTracksForArtistAsync(string artistName, ServiceType serviceType) { var result = _distributedCacheHandler.GetList(GetExtendedTopTracksForArtistCacheKey(artistName, serviceType)); return Task.FromResult(result); } public async Task CacheExtendedTopTracksForArtistAsync(string artistName, List tracks, ServiceType serviceType) { _distributedCacheHandler.PutList(GetExtendedTopTracksForArtistCacheKey(artistName, serviceType), tracks); } private static string GetExtendedTopTracksForArtistCacheKey(string artistName, ServiceType serviceType) { return "Filtr.ExtendedTopTracksForArtist:" + typeof(ExtendedTrack) + ":" + ExtendedTrack.Version + ":" + artistName.ToLowerInvariant() + ":" + serviceType; } //public List> FetchArtistMood(string artistName) //{ // return DistributedCacheHandler.Instance.Get(GetArtistMoodCacheKey(artistName)) as List>; //} //public void CacheArtistMood(string artistName, List> moods) //{ // DistributedCacheHandler.Instance.Put(GetArtistMoodCacheKey(artistName), moods); //} //private static string GetArtistMoodCacheKey(string artistName) //{ // return "Sony.Filtr.PlaylistGeneration.Caching.CacheArtistMood-2.0:" + ":" + artistName; //} public void CacheExtendedTopTracksForTag(string tag, List groupedExtendedTracks) { return; } public List FetchExtendedTopTracksForTag(string tag) { return null; } } }