using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using ErsatzTV.Core; using ErsatzTV.Core.Domain; using ErsatzTV.Core.Interfaces.Repositories; using LanguageExt; using MediatR; using static ErsatzTV.Application.ProgramSchedules.Mapper; using static LanguageExt.Prelude; namespace ErsatzTV.Application.ProgramSchedules.Commands { public class CreateProgramScheduleHandler : IRequestHandler> { private readonly IProgramScheduleRepository _programScheduleRepository; public CreateProgramScheduleHandler(IProgramScheduleRepository programScheduleRepository) => _programScheduleRepository = programScheduleRepository; public Task> Handle( CreateProgramSchedule request, CancellationToken cancellationToken) => Validate(request) .MapT(PersistProgramSchedule) .Bind(v => v.ToEitherAsync()); private Task PersistProgramSchedule(ProgramSchedule c) => _programScheduleRepository.Add(c).Map(ProjectToViewModel); private Task> Validate(CreateProgramSchedule request) => ValidateName(request) .MapT( name => new ProgramSchedule { Name = name, MediaCollectionPlaybackOrder = request.MediaCollectionPlaybackOrder, KeepMultiPartEpisodesTogether = request.MediaCollectionPlaybackOrder == PlaybackOrder.Shuffle && request.KeepMultiPartEpisodesTogether }); private async Task> ValidateName(CreateProgramSchedule createProgramSchedule) { List allNames = await _programScheduleRepository.GetAll() .Map(list => list.Map(c => c.Name).ToList()); Validation result1 = createProgramSchedule.NotEmpty(c => c.Name) .Bind(_ => createProgramSchedule.NotLongerThan(50)(c => c.Name)); var result2 = Optional(createProgramSchedule.Name) .Filter(name => !allNames.Contains(name)) .ToValidation("Schedule name must be unique"); return (result1, result2).Apply((_, _) => createProgramSchedule.Name); } } }