using System; using System.Collections.Generic; using System.Linq; using JetBrains.Annotations; using Portoa.Persistence; using VideoGameQuotes.Api; using VideoGameQuotes.Web.Models; namespace VideoGameQuotes.Web.Services { public interface IQuoteService { Game GetGame(int id); IEnumerable GetAllGames(); IEnumerable GetAllSystems(); IEnumerable GetAllPublishers(); IEnumerable GetAllCategories(); Quote SaveQuote(Quote quote); Quote GetQuote(int id); Publisher GetPublisher(int id); GamingSystem GetSystem(int systemId); Category GetCategory(int categoryId); Category SaveCategory(Category category); IEnumerable GetMostRecentQuotes(int limit); [CanBeNull] Quote GetRandomQuote(); IEnumerable GetBestQuotes(int start, int end); Vote SaveVote(Vote vote); Vote GetVoteOrCreateNew(Quote quote, User voter); IEnumerable GetBrowsableQuotes(BrowseModel model); } public class QuoteService : IQuoteService { private readonly IRepository quoteRepository; private readonly IRepository gameRepository; private readonly IRepository systemRepository; private readonly IRepository publisherRepository; private readonly IRepository categoryRepository; private readonly IRepository voteRepository; public QuoteService( IRepository quoteRepository, IRepository gameRepository, IRepository systemRepository, IRepository publisherRepository, IRepository categoryRepository, IRepository voteRepository ) { this.quoteRepository = quoteRepository; this.categoryRepository = categoryRepository; this.voteRepository = voteRepository; this.gameRepository = gameRepository; this.systemRepository = systemRepository; this.publisherRepository = publisherRepository; } [UnitOfWork] public Game GetGame(int id) { return gameRepository.FindById(id); } [UnitOfWork] public IEnumerable GetAllGames() { return gameRepository.Records; } [UnitOfWork] public IEnumerable GetAllSystems() { return systemRepository.Records; } [UnitOfWork] public IEnumerable GetAllPublishers() { return publisherRepository.Records; } [UnitOfWork] public IEnumerable GetAllCategories() { return categoryRepository.Records; } [UnitOfWork] public Quote SaveQuote(Quote quote) { return quoteRepository.Save(quote); } [UnitOfWork] public Quote GetQuote(int id) { return quoteRepository.FindById(id); } [UnitOfWork] public Publisher GetPublisher(int id) { return publisherRepository.FindById(id); } [UnitOfWork] public GamingSystem GetSystem(int systemId) { return systemRepository.FindById(systemId); } [UnitOfWork] public Category GetCategory(int categoryId) { return categoryRepository.FindById(categoryId); } [UnitOfWork] public Category SaveCategory(Category category) { return categoryRepository.Save(category); } [UnitOfWork] public IEnumerable GetMostRecentQuotes(int limit) { return quoteRepository .Records .OrderByDescending(quote => quote.Created) .Take(limit); } [UnitOfWork] public Quote GetRandomQuote() { var quotes = quoteRepository.Records.ToArray(); if (quotes.Length == 0) { return null; } return quotes[new Random().Next(quotes.Length)]; } [UnitOfWork] public IEnumerable GetBestQuotes(int start, int end) { var records = quoteRepository.Records.ToArray(); return records .OrderByDescending(quote => quote.Score) .ThenByDescending(quote => quote.UpVotes) .Skip(start) .Take(end - start + 1); } [UnitOfWork] public Vote SaveVote(Vote vote) { return voteRepository.Save(vote); } [UnitOfWork] public Vote GetVoteOrCreateNew(Quote quote, User voter) { var vote = voteRepository.Records.SingleOrDefault(v => v.Quote == quote && v.Voter == voter); return vote ?? new Vote { Quote = quote, Voter = voter }; } [UnitOfWork] public IEnumerable GetBrowsableQuotes(BrowseModel model) { var quotes = quoteRepository.Records; if (model.GameIds.Any()) { quotes = quotes.Where(quote => model.GameIds.Contains(quote.Game.Id)); } if (model.PublisherIds.Any()) { quotes = quotes.Where(quote => quote.Game.Publishers.Any(publisher => model.PublisherIds.Contains(publisher.Id))); } if (model.SystemIds.Any()) { quotes = quotes.Where(quote => quote.Game.Systems.Any(system => model.SystemIds.Contains(system.Id))); } if (model.CategoryIds.Any()) { quotes = quotes.Where(quote => quote.Categories.Any(category => model.CategoryIds.Contains(category.Id))); } return quotes; } } }