using System; using System.Collections.Generic; using System.Threading.Tasks; using ErsatzTV.Core; using ErsatzTV.Core.Domain; using ErsatzTV.Core.Interfaces.Repositories; using LanguageExt; using Microsoft.EntityFrameworkCore; using static LanguageExt.Prelude; namespace ErsatzTV.Infrastructure.Data.Repositories { public class TelevisionRepository : ITelevisionRepository { private readonly TvContext _dbContext; public TelevisionRepository(TvContext dbContext) => _dbContext = dbContext; public Task Add(TelevisionShow show) => _dbContext.TelevisionShows.AddAsync(show).AsTask() .Bind(_ => _dbContext.SaveChangesAsync()) .ToUnit(); public Task> GetAllByMediaSourceId(int mediaSourceId) => _dbContext.TelevisionShows .Include(s => s.Metadata) .Include(s => s.Seasons) .ThenInclude(s => s.Episodes) .ToListAsync(); public async Task Update(TelevisionShow show) { _dbContext.TelevisionShows.Update(show); return await _dbContext.SaveChangesAsync() > 0; } public async Task Update(TelevisionEpisodeMediaItem episode) { _dbContext.TelevisionEpisodeMediaItems.Update(episode); return await _dbContext.SaveChangesAsync() > 0; } public async Task> GetOrAddShow(int mediaSourceId, string path) { Option maybeExisting = await _dbContext.TelevisionShows .Include(i => i.Metadata) .SingleOrDefaultAsync(i => i.Path == path); return await maybeExisting.Match( show => Right(show).AsTask(), () => AddShow(mediaSourceId, path)); } public async Task> GetOrAddSeason( TelevisionShow show, string path, int seasonNumber) { Option maybeExisting = await _dbContext.TelevisionSeasons .SingleOrDefaultAsync(i => i.Path == path); return await maybeExisting.Match( season => Right(season).AsTask(), () => AddSeason(show, path, seasonNumber)); } public async Task> GetOrAddEpisode( TelevisionSeason season, int mediaSourceId, string path) { Option maybeExisting = await _dbContext.TelevisionEpisodeMediaItems .Include(i => i.Metadata) .SingleOrDefaultAsync(i => i.Path == path); return await maybeExisting.Match( episode => Right(episode).AsTask(), () => AddEpisode(season, mediaSourceId, path)); } private async Task> AddShow(int mediaSourceId, string path) { try { var show = new TelevisionShow { MediaSourceId = mediaSourceId, Path = path, Seasons = new List() }; await _dbContext.TelevisionShows.AddAsync(show); await _dbContext.SaveChangesAsync(); return show; } catch (Exception ex) { return BaseError.New(ex.Message); } } private async Task> AddSeason( TelevisionShow show, string path, int seasonNumber) { try { var season = new TelevisionSeason { TelevisionShowId = show.Id, Path = path, Number = seasonNumber, Episodes = new List() }; await _dbContext.TelevisionSeasons.AddAsync(season); await _dbContext.SaveChangesAsync(); return season; } catch (Exception ex) { return BaseError.New(ex.Message); } } private async Task> AddEpisode( TelevisionSeason season, int mediaSourceId, string path) { try { var episode = new TelevisionEpisodeMediaItem { MediaSourceId = mediaSourceId, SeasonId = season.Id, Path = path }; await _dbContext.TelevisionEpisodeMediaItems.AddAsync(episode); await _dbContext.SaveChangesAsync(); return episode; } catch (Exception ex) { return BaseError.New(ex.Message); } } } }